Переменная Python не возвращается в цикл - PullRequest
1 голос
/ 08 марта 2012
employees = []
for i in range(0,10):

    emp = Employee(i)
    emp.first_name = "%s-%s"%("first name", i)
    emp.last_name = "%s-%s"%("last_name", i)
    emp.desgination = "%s-%s"%("engineer", i)

    employees.append(emp)


ids = [e.eid for e in employees]

Вот мое определение класса:

class Employee:

    _fields = {}

    def __init__(self, eid):
        self.eid = eid

    def __getattr__(self, name):
        return self._fields.get(name)

    def __setattr__(self,name,value):
        self._fields[name] = value

    def __str__(self):
        return str(self._fields)

    def __unicode__(self):
        return str(self._fields)

Проблема в том, что когда я печатаю идентификаторы, он содержит 10 раз 9 ... то есть

[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

Кажется, что та же самая переменная emp перезаписывается. Я не уверен, что происходит не так. Хотя я Java-кодер, но я подумал, что у меня тоже есть представление о Python.

Ответы [ 2 ]

4 голосов
/ 08 марта 2012

Проблема, действительно, в вашем прошлом Java!:)

Ошибка здесь:

_fields = {}

_fields является членом КЛАССА!Таким образом, каждый экземпляр Employee использует один и тот же _fields var, и каждый раз, когда вы его модифицируете, вы изменяете все другие объекты.Вы должны переместить деталь _fields = {} в функцию __init__:

self._fields={}

Но тогда вы столкнетесь с другой проблемой: self.eid = xx вызывает метод __setattr__!(как и self._fields!)

Решение состоит в том, чтобы использовать self.__dict__['_fields'], когда вам нужен доступ к элементу _fields экземпляра вместо self._fields.Он получит прямой доступ к члену, вместо того, чтобы проходить через __getattr__ и бесконечное повторение, с хорошим переполнением стека в конце.

0 голосов
/ 08 марта 2012

это побочный эффект функций:

def __getattr__(self, name):
    return self._fields.get(name)

def __setattr__(self,name,value):
    self._fields[name] = value

удалить их, и это работаеттак что это направление смотреть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...