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