Module scope is functionally almost-global. That is, it's so close to global you'll want to use it, but it's far enough away that you'll end up shooting yourself in the foot.
Consider this code snippet:
#!/bin/env python2.6 import os import sys varname = 33 vardict = { 'a' : 44 } # other imports here print "Starting!" def something(): print "thing", varname print "next" something() print "end"
This is what I call drop-thru code. All the variables are global, and the call to something() will fail because varname is out of scope.
Contrast this with what I prefer, well-encapsulated code:
#!/bin/env python2.6 import os import sys class SomeThing(object): def __init__(self): self.varname = 33 def something(self): print "thing", self.varname def main(self): self.vardict = { 'a' : 44 } # other imports here print "Starting!" print "next" self.something() print "end" st = SomeThing() st.main()
Nothing is global, it's obvious what the scope for things is. Clean, beautiful, easy to understand.
There are lots of examples of scope problems. I created this one for my team so they understood my frustration:
outside = 1 def function1(): try: print "f1 outside: %s" % (outside) outside += 1 except: print "no outside in function1." print "a outside: %s" % (outside) function1() print "b outside: %s" % (outside) def function2(): global outside try: print "f2 outside: %s" % (outside) outside += 1 except: print "no outside in function2" function2() function2() class Dum(object): def __init__(self): print "dum instantiated." def main(self): print "Dum main outside: %s" % (outside) def changeOutside(self, inval): outside = inval print "Dum changed: outside: %s" % (outside) def changeGlobalOutside(self, inval): global outside outside = inval print "Dum changed: outside: %s" % (outside) d = Dum() print "c outside: %s" % (outside) d.main() print "d outside: %s" % (outside) d.changeOutside(33) print "e outside: %s" % (outside) d.main() d.changeGlobalOutside(44) d.main() print "f outside: %s" % (outside) ______________________________________________________ output: krice4@zaphod:~/checkouts/userSandboxes/krice4$ python scopeTest.py a outside: 1 no outside in function1. b outside: 1 f2 outside: 1 f2 outside: 2 dum instantiated. c outside: 3 Dum main outside: 3 d outside: 3 Dum changed: outside: 33 e outside: 3 Dum main outside: 3 Dum changed: outside: 44 Dum main outside: 44 f outside: 44
In short, Drop-Thru Code is considered harmful. It allows for lots of scope problems that show up as bugs and frustrations later. So, avoid them. Put all the vars you can in a class and invoke that class, you'll be glad you did. IMHO.
No comments:
Post a Comment