[Python-Dev] RFC: readproperty
Žiga Seilnacht
ziga.seilnacht at gmail.com
Wed Sep 28 19:28:45 CEST 2005
Michael Hudson <mwh <at> python.net> writes:
>
> "Phillip J. Eby" <pje <at> telecommunity.com> writes:
>
> > Unfortunately, finding out a descriptor's name is non-trivial; it'd be nice
> > if there were a descriptor hook __bind__(cls,name) that was called by
> > classes during cls.__new__ or assignment to a class attribute, and which
> > you could define to return a replacement descriptor. It seems like one of
> > the first metaclasses I end up writing in any new project is something to
> > do this, and I believe Ian Bicking has encountered the same thing in e.g.
> > SQLObject.
>
> I've done this many times too, but I've never really felt the need to
> propose a change to Python for it. I guess one could modify the
> descriptor protocol slightly, but is it worth it? Hmm, dunno.
>
> Cheers,
> mwh
>
You can use something like this to find a descriptor's name:
class Private(property):
def __init__(self, permission, fget=None, fset=None, fdel=None, doc=None):
fget = fget or 'r' in permission and self.default_fget or None
fset = fset or 'w' in permission and self.default_fset or None
fdel = fdel or 'd' in permission and self.default_fget or None
super(private, self).__init__(fget, fset, fdel, doc)
def get_attribute_name(self, instance):
my_name = None
for cls in instance.__class__.mro():
for attribute_name, attribute_object in cls.__dict__.iteritems():
if attribute_object is self:
my_name = attribute_name
break
if my_name is not None:
class_name = cls.__name__
break
attribute_name = '_%s__%s' % (class_name, my_name)
self.attribute_name = attribute_name
return attribute_name
def default_fget(self, instance):
try:
attribute_name = self.attribute_name
except AttributeError:
attribute_name = self.get_attribute_name(instance)
return getattr(instance, attribute_name)
def default_fset(self, instance, value):
try:
attribute_name = self.attribute_name
except AttributeError:
attribute_name = self.get_attribute_name(instance)
setattr(instance, attribute_name, value)
def default_fdel(self, instance):
try:
attribute_name = self.attribute_name
except AttributeError:
attribute_name = self.get_attribute_name(instance)
delattr(instance, attribute_name)
More information about the Python-Dev
mailing list