__getattribute__ and __slots__
Peter Otten
__peter__ at web.de
Mon Apr 17 04:18:56 EDT 2006
pascal.parent at free.fr wrote:
Python has both __getattribute__() and __getattr__(). While
__getattribute__() will always be called if you ask for an attribute
__getattr__() serves only as fallback if the attribute if not found by
other means.
> I try to define a (new-style) class who:
> - have a __slots__ defined to be strict attributes,
__slots__ is a performance/memory optimization. Using __slots__ to introduce
bondage & discipline through the backdoor is against Python's spirit.
> - return None if the attribute is 'ok' but not set, or raise a 'normal'
> error if the attribute isn't in __slots__.
The approach you have chosen is a very ineffective one. Why don't you just
set the attribute to a default value in the initializer?
> This code runs, but is it the good way?
I don't think so...
> class test(object):
> __slots__ = ['id']
> def __getattr__(self, attr):
> if not attr in self.__slots__: raise AttributeError
> try:
> return self.attr
The line above does not do what you think it does. It just calls
test_instance.__getattr__("attr"), and since "attr" is not in __slots__ it
raises an AttributeError.
> except:
> return None
You should get the same effect with
>>> class T(object):
... __slots__ = ["id"]
... def __getattr__(self, name):
... if name not in self.__slots__:
... raise AttributeError
... return 42 # for better visibility
...
>>> t = T()
>>> t.id
42
>>> t.whatever
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 5, in __getattr__
AttributeError
>>> t.id = "something else"
>>> t.id
'something else'
>>> t.whatever = "something else"
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'T' object has no attribute 'whatever'
Peter
More information about the Python-list
mailing list