Форум сайта python.su
0
Продолжил решение этих задач:
http://pyobject.ru/blog/2010/02/04/python-quiz/
И столкнулся с проблемами при решении 4-й из темы “классы”:
Написать класс, который регистрирует свои экземпляры и предоставляет интерфейс итератора по ним
>>> x = Reg() >>> x <Reg instance at 0x98b6ecc> >>> y = Reg() >>> y <Reg instance at 0x98b6fec> >>> z = Reg() <Reg instance at 0x98ba02c> >>> for i in Reg: ... print i <Reg instance at 0x98b6ecc> <Reg instance at 0x98b6fec> <Reg instance at 0x98ba02c>
Офлайн
52
А что не так со списком self._instances?
Офлайн
0
fata1exА можно поподробнее? Если не сложно, можете набросать первую часть задания - без механизма итератора?
А что не так со списком self._instances?
Офлайн
52
Не self, a cls.
class MetaReg(type): def __iter__(cls): return iter(cls._instances) class Reg(object): __metaclass__ = MetaReg _instances = [] def __new__(cls, *args, **kwargs): instance = super(Reg, cls).__new__(cls, *args, **kwargs) cls._instances.append(instance) return instance a, b, c = Reg(), Reg(), Reg() for obj in Reg: print obj
Отредактировано fata1ex (Июнь 24, 2012 17:24:48)
Офлайн
0
Спасибо огромное! Приступил к чтению.
Офлайн
0
Покопался с метаклассами, ужаснулся, впечатлился. Статьи отличные, спасибо.
Но возник вопрос: а зачем тут, в принципе, метаклассы? Собственно, ковыряя и переиначивая решение, достиг нужного результата проще:
class Reg(object): _instances = [] def __init__(self): self._instances.append(self) def __iter__(self): return iter(_instances)
Офлайн
0
Правда этот вопрос вызвал у меня сомнение великое:
Скажите, почему работает так:
>>>class A(object): a = 0 def __init__(self): self.a+=1 >>>class B(object): b = [] def __init__(self): self.b.append(1) >>> a1 = A() >>> a2 = A() >>> a2.a 1 >>> b1 = B() >>> b2 = B() >>> b2.b [1, 1]
Офлайн
А что, собственно, вы ожидали? Обычное поведение списков. Создавая новый инстанс, вы вызываете __init__, каждый раз добавляя в свой список единицу. Нового списка-то вы там не создаете. Другое дело неизменяемые типы, инт, self.a += 1 это уже другая переменная.
Офлайн
0
dimy44
А что, собственно, вы ожидали? Обычное поведение списков. Создавая новый инстанс, вы вызываете __init__, каждый раз добавляя в свой список единицу. Нового списка-то вы там не создаете. Другое дело неизменяемые типы, инт, self.a += 1 это уже другая переменная.
Офлайн
568
vaultb в твоём коде - аттрибут класса. Чтобы он стал аттрибутом объекта его нужно определять внутри метода.dimy44
А что, собственно, вы ожидали? Обычное поведение списков. Создавая новый инстанс, вы вызываете __init__, каждый раз добавляя в свой список единицу. Нового списка-то вы там не создаете. Другое дело неизменяемые типы, инт, self.a += 1 это уже другая переменная.
Извините, я, видимо, не очень понимаю суть неизменяемых типов. Мне казалось, что просто при передаче аргумента на изменяемые типы в функцию, или присваивания другой переменной, передается указатель на ту же самую структуру данных.
Но почему здесь-то a относится к self, а b к cls? Ведь в __init__ мы аппендим к селф, а не к цлс? Какой механизм действий при создании экземпляра класса?
Офлайн