From: Stephen Hansen on 16 Jun 2010 12:31 On 6/16/10 1:23 AM, Christian Heimes wrote: >> There aren't any; modules do not follow the class object protocol. They >> are simple types with a __dict__ (which you can't change, either, so no >> replacing it with a dict that implements __setattr__). > > You are wrong, my friend. :) > > Modules follow the new style class and instance protocol. Modules aren't > classes but instances of the internal module type. Since you can't > overwrite magic methods on instances of new style classes you can't > overwrite __setattr__ on module level, too. Well, fine, be that way, all right and correct and shiznit. :) -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/
From: John Nagle on 16 Jun 2010 14:55 On 6/15/2010 8:34 PM, Michele Simionato wrote: > On Jun 16, 4:43 am, John Nagle<na...(a)animats.com> wrote: >> Is it possible to override "__setattr__" of a module? I >> want to capture changes to global variables for debug purposes. >> >> None of the following seem to have any effect. >> >> modu.__setattr__ = myfn >> >> setattr(modu, "__setattr__", myfn) >> >> delattr(modu, "__setattr__") >> >> John Nagle > > There is a dirty trick which involves fiddling with sys.modules... That doesn't do quite what you'd expect. Here's a version with more debug output: import sys class FakeModule(object): def __init__(self, dic): vars(self).update(dic) def __setattr__(self, name, value): print "setting %s=%s" % (name, value) object.__setattr__(self, name, value) a = 1 def f(): print ('called f, a = %s' % (a,)) print("Patching " + __name__) sys.modules[__name__] = FakeModule(globals()) --- C:\projects\newthreading>\python26\python ActivePython 2.6.5.12 (ActiveState Software Inc.) based on Python 2.6.5 (r265:79063, Mar 20 2010, 14:22:52) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import x Patching x >>> x.f() called f, a = None >>> x.a 1 >>> x.a = 2 setting a=2 >>> x.f() called f, a = None --- 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. John Nagle
From: Ian Kelly on 16 Jun 2010 16:10 On Wed, Jun 16, 2010 at 12:55 PM, John Nagle <nagle(a)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
From: John Nagle on 16 Jun 2010 17:38 On 6/16/2010 1:10 PM, Ian Kelly wrote: > On Wed, Jun 16, 2010 at 12:55 PM, John Nagle<nagle(a)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 That just leaves things in a state where even "sys" and "import" are undefined. John Nagle
From: Ian Kelly on 16 Jun 2010 18:56 On Wed, Jun 16, 2010 at 3:38 PM, John Nagle <nagle(a)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)> Ian
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Python editing .txt file Next: [ANN] OpenOpt 0.29, FuncDesigner 0.19, DerApproximator 0.19 |