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