On 3/15/07, Greg Ewing <[EMAIL PROTECTED]> wrote:
Guido van Rossum wrote:
> We could even do this by hacking the default getattr
> implementation to skip the instance dict if the name starts and ends
> with two underscores.
But unless I'm mistaken, this behaviour is only
appropriate for *methods*, and you can't tell
just from whether the name has double underscores
whether it's a method or not.
We can make __*__ methods be a different kind of method (by making the
metaclass wrap them up in a different kind of descriptor, one with __set__
set. Python treats descriptors with a __set__ slightly different than those
without __set__: it bypasses __dict__ entirely, for new-style classes. This
trick doesn't work for classic classes.)
For instance:
import types
class SpecialMethodDescr(object):
def __init__(self, func):
self.func = func
def __get__(self, inst, cls=None):
# For backward compatibility, insert inst.__dict__ checks and warns
here (and we should get our name passed in.)
return self.func.__get__(inst, cls)
def __set__(self, inst, value):
# Possibly allow assignment here, by assigning to inst.__dict__, but
warn about it not being used.
raise AttributeError
class SMDType(type):
def __new__(cls, name, bases, attrs):
for attr in attrs:
if (attr.startswith("__") and attr.endswith("__") and
isinstance(attrs[attr], types.FunctionType)):
attrs[attr] = SpecialMethodDescr(attrs[attr])
return super(SMDType, cls).__new__(cls, name, bases, attrs)
class smd_object(object):
__metaclass__ = SMDType
And to see it in action:
class Old(object):
... def __repr__(self):
... return "Old.__repr__"
...
class New(smd_object):
... def __repr__(self):
... return "New.__repr__"
...
o = Old()
n = New()
def o_repr():
... return "o_repr"
...
o.__dict__['__repr__'] = o_repr
def n_repr():
... return "n_repr"
...
n.__dict__['__repr__'] = n_repr
o
Old.__repr__
n
New.__repr__
o.__repr__()
'o_repr'
n.__repr__()
'New.__repr__'
--
Thomas Wouters <[EMAIL PROTECTED]>
Hi! I'm a .signature virus! copy me into your .signature file to help me
spread!
_______________________________________________
Python-3000 mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe:
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com