__getattr__ and static vs. instantiated

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Wed Sep 12 03:50:13 EDT 2007


tvaughan a écrit :
> Hi,
> 
> Let's say I have:
> 
> class Persistable(object):
> 
>         __attrs__ = {}
> 
>         def __getattr__(self, name):
>                 if name in self.__attrs__:
>                         return self.__attrs__[name]['value']
>                 else:
>                         return Object.__getattr__(self, name)
> 
>         def __setattr__(self, name, value):
>                 if name in self.__attrs__:
>                         self.__attrs__[name]['value'] = value
>                 else:
>                         Object.__setattr__(self, name, value)
> 
> And the I have:
> 
> class Person(Persistable):
> 
>         __storm_table__ = 'person'
> 
>         id = Int(primary=True)
> 
>         __attrs__ = {
>                 'name': {
>                         'lang': 'en',
>                         'value': Unicode(),
>                 },
>         }
> 
>         def __init__(self):
>                 self.id = int(random.random() * 1000)
> 
> I can do this:
> 
> person = Person()
> person.name = 'Jane Smith'
> 
> But I cannot do:
> 
> Person.name = 'Jane Smith'

yes, you can. But it won't do the same thing.

> or use Person.name in a Storm query like:
> 
> Person.name == 'Jane Smith'

It will obviously raise an AttributeError if the class Person doesn't 
have a 'name' attribute.

> __getattr__ is only called when using an instantiated class,

A class's '__getattr__' method is only triggered when looking up 
attributes on an instance of the class, yes.

> and
> never, it seems, in a static case. Why? How do I work around this?

Since classes are instances of their type, the obvious solution would be 
to define a custom metaclass implementing __getattr__. I didn't try, but 
it might work.

Now is this the best thing to do is another question. You seems not to 
be aware of the descriptor protocol - which is used to implement methods 
and properties. This lets you define 'smart' attributes. You'll find 
relevant documentation here:
http://docs.python.org/ref/descriptors.html
and here:
http://users.rcn.com/python/download/Descriptor.htm


Also, you seem to be trying to roll your own ORM. There are already 
quite a few existing ones - SQLAlchemy being probably the best one 
already, and also a good base (no pun) for building your own solutions.

HTH



More information about the Python-list mailing list