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

Alex Martelli aleax at aleax.it
Mon Jan 28 11:20:05 EST 2002


"Pedro Rodriguez" <pedro_rodriguez at club-internet.fr> wrote in message
news:pan.2002.01.28.15.33.29.559545.1770 at club-internet.fr...
    ...
> Still, phrases are always required, a diagram won't explain all
> (I have something like 'the map is not the field' in mind).

"The map is not the territory", but it applies to verbal maps too.


> > Back to the mechanics (metaclasses or otherwise) that one can use to
> > implement creational design patterns (and other kinds).  When I have a
> > class object C, "instantiation" is a call on C, say:
> >     instance = C(*args, **kwds)
> > so it involves C.__call__, which typically comes from C.__class__.
>                  ^^^^^^^^^^
>
> < example sniped for brievety >
>
> 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.



> > Nothing mysterious here, right?  Just notice the difference between
> > 'self' in the two cases.  Now, clearly, if you want to influence what
    ...
> It may be good to remind that __new__ is a static method whose signature
> looks like 'def __new__(cls, ...)', and also, I felt confused when reading
:

Yes, using cls instead of self is probably a good convention to remind
of "the difference between [the first argument's role] in the two cases".


> > If you choose to work by subclassing type (having C use your own
> > metaclass), you can get at the "template method" itself and insert or
> > tweak whatever you need to.  For example:
> >
> > class autoborg(type):
> >   metastate = {}
> >   def __call__(self, *args, **kwds):
> >       result = self.__new__(self, *args, **kwds)
> >       result.__dict__ = self.metastate
> >       if result: result.__init__(*args, **kwds)
> >       return result
> >
>
> ... 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.


> I guess I need a clearer head to sort out this __call__/__new__/__init__
> chain. I wonder how much time it will take me to get my marks on those
> matters, and use them when appropriate (headaches in sight ;)

Same here -- I'm just starting to get my feet wet with them:-).  Trying
to explain things help me clarify them for myself, too...:-).


> > honor of Jorge Luis Borges, master of identity and separateness, just
> > shortened for ease of use and uniformity of pronunciation across
    ...
> I like it (not the Borges reference, whose writings I recommend, just like
> those from Bioy Casares), it just these words 'just shortened'. If it
> wasn't coming from you, I might have give it a thought ;)

Well, I've defended 'len' vs 'length' just today, haven't I...?-)


Alex






More information about the Python-list mailing list