Replacing a built-in method of a module object instance

Peter Otten __peter__ at web.de
Sat Jun 27 07:52:38 CEST 2009


David Hirschfield wrote:

> I have a need to replace one of the built-in methods of an arbitrary
> instance of a module in some python code I'm writing.
> 
> Specifically, I want to replace the __getattribute__() method of the
> module I'm handed with my own __getattribute__() method which will do
> some special work on the attribute before letting the normal attribute
> lookup continue.
> 
> I'm not sure how this would be done. I've looked at all the
> documentation on customizing classes and creating instance methods...but
> I think I'm missing something about how built-in methods are defined for
> built-in types, and where I'd have to replace it. I tried this naive
> approach, which doesn't work:
> 
> m = <module instance>
> 
> def __getattribute__(self, attr):
>     print "modified getattribute:",attr
>     return object.__getattribute__(self, attr)
> 
> import types
> m.__getattribute__ = types.MethodType(__getattribute__,m)
> 
> It seems to create an appropriately named method on the module instance,
> but that method isn't called when doing any attribute lookups, so
> something's not right.
> Any ideas? Is this even possible?

Special methods are looked up in the type, not the instance, and you cannot 
set attributes of the module type.

As a workaround you can write a wrapper class and put that into the 
sys.modules module cache:

>>> class Module(object):
...     def __init__(self, module):
...             self.__module = module
...     def __getattr__(self, name):
...             try:
...                     return getattr(self.__module, name.lower())
...             except AttributeError:
...                     def dummy(*args): pass
...                     return dummy
...
>>> import shutil
>>> import sys
>>> sys.modules["shutil"] = Module(shutil)
>>> import shutil
>>> shutil.MOVE
<function move at 0x7f20f9b7d5f0>
>>> shutil.yadda
<function dummy at 0x7f20f9b7d6e0>

Peter




More information about the Python-list mailing list