Wrapping methods of built-in dict

shailesh kochhar.mw at gmail.com
Thu May 21 17:55:23 EDT 2009


On May 20, 7:31 pm, Steven D'Aprano
<ste... at REMOVE.THIS.cybersource.com.au> wrote:
> On Wed, 20 May 2009 18:42:38 -0700, shailesh wrote:
> > The reason as far as I understand is that the methods on the built-in
> > dict are not of MethodType or FunctionType
>
> That seems to be true:
>
> >>> type({}.get)
> <type 'builtin_function_or_method'>
>
>>> type(dict.get>
> <type 'method_descriptor'>
>
> > so they are not included in
> > the result of the inspect.getmembers call and are not wrapped.
>
> But that isn't:
>
> >>> zip(*inspect.getmembers(dict))[0]  # extract the names only
>
> ('__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__',
> '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__',
> '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__',
> '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
> '__setattr__', '__setitem__', '__str__', 'clear', 'copy', 'fromkeys',
> 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys',
> 'pop', 'popitem', 'setdefault', 'update', 'values')
>
> So the problem isn't directly with getmembers, but with the predicate
> functions you have passed to it (inspect.isfunction and inspect.method).
> Try inspect.ismethoddescriptor instead.

Thanks for that. Between ismethod, isfunction, ismethoddescriptor and
isbuiltin I think I can cover all the types needed for wrapping
classes.

I began writing an equivalent version for wrapping objects instead of
classes. The problem I run into is that there isn't a predicate for
some methods of dict instances

>>> all = set([ name for (name, method) in inspect.getmembers({}) ])    # get all the methods
>>> builtin = set([ name for (name, method) in inspect.getmembers({}, inspect.isbuiltin) ])  # get the builtin methods
>>> for m in all.difference(builtin):    # print the types of what's left over
...     print m, type(getattr({}, m))
...
__ne__ <type 'method-wrapper'>
__setattr__ <type 'method-wrapper'>
__hash__ <type 'NoneType'>
__delitem__ <type 'method-wrapper'>
__str__ <type 'method-wrapper'>
__getattribute__ <type 'method-wrapper'>
__class__ <type 'type'>
__cmp__ <type 'method-wrapper'>
__delattr__ <type 'method-wrapper'>
__iter__ <type 'method-wrapper'>
__le__ <type 'method-wrapper'>
__len__ <type 'method-wrapper'>
__gt__ <type 'method-wrapper'>
__setitem__ <type 'method-wrapper'>
__lt__ <type 'method-wrapper'>
__ge__ <type 'method-wrapper'>
__eq__ <type 'method-wrapper'>
__doc__ <type 'str'>
__init__ <type 'method-wrapper'>
__repr__ <type 'method-wrapper'>

>>> [ attr for attr in dir(inspect) if attr.startswith('is') ]   # list of predicates supported by inspect
['isabstract', 'isbuiltin', 'isclass', 'iscode', 'isdatadescriptor',
'isframe', 'isfunction', 'isgenerator', 'isgeneratorfunction',
'isgetsetdescriptor', 'ismemberdescriptor', 'ismethod',
'ismethoddescriptor', 'ismodule', 'isroutine', 'istraceback']

>>> inspect.getmembers({}, inspect.ismethod)
[]
>>> inspect.getmembers({}, inspect.isfunction)
[]
>>> inspect.getmembers({}, inspect.ismemthoddescriptor)
[]

There doesn't seem to be a predicate returning method wrappers. Is
there an alternate way to query an object for attributes that are of
method wrappers?

This exercise also makes me question if I'm going about this
correctly. If I want to add functionality to the methods of a class or
an object are decorators and the inspect module the pythonic way to go
about it? I can think of alternative implementations either through
metaclasses or proxy objects.

Thanks again.



More information about the Python-list mailing list