property for class objects

Steve Menard foo at bar.com
Wed Nov 10 08:28:22 EST 2004


Bengt Richter wrote:
> On Tue, 09 Nov 2004 23:08:44 -0500, Steve Menard <foo at bar.com> wrote:
> 
> 
>>Jp Calderone wrote:
>>
>>>On Tue, 09 Nov 2004 21:54:50 -0500, Steve Menard <foo at bar.com> wrote:
>>>
>>>
>>>>As par of JPype, I find that I have to brifge Java static members into 
>>>>class attributes.
>>>>
>>>>I am using a metaclass to dynamically create a Python class for every 
>>>>Java type encountered. Instance variables were handled by adding a 
>>>>property(get, set) to the class's dictionary.
>>>>
>>>>Now static members are giving me a headache. I cannot use "property" for 
>>>>them, because properties are for instances only.
>>>>
>>>>What I am currently doing is adding a __getattr__ and a __setattr__ 
>>>>methods to the metaclass, which is called when a class attribute is 
>>>>requested but not found in the class' dict.
>>>>
>>>>This works fine exact it does not walk the inheritance tree to find 
>>>>static members defined in base classes. I am currently adding up all the 
>>>>names in every class. This "works", however it is misleading when you do 
>>>>a dir() of the class.
>>>>
>
[ SNIP previous idea]

> 
> Sometimes a custom descriptor can get you there. You can pass stuff to its
> constructor to hang on its self, which is accessible separately from the self
> of an instance or the latter's class. So there is room for customizing various
> descriptor instances using one class (not a metaclass). If you only need read
> access, this is easy. If you want a r/w property you may have to go to a metaclass
> solution unless you are willing to use  cvar.x = val or cvar[something] = var or
> cvar.method(var) etc. -- i.e. return the descriptor self and have __setitem__ etc
> as methods of the descriptor. You can hang something temporarily on self for use
> in the subsequent method call, though I have the feeling there's some pitfall in
> some uses of that. Anyway, here's a minimal descriptor (property is build on
> the descriptor mechanisms, and you probably know all this, so I don't know why
> I'm posting this ;-) IIRC, if you don't have a __set__ method, an attribute
> assignment to an instance can shadow the descriptor, but not if you have __set__.
> Of course, an attribute assignment to the class is no different than the original
> class var assignment unless you have a descriptor/property in the metaclass to intercept it.
> 
>  >>> class Desc(object):
>  ...     def __get__(self, inst, cls=None):
>  ...         if inst is None: print 'accessed via class attribute'
>  ...         else: accessed
>  ...
>  >>> class Desc(object):
>  ...     def __get__(self, inst, cls=None):
>  ...         if inst is None: print '%r accessed via class attribute' %cls
>  ...         else:  print '%r accessed via instance attribute' %inst
>  ...
>  >>> class Foo(object):
>  ...    cvar = Desc()
>  ...
>  >>> foo = Foo()
>  >>> foo.cvar
>  <__main__.Foo object at 0x009B61B0> accessed via instance attribute
>  >>> Foo.cvar
>  <class '__main__.Foo'> accessed via class attribute
> 
> Regards,
> Bengt Richter

I wasnt aware of those descriptors (I am just now delving in the "meta" 
side of things), and it looks promising. So thanks for taking the time 
to tlel me about it :)

Static variables are not just constants however, and the __set__ has to 
work as normal. I did a quick test and it seems by mistake you can even 
erase the descriptor with a new value .. not good.

At least I can use this for the constant static values (which probably 
comprises the bulk) and use the __setattr__ to prevent overwriting them.

Steve

Still looking for a more complete solution howeber



More information about the Python-list mailing list