Overriding "__setattr__" of a module - possible?

Ian Kelly ian.g.kelly at gmail.com
Wed Jun 16 16:10:26 EDT 2010


On Wed, Jun 16, 2010 at 12:55 PM, John Nagle <nagle at animats.com> wrote:
> Note that there are now two copies of "a", one bound to the module and
> referenced in "f", and a second bound to the class, and referenced by
> "x.a".  Uh oh.
>
> The problem here is that when "def f..." was defined, its reference
> to "a" was bound to the object containing "a" at the time, which is
> the module-level copy of the variable.
>
> I don't think turning a module into a class is going to work.
> Binding the functions into the class won't work, because Python
> doesn't have class-level (as opposed to instance-level) functions.
> If we move x.f into class FakeModule, then "x.f()" is called as
> "f(x)", with an unexpected argument.
>
> Any better ideas?  All I really want to do is to override "__setattr__"
> for a module.

It seems to me that a proxy for the actual module would work better.

import sys

class ModuleProxy(object):

  def __init__(self, module):
    object.__setattr__(self, 'module', module)

  def __getattribute__(self, name):
    module = object.__getattribute__(self, 'module')
    return getattr(module, name)

  def __setattr__(self, name, value):
    module = object.__getattribute__(self, 'module')
    print "setting %s=%s" % (name, value)
    setattr(module, name, value)

a = 1
def f():
    print a

sys.modules[__name__] = ModuleProxy(__import__(__name__))


Cheers,
Ian



More information about the Python-list mailing list