pre-PEP generic objects
Jp Calderone
exarkun at divmod.com
Thu Dec 2 15:35:19 EST 2004
On Thu, 02 Dec 2004 12:26:31 -0800, Scott David Daniels <scott.daniels at acm.org> wrote:
>Nick Craig-Wood wrote:
> > Scott David Daniels <Scott.Daniels at Acm.Org> wrote:
> >> You can simplify this:
> >> class Hash(object):
> >> def __init__(self, **kwargs):
> >> for key,value in kwargs.items():
> >> setattr(self, key, value)
> >> __getitem__ = getattr
> >> __setitem__ = setattr
> > That doesn't work unfortunately...
> >>>>h['a']
> >
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in ?
> > TypeError: getattr expected at least 2 arguments, got 1
> >
> > I'm not exactly sure why though!
>
> I could have sworn I tested this, but I must have accidentally
> tested h.a rather than h['a']. I don't know why it doesn't work either.
> For example:
>
> def gattr(*args): return getattr(*args)
> def sattr(*args): return setattr(*args)
> class Hash(object):
> def __init__(self, **kwargs):
> for key,value in kwargs.items():
> setattr(self, key, value)
> __getitem__ = gattr
> __setitem__ = sattr
>
> does work.
>>> def getattr2(obj, name, value):
... return getattr(obj, name, value)
...
>>> class X:
... a = getattr
... b = getattr2
...
>>> X.a
<built-in function getattr>
>>> X.b
<unbound method X.getattr2>
>>> type(getattr)
<type 'builtin_function_or_method'>
>>> type(getattr2)
<type 'function'>
>>>
When the class object is created, the namespace is scanned for instances of <type 'function'>. For those and only those, a descriptor is created which will produce bound and unbound methods. Instances of other types, such as <type 'int'> or <type 'builtin_function_or_method'>, are ignored, leading to the critical difference in this case:
>>> X().a
<built-in function getattr>
>>> X().b
<bound method X.getattr2 of <__main__.X instance at 0xb7e5e1ec>>
>>>
No bound method for getattr, hence trying to call it with two arguments fails, as it has no self on which to operate.
Jp
More information about the Python-list
mailing list