Aaron "Castironpi" Brady wrote:
class A(type):
... def __call__( self, *ar ):
... print 'call', self, ar
...
class B(object):
... __metaclass__= A
...
B(3)
call <class '__main__.B'> (3,)
Overriding the __call__ method of 'type' has the effect of giving you
a static __call__ method on a class-- a method which doesn't need an
instance to call. Your behavior may be counterintuitive though, to
someone who wants to instantiate 'B', in this case, and proceed like a
normal object. That is, they want to call a generic class and use it,
and also expect instances of B to behave as B. You can't have both,
so either return B from B.__new__, or, to instantiate B, take the long
way and call B.__new__ directly.
B.__new__(B)
<__main__.B object at 0x009FDB70>
Has anyone stepped through the C code to find out when the decision is
made to call which function, B.__new__ or A.__call__, when B is
called?
For Python coded objects, ob(*args) in code translates to internal
execution of type(ob).__call__(ob, *args) (without further
translation!). The interpreter compiles a statement at a time, without
looking back to do type inferencing, and so does not know what type is
being called or if it is even callable.
For B, B(*args) == type(B).__call__(B, *args) == A.__call__(B, *args).
So there is no decision.
For C coded objects, I believe ob(*args) in Python code translate to a C
call of the C equivalent of type(ob).tp_call (or something like that).
From observation, type.tp_call acts something like this:
def __call__(cls, *args):
if cls == type:
if len(*args):
return arg[0].__class__
elif len(*args) == 3:
return type.__new__(type, *args) # or maybe not pass type?
else:
raise TypeError('type() takes 1 or 3 arguments')
else:
return cls.__new__(cls, *args)
So, for a normal class C (an instance of type), type.__call__ calls
C.__new__.
Terry Jan Reedy
--
http://mail.python.org/mailman/listinfo/python-list