hasattr + __getattr__: I think this is Python bug

Ethan Furman ethan at stoneleaf.us
Tue Jul 27 12:46:11 EDT 2010


Bruno Desthuilliers wrote:
> Bruno Desthuilliers a écrit :
>> Ethan Furman a écrit :
>>> Bruno Desthuilliers wrote:
>>>> Duncan Booth a écrit :
>> (snip)
>>
>>>>> Or you could create the default as a class attribute 
>>>>
>>>> from the OP:
>>>> """
>>>> I have a class (FuncDesigner oofun) that has no attribute "size", but
>>>> it is overloaded in __getattr__, so if someone invokes
>>>> "myObject.size", it is generated (as another oofun) and connected to
>>>> myObject as attribute.
>>>> """
>>>>
>>>> so this solution won't obviously work in this case !-)
>>>>
>>>> Also and FWIW, I wouldn't advocate this solution if the "default" 
>>>> class attribute is of a mutable type.
>>>
>>> Well, it is Monday, so I may be missing something obvious, but what 
>>> is the effective difference between these two solutions?
>>
> 
> If you meant "what is the difference between creating the "whatever" 
> attribute with a default value in the initializer and creating it on 
> demand in the __getattr__ hook", the main difference is that in the 
> first case, the instance is garanteed to have this attribute, so you get 
> rid of "hasattr" checks (and the unwanted side effects) or, worse, 
> direct check of the instance __dict__. Except for a couple of corner 
> case, client code shouldn't have to worry about this kind of things - 
> this breaks encapsulation.

Yay Tuesday!  :D

What I meant was what is the difference between:

[Bruno Desthuilliers]
 > DEFAULT_WHATEVER = Whathever()
 > class MyClass(object):
 >      def __init__(self, x, y):
 >          self.size = DEFAULT_WHATEVER

and

[Duncan Booth]
 > class MyClass(object):
 >     size = Whatever()
 >     def __init__(self, x, y):
 >         ...

in both cases the object ends up with a size attribute and no further 
need of __getattr__. Of course, the warning about having a mutable 
object as a class attribute stands.

To phrase it another way, why does your solution (Bruno) work, but 
Duncan's "obviously won't"?

~Ethan~



More information about the Python-list mailing list