Overriding "__setattr__" of a module - possible?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Thu Jun 17 03:25:25 EDT 2010


En Wed, 16 Jun 2010 19:56:39 -0300, Ian Kelly <ian.g.kelly at gmail.com>  
escribió:

> On Wed, Jun 16, 2010 at 3:38 PM, John Nagle <nagle at animats.com> wrote:
>> That just leaves things in a state where even "sys" and "import"
>> are undefined.
>
> Say what?  It works fine for me.
>
>>>> import proxy_mod
>>>> proxy_mod.f()
> 1
>>>> proxy_mod.a = 2
> setting a=2
>>>> proxy_mod.f()
> 2
>>>> proxy_mod.sys
> <module 'sys' (built-in)>

It *mostly* works, but not always. Try this function:

def g(x):
     global a
     print 'global a -> ', x
     a = x

py> import fake # ModuleProxy stuff
py> fake.f()
1
py> fake.a = 3
setting a=3
py> fake.f()
3
py> fake.g(8)
global a ->  8
py> fake.f()
8
py> fake.a
8

Note the fake.g(8) call: __setattr__ wasn't called.
If the OP wants to trace assignments to global variables, this becomes a  
problem.

A function defined in a module holds a reference to the module's __dict__  
in its func_globals attribute. Getting and setting global variables goes  
directly to this dictionary, and does not use the module object at all.

Even worse, the LOAD_GLOBAL/STORE_GLOBAL opcodes (which implement getting  
and setting global variables) assume func_globals is a true dictionary and  
bypass any overriden __getitem__/__setitem__ methods (an optimization,  
surely). I'm afraid it will be hard to intercept global variable usage in  
these circumstances.

-- 
Gabriel Genellina




More information about the Python-list mailing list