0
import inspect
class meta(type):
def __new__(cls, t_name, bases, argdict):
print "inside meta __new__"
return super(meta, cls).__new__(cls, t_name, bases, argdict)
def __init__(self, t_name, bases, argdict):
print "inside __init__ of meta"
def __call__(cls, *args, **kwargs):
print "*************************"
print "inside __call__ of meta"
print cls, args, kwargs #--> cls is A
# How cls is passed as __call__ does not take cls param? through super/how? Why super requires cls?
inst = super(meta, cls).__call__(*args, **kwargs) # why no cls to call? how super works here
#inst = type.__call__(cls, *args, **kwargs) # this works well
print inst, "instance inside meta"
print "*************************"
return inst
class A(object):
__metaclass__ = meta # this line triggers metaclass
def __new__(cls, *args, **kwargs):
print "inside A __new__"
print cls, args, kwargs # we get cls here as A
inst = super(A, cls).__new__(cls, *args, **kwargs)
print inst, "instance inside A"
return inst
def __init__(self, *args, **kwargs):
print "inside A __init___"
self.attr = args[0]
def __call__(self, *args, **kwargs):
print "inside A __call__ "
print self, args, kwargs
a = A("simple arg") # this is type(A).__call__(A, ...) == meta.__call__(A, ...)
print a
a("param") # type(a).__call__(a), ...
print type(A)
OUTPUT
Как работает метакласс (__call__)?
inside meta __new__
inside __init__ of meta
*************************
inside __call__ of meta
<class '__main__.A'> ('simple arg',) {}
inside A __new__
<class '__main__.A'> ('simple arg',) {}
<__main__.A object at 0x7ff0010f2c10> instance inside A
inside A __init___
<__main__.A object at 0x7ff0010f2c10> instance inside meta
*************************
<__main__.A object at 0x7ff0010f2c10>
inside A __call__
<__main__.A object at 0x7ff0010f2c10> ('param',) {}
<class '__main__.meta'>
<type 'type'>
True
У меня есть несколько вопросов, внедренные в код [не прикладывая здесь, как это сделает вопрос более больше]
Спасибо ignacio, первая часть Я понял, почему мы называем это 'cls'. но вторая часть неясна, может быть, глупые вопросы 'type type() триггеров типа .__ call__' как и все остальные вызовы? ? и имеет ли '__new__' явное требование для cls, и почему мы его предоставляем? –
Все вызовы связаны с методом '__call __()' напрямую или иным образом. '__new __()' [определяется таким образом] (https://docs.python.org/2/reference/datamodel.html#object.__new__). –