Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 2, 2012 21:38:26

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

1. str(1) - что вызывается, __init__ или __call__?
2.

>>> print str('a')
a
>>> print str.__init__('a')
None
>>> print str.__call__('a')
a
Почему __init__ возвращает None вместо self?

3.
MyClass(a, b) = 1
Такое может работать?

Отредактировано odnochlen (Окт. 3, 2012 19:11:03)

Офлайн

#2 Окт. 2, 2012 22:12:28

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

1. Строки - immutable. Вызывается __new__
2. __init__ не должен ничего возвращать (т.е. возвращать None)

As a special constraint on constructors, no value may be returned; doing so will cause a TypeError to be raised at runtime.
3. Думаю нет. Результатом же будет ссылка на экземпляр или immutable, для которого вообще бессмысленно.

Офлайн

#3 Окт. 2, 2012 22:49:19

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

1. Ага, то есть сначала вызывается class.__new__() и возвращает новый экземпляр класса, а потом вызывается class.__init__(obj, *params)? А как быть с __call__?

Офлайн

#4 Окт. 3, 2012 01:05:52

Fibio
От:
Зарегистрирован: 2010-09-14
Сообщения: 74
Репутация: +  2  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

__call__ вызывается при обращении к экземпляру как к функции, str(1) - вы создаете экземпляр класса str а не вызываете его



Офлайн

#5 Окт. 3, 2012 01:29:24

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

Так что и в каком порядке происходит, если я пишу hz(1)?

Офлайн

#6 Окт. 3, 2012 11:53:29

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Что происходит при создании экземпляра класса?

Вызывается hz.__call__(1) Если hz — класс, то __call__ создает его экземпляр вызывая __new__ и __init__



Офлайн

#7 Окт. 3, 2012 16:28:21

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

А как он вызывает __new__ и __init__?

Офлайн

#8 Окт. 3, 2012 18:07:38

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

odnochlen
А как он вызывает __new__ и __init__?
Как я понимаю: классы создает type, внутри его __call__ все и вызывается.

Самому стало интересно . Вот что будет если переопределить type и добавить принты:
class FooMeta(type):
    def __call__(mcs, *args, **kwargs):
        print 'mcs call', args, kwargs
        return super(FooMeta, mcs).__call__(*args, **kwargs)
 
    def __new__(mcs, name, bases, attrs):
        print 'mcs new', name, bases, attrs
        return super(FooMeta, mcs).__new__(mcs, name, bases, attrs)
 
    def __init__(mcs, *args, **kwargs):
        print 'mcs init', args, kwargs
        return super(FooMeta, mcs).__init__(*args, **kwargs)
 
 
class Foo(object):
    __metaclass__ = FooMeta
 
    def __new__(cls, *args):
        print 'ex new', cls, args
        return super(Foo, cls).__new__(cls, *args)
     
    def __init__(self, *args):
        print 'ex init', args
 
foo = Foo(123)
foo = Foo(321)
Вот какая очередность получается:
mcs new Foo (<type 'object'>,) {'__module__': '__main__', '__metaclass__': <class '__main__.FooMeta'>, '__new__': <function __new__ at 0x015751F0>, '__init__': <function __init__ at 0x01575230>}
mcs init ('Foo', (<type 'object'>,), {'__module__': '__main__', '__metaclass__': <class '__main__.FooMeta'>, '__new__': <function __new__ at 0x015751F0>, '__init__': <function __init__ at 0x01575230>}) {}
mcs call (123,) {}
ex new <class '__main__.Foo'> (123,)
ex init (123,)
mcs call (321,) {}
ex new <class '__main__.Foo'> (321,)
ex init (321,)
Сначала создается класс Foo (один раз), класс инициализируется (тоже один раз). Потом уже используется __call__ этого класса для создания экземпляров. Так как мы в нем вызываем базовый type.__call__, он вызывает __new__ (если бы его не было, использовался бы object.__new__), а базовый object.__new__ вызывает Foo.__init__

Офлайн

#9 Окт. 3, 2012 19:08:52

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

Т.е. переопределение __new__ и __call__ в классах ничем хорошим не закончится?

Офлайн

#10 Окт. 3, 2012 19:36:38

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Что происходит при создании экземпляра класса?

odnochlen
Т.е. переопределение __new__ и __call__ в классах ничем хорошим не закончится?
Если базовые методы не вызывать то да. Но для своих модификаций immutable типов или при реализации штук наподобие декларативного Django ORM, Enthought Traits и т.п., без этого не обойтись.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version