python - Alter module variables in one module while it doesn't change in the original -



python - Alter module variables in one module while it doesn't change in the original -

i'm using foo module includes few module level variables dictate behavior. 1 of these variables sanitize.

i want able utilize foo in 2 ways, foo.parse() , foo2.parse(), difference foo has sanitize=false , foo2 has sanitize=true

i want while not having re-create paste code. example

#foo module sanitize='foo' def parse(): print sanitize #foo2 module import foo foo.sanitize='foo2' #test script import foo import foo2 foo2.foo.parse() #i want print 'foo2' foo.parse() #i want print 'foo'

however, above illustration print 'foo2' both times. there way accomplish behavior?

thanks!

if your code, solution not depend in module level variables, in other way maintain state of objects. modules in python "singletons" - means 1 time imported module, there 1 version of then, interpreter wide - behavior want, example, get, free, if utilize class inheritance - kid class can customize some, no need rewrite all, of parent class.

so, if much encapsulate "foo" code within class - may not have write class needs instances, features want already:

#foo module: class foo(object): sanitize = "value 1" @classmethod def parse(cls): print cls.sanitize #foo2 foo import foo class foo2(foo): sanitize = "value 2" # code: foo import foo foo2 import foo2 foo.parse() foo2.parse()

of course, cheer amount of introspection , metaprogramming python allows, would possible want - complicate matters, no good. module variables have of same disadvantages global variables have in c code.

one way create "foo" when accessed through foo2 create variable changes on fly, phone call function in "foo" , restore previosu values on exit. arbitrary code triggered on attribute access of "foo" on module "foo2", "foo" has refer object "property" attribute --

so, exa illustration wrote run, in concurency-unsafe way, btw, unsafe way, if foo2 written more or less so:

import foo _foo sanitize = "value2" class _foowrapper(object): def __getattribute__(self, attr): self.change_vars() original_function = getattr(_foo, attr) if callable(original): def wrapper(func): def new_func(*args, **kw): res = func(*args, **kw) self.restore_vars() homecoming res homecoming new_func homecoming wrapper(original) homecoming original def change_vars(self): self.original_sanitize = _foo.sanitize _foo.sanitize = sanitize def restore_vars(self): __foo.sanitize = self.original_sanitize foo = _foowrapper()

this creates "foo" object in module foo2 when accessed, retrieves requested attributes original "foo" module instead. "foo2.foo.parse" "foo" parse function - but, perceive ammount of "hackiness" in approach - in order able restore original value in "foo" module lives within python interpreter, after function fetched foo2, function have too, upon returning, restore values itself. way modifying function runs additional code when returns - decorated on fly code above.

i think illustration makes clear having module level configurations not way go in case, although possible.

edit o.p. commented:

thanks jsbueno, unfortunately not code , must rely on module level variables. wrapper class method interesting said, hacky , incredibly non thread safe, i'm afraid won't case

in reply that:

modules "singletons" - so, changing variable on module, @ point create thread unsafe. other way can think creating "photocopier" module re-creates classes, attributes , instances of another, existing module, when imported - rebinding functions global variables (methods still acessed functions @ level)

reading description may sound "unfeasable" - easier done described - here follows "foo2" module above:

from types import moduletype, functiontype import foo _foo sanitize = "value 2" def rebuild_function(func, glob): """rebinds globals in given functions globals in module default""" new_func = functiontype(func.func_code, glob, func.func_name, func.func_defaults, func.func_closure) homecoming new_func def rebuild_class(cls, glob): metatype = type(cls) dct = cls.__dict__.copy() key, value in dct.items(): if isinstance(value, functiontype): dct[key] = rebuild_function(value, glob) homecoming metatype(cls.__name__, cls.__bases__, dct) def rebuild_module(mod,glob): new_module = moduletype(mod.__name__) key, value in mod.__dict__.items(): if isinstance(value, functiontype): value = rebuild_function(value, glob) elif isinstance(value, type): value = rebuild_class(value, glob) setattr(new_module, key, value) homecoming new_module foo = rebuild_module(_foo, globals()) __all__ = ["foo", "sanitize"]

this code described - recreates function objects in original module, rebindign globals dict each function. concurrency safe. there corner cases if to-be clonned module point native code classes or functions (they not of "functiontype"). if makes heavy usage of multiple class inheritance, metaclasses,- miught work, or not.

i tested simple class , worked fine:

#module "foo" sanitize='foo' def parse(): print sanitize class parser(object): def __init__(self): print sanitize * 2

and

#test script import foo import foo2 foo2.foo.parse() #i want print 'foo2' foo2.foo.parser() foo.parse() #i want print 'foo' foo.parser()

output:

[gwidion@powerpuff tmp16]$ python test_foo.py foofoo value 2 value 2value 2 foo foofoo [gwidion@powerpuff tmp16]$

python scope python-module

Comments

Popular posts from this blog

How do I check if an insert was successful with MySQLdb in Python? -

delphi - blogger via idHTTP : error 400 bad request -

postgresql - ERROR: operator is not unique: unknown + unknown -