autoborg &c (was )e:d Unified Type/class (Singleton)

Pedro Rodriguez pedro_rodriguez at club-internet.fr
Mon Jan 28 13:38:32 EST 2002


"Alex Martelli" <aleax at aleax.it> wrote:

> "Pedro Rodriguez" <pedro_rodriguez at club-internet.fr> wrote in message

>> Ok. Except for a probable typo on 'C.__call__' which may exist or not
>> but is not involved in this process (your examples suggests C.__new__).
> 
> Wrong, at least in the simplest case:
> 
>>>> class C(object): pass
> ...
>>>> C.__call__
> <method-wrapper object at 0x007B4200>
>>>> y=C.__call__()
>>>> y
> <__main__.C object at 0x007B6FB0>
> 
> C.__call__ does indeed exist (and here comes from C's type, i.e. the
> type metaclass), and is exactly what's involved when you call C
> ("typically comes from C.__class__", as I said).
> 
> Of course, if C's class-body defines an attribute or method __call__:
> 
>>>> class C(object):
> ...   def __call__(self): print '!'
> ...
>>>> C.__call__
> <unbound method C.__call__>
> 
> then C.__call__ comes to mean something else, because of how
> object.__getattr__ is coded.  C.__class__.__call__ (if any) is typically
> what's involved in calling C.
> 
> 
This could be confusing, but I am sure there is a reason in Python
internals.

I understand that a __call__ defined in a class turned its instances into
callables. So why should a class have a __call__ attribute with a
different semantic by default (C.__call__() == C() ?)

It seems to come from the 'type' object and slot allocation in
typeobject.c :
   >>>> help(type) returns :
   ...
   __call__(...)
      x.__call__(...) <==> x(...)
   ...

The best explanation I can think of is : all slots (for future '__xxx__'
attributes) need to be allocated for class objects. They get a semantic
and this is a default value.

Notice that, when not defined by the developer, it doesn't appear with
dir() ( from descrintro : 'It does not show class attributes that are
defined by a metaclass', I think if falls in this category).


>> ... because, I would have written :
>>        result = type.__new__(self, *args, **kwds)
>> instead of :
>>        result = self.__new__(self, *args, **kwds)
>>
>> I just realize now that 'parentClass.staticMethod()' is equivalent to
>> 'self.staticMethod()' (same arguments used), whereas in classical
>> classes the meaning is different (bound/unbound method).
> 
> Yes, and you could override it in the self case, but not in the other
> case -- which might perhaps be better coded as
>     super(autoborg, self).__new__
> just in case.
> 
> 
Yes. I belive this is the proper way to call the parent classes methods.


-- 

Pedro



More information about the Python-list mailing list