global declarations
Bengt Richter
bokr at oz.net
Tue Dec 24 11:12:20 EST 2002
More information about the Python-list mailing list
Tue Dec 24 11:12:20 EST 2002
- Previous message (by thread): global declarations
- Next message (by thread): OT: Connect to the list's newsgroup!
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Tue, 24 Dec 2002 00:05:41 +0100 (MET), Frederik Fuest <ffrederik at gmx.de> wrote: >> x = 10 >> class ManagerOfX: >> def printIt(self): >> global x >> print x >> x = x + 1 >> >> def restoreIt(self): >> global x >> x = 10 >> >> m = ManagerOfX() >> m.printIt() >> m.printIt() >> m.restoreIt() >> m.printIt() >> >> >> Global variables lock you into some bad patterns, make code hard to >> reuse/scale. Avoid their use where possible. For example, the above >> should >> be rewritten as... >> >> class ManageOfX: >> x = 10 >> >> def printIt(self): >> print self.x >> self.x = self.x + 1 >> >> def restoreIt(self): >> self.x = 10 > > >thank you very much, this was exactly was i needed to know! >now i've killed almost all global variables in my code, and it runs! But if you are using the above, there's a good chance "it runs" doing something different than you think ;-) >>> class ManageOfX: ... x = 10 ... def printIt(self): ... print self.x ... self.x = self.x + 1 ... def restoreIt(self): ... self.x = 10 ... Ok. Here's an instance >>> mx = ManageOfX() We write what looks like an instance attribute access: >>> mx.x 10 And what we got was the class variable x. So far so good, if that was the intent. >>> vars(mx) {} This shows what instance attributes there are. None at this time. >>> mx.printIt() 10 That printed the same class variable x, and used it on the right hand side of the assignment statement, but on the left hand side, it does NOT replace the class variable binding, it creates an instance attribute x: >>> vars(mx) {'x': 11} As the above shows. >>> ManageOfX.x 10 The class variable is still there, as the above shows. >>> mx.restoreIt() >>> vars(mx) {'x': 10} The effect of restoreIt was to rebind the instance attribute, not touching the class variable >>> mx.x 10 The above saw the instance attribute, so let's get rid of it and see what happens: >>> del mx.x >>> mx.x 10 This is no longer the instance attribute, but the search finds the class variable value. >>> vars(mx) {} The above shows that the instance attribute is gone >>> ManageOfX.x 10 and the class variable is still there. If you use printIt more than one time, the presence of the instance attribute created the first time will shadow the class attribute, and thus the addition will succeed in accumulating. If we change the restoring value to something different from the class variable, it will show that you can't reach a class variable with self.x = something (unless you have defined a property that acts on class variables, but that's a different story). To illustrate: >>> class ManageOfX: ... x = 10 ... def printIt(self): ... print self.x ... self.x = self.x + 1 ... def restoreIt(self): ... self.x = 20 ... >>> mx = ManageOfX() >>> ManageOfX.x 10 >>> mx.x 10 >>> vars(mx) {} >>> mx.restoreIt() >>> mx.x 20 That was the instance attribute x not the class variable x >>> ManageOfX.x 10 as you can see by accessing explicitly >>> vars(mx) {'x': 20} There are lots of options. Defining a module that you can import into any module in your app that needs to share app-wide-global globals may be a good option. If the file is MyGlobals.py and you import MyGlobals, you can access things like print MyGlobals.x and you can also set them with MyGlobals.x = 'new value' etc. You could also have MyGlobals.py create an instance of ManageOfX the first time it's imported (subsequent imports don't normally re-execute the code, so other imports will see the results of the first just like the first importer sees it). It there were a statement in MyGlobals.py like mx = ManageOfX() (after the class definition code) (to use the example), then you could access mx after import MyGlobals like MyGlobals.mx.printIt() or plain MyGlobals.mx.x or MyGlobals.ManageOfX.x etc. analogous to the way we were doing interactively. So you can play combinations. Also, you could write __init__ code in the ManageOfX class to read a config file or whatever, and store things in the mx instance. If you want to have actions triggered when you access what looks like ordinary instance attributes, you can define properties in its class definition to do anything you like. So there is tremendous flexibility ;-) Regards, Bengt Richter
- Previous message (by thread): global declarations
- Next message (by thread): OT: Connect to the list's newsgroup!
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list