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

Reply via email to