Brian van den Broek wrote:
> Kent Johnson said unto the world upon 2005-12-13 16:34:
>>You can use self.__class__.__module__ and self.__class__.__name__ 
>>instead of parsing str(self.__class__).
> 
> thanks! I knew there had to be an easier way that the manual parse. I 
> tried to find it with dir(), but now I see this as odd:
> 
>  >>> class A(object):pass
> 
>  >>> a=A()
>  >>> dir(a.__class__)
> ['__class__', '__delattr__', '__dict__', '__doc__', 
> '__getattribute__', '__hash__', '__init__', '__module__', '__new__', 
> '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 
> '__weakref__']
>  >>> a.__class__.__name__
> 'A'
>  >>>
> 
> So, a.__class__ has a __name__ attribute, but dir() doesn't know about 
> it. Odd. Is there a reason for the dir-invisibility of the __name__ 
> attribute that you know of?

__name__ is an attribute of 'type' - the class of the class of A:

  >>> dir(type)
['__base__', '__bases__', '__basicsize__', '__call__', '__class__', 
'__cmp__', '__delattr__', '__dict__', '__dictoffset__', '__doc__', 
'__flags__', '__getattribute__', '__hash__', '__init__', '__itemsize__', 
'__module__', '__mro__', '__name__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasses__', 
'__weakrefoffset__', 'mro']

None of these show up when you do dir(A).

The guts of the dir() function are in Objects\object.c in the Python 
source. A comment in PyObject_Dir() says,

        /* Elif some form of type or class, grab its dict and its bases. We 
deliberately don't suck up its __class__, as methods belonging to the 
metaclass would probably be more confusing than helpful. */

So metaclass attributes are deliberately left out. In general I think 
they would be confusing, if you did dir(A) and saw __getattribute__ and 
__setattr__, for example, you would think the class was doing some 
attribute magic, but they might just be the metaclass attributes which 
do the normal class magic :-)

> 
> I just checked, and the docs say that dir's returned list is "is not 
> necessarily complete" <http://docs.python.org/lib/built-in-funcs.html>.
> which I did not know.

The docs also say, "it tries to supply an interesting set of names more 
than it tries to supply a rigorously or consistently defined set of 
names". So it is someone's judgement of what is useful.

>>- you can set the custom __repr__ for all classes in a module by 
>>assigning __metaclass__ at the module (instead of class) level.
>>
>>For example:
>>
>>class AutoRepr(type):
>>     def __init__(cls, name, bases, d):
>>         super(type, cls).__init__(name, bases, d)
>>
>>         def __repr__(self):
>>             return '%s.%s(%s, %s)' % (cls.__module__, cls.__name__, 
>>self.arg1, self.arg2)
>>
>>         setattr(cls, '__repr__', __repr__)
>>
>>__metaclass__ = AutoRepr # This makes AutoRepr be the meta class of A1
>>
>>class A1:
>>     def __init__(self, arg1, arg2):
>>         self.arg1 = arg1
>>         self.arg2 = arg2
>>
>>a=A1(1, 2)
>>
>>print repr(a)
>>
>>
>>prints:
>>__main__.A1(1, 2)
> 
> 
> 
> That's pretty cool! I think I'm going to have to try to unpack what's 
> going on and then play with it to see if I can make it work with 
> variable signatures, etc. Thanks for showing it.

Basically the metaclass is manipulating the class when it is created, 
jamming in a __repr__ function. Defining a module-level __metaclass__ 
variable sets the default the metaclass for any classes in the module 
that don't define a metaclass some other way.

See Guido's "Unifying Types and Classes" essay and PEP 253 for details. 
And ask questions - maybe if I answer enough questions I will understand 
this stuff!
http://www.python.org/2.2.3/descrintro.html#metaclasses
http://www.python.org/peps/pep-0253.html

Kent

_______________________________________________
Tutor maillist  -  [email protected]
http://mail.python.org/mailman/listinfo/tutor

Reply via email to