'if foo' calls getattr?!?
Ted Horst
Ted.Horst at wdr.com
Mon Aug 30 14:07:41 EDT 1999
On Mon, 30 Aug 1999, Joe Strout wrote:
> Doing some profiling on Graphite this weekend, we found a very curious
> thing: a gazillion calls to __getattr__ on one of our classes, where we
> expected to find none. We eventually tracked it down to a seemingly
> innocent test, basically, "if foo: self.myfoo = foo". The "if foo" was
> invoking foo.__getattr__ (which is very expensive).
>
> I can think of no reason why it should be this way, but it is. Below is
> a very simple stand-alone demonstration. It leads me to the absurd
> idiom of saying "if id(foo) != id(None)" when I really mean "if foo",
> just because using id() avoids the __getattr__ call.
>
> Can anybody explain why this should be? Is it a bug in Python? Is
> there some other way to check whether I have a reference to an object
> that doesn't involve a function call?
>
> Confused,
> -- Joe
The statement
if foo:
tries to determine the truth value of foo. Different types respond to this
differently. An instance will respond by returning the results of
__nonzero__ if defined, or else returning the result of __len__ if defined.
The following session illustrates this, and a faster way to check for None.
>>> class Foo:
... def __getattr__(self,name):
... print name
... raise AttributeError, name
...
>>> foo = Foo()
>>> if foo:
... print 'yes'
...
__nonzero__
__len__
yes
>>> if foo is not None:
... print 'yes'
...
yes
>>>
Ted
---
More information about the Python-list
mailing list