staticmethod and __call__
James_Althoff at i2.com
James_Althoff at i2.com
Thu Dec 6 18:49:28 EST 2001
Bruce Eckel wrote:
>I seem to have trouble getting __call__ to behave as a static
>method:
>
>class Item:
> def f(): print 'An Item'
>
>Item.a = 'a'
>Item.b = 'b'
>Item.c = 'c'
>
>class ItemGenerator:
> import random
> rgen = random.Random()
> items = [j for j in vars(Item).values() if isinstance(j, Item)]
> def __call__():
> return ItemGenerator.rgen.choice(ItemGenerator.items)
> __call__ = staticmethod(__call__)
>
>
>items = [ItemGenerator() for i in range(5)]
>for i in items:
> i.f()
>
>Output:
>Traceback (most recent call last):
> File "test.py", line 18, in ?
> i.f()
>AttributeError: ItemGenerator instance has no attribute 'f'
>
>It doesn't seem to be making the __call__
We are presented with several mysteries here. <wink>
For one, "isinstance(j, Item)" is going to fail since none of class Item's
attributes have values that are instances of class Item itself. So
ItemGenerator.items is the empty list [].
Also, __call__ is normally added to a class like ItemGenerator to make its
*instances* callable -- the ItemGenerator class object already responds to
(), it being a class object -- so making __call__ a static method seems
unusual. Nonetheless, it will be called if ItemGenerator() is changed to
ItemGenerator()() (note the extra paren.s).
Having called __call__ as a static method on an ItemGenerator instance
(which is probably not what was desired), however, "i.f()" will still
generate an error because of "def f():" not being "def f(self):".
Seems like there should be a more straightforward way. <wink>
Jim
More information about the Python-list
mailing list