Having a problem of a sub-process that has to execute just a callable (function, lambda or class with __call__ defined), and following DRY, I've put common functionality in base class and then created a set of children. As this code is part of much bigger project, DIRAC, where have to follow conventions and use everywhere a set of of global variables (references to services, clients, some global functions, etc.). Of course I was going to import them in a base class, but then what?
Globals are visible at the module level, so if I put them to base class, I would be able to use them in base class module (all functions and methods over there). But what I really want, was to use them in inherited classes to.
No problem, you can always store them as a member of base... Yuck! But then instead of just calling "gGlobalVar.doSomethingForMe()" I have to call it by "self.gGlobalVar.doSomethingForMe()". Awkward! Ugly! Bad!
What come to my mind is a python sequence for looking up symbols. There is always __builtins__ module, right? And this one is first in a line of r lookup, right? So what about storing them over there?
So here is an example:
- let's say this is our module storing "globals", say testGlobals.py:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
gX = 1 def foo( ): print "function foo called" - and here is a base class, say testBase.py:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
class baseClass( object ): def __init__( self ): from testGlobal import gX, foo try: __builtins__["gX"] = gX __builtins__["foo"] = foo except: setattr( __builtins__, "gX", gX ) setattr( __builtins__, "foo", foo ) def run( self ): print "in base class run" print "gX = ", gX foo() This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersclass A: def __init__( self ): print type(__builtins__) if __name__ == "__main__": a = A()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersFri, 04 Nov 14:29 E0][cibak@localhost:~/test]> python Python 2.7 (r27:82500, Sep 16 2010, 18:02:00) [GCC 4.5.1 20100907 (Red Hat 4.5.1-3)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from a import A >>> a = A() <type 'dict'> This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters[Fri, 04 Nov 14:32 E0][cibak@localhost:~/test]> python -m a <type 'module'> - and here it is, a testChild.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersfrom testBase import baseClass class testChild( baseClass ): def __init__( self ): baseClass.__init__( self ) print "in child, gX is there? ", "gX" in globals() print "in child, foo is there? ", "foo" in globals() def myRun( self ): print "in testChild.MyRun" foo() print "gX = ", gX - at least some testing:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersif __name__ == "__main__": print "#"*5, "creating child" child = testChild() print "#"*5, "baseClass.run() execution" child.run() print "#"*5, "testChild.myRun() execution" child.myRun() - and its output:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters[Fri, 04 Nov 14:17 E0][cibak@localhost:~/test]> python test.py ##### creating child in child, gX is there? False in child, foo is there? False ##### baseClass.run() execution in base class run gX = 1 function foo called ##### testChild.myRun() execution in testChildMyRun function foo called gX = 1
Dear Python, if you knew how to cook and clean...