Class scoping problem...
Kragen Sitaker
kragen at dnaco.net
Wed Sep 27 00:40:26 EDT 2000
More information about the Python-list mailing list
Wed Sep 27 00:40:26 EDT 2000
- Previous message (by thread): Class scoping problem...
- Next message (by thread): Class scoping problem...
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
In article <mailman.969985661.20283.python-list at python.org>, Simon Brunning <SBrunning at trisystems.co.uk> wrote: >I'm having a bit of a problem with scoping within a class. Something similar >is mentioned in Andrew Kuchling's 'Python Warts' page, but I can't find a >workaround. > >Take the following: > >class Foo: > > def __init__(self): > self.bar = 1 > > def baz(self): > > def quix(): > return self.bar > > return quix() I think you mean 'return quix', so you're returning something you can call later. quix() here will return 1, so baz will return 1, as you have written it. (Except that it doesn't work, which I'll get to in a minute.) >Running this, I get this: > > File "H:\SBrunning\Python\ClassScope.py", line 9, in quix > return self.bar >NameError: There is no variable named 'self' > >Which is fair enough, 'cos self.bar isn't in the global namespace, and nor >is it in baz's namespace. But what do I *do*? It *is* in baz's namespace; self is a formal parameter of baz. It's listed in the parameter list. Where it isn't is in quix's namespace, which is the problem. There are several possibilities. Python has two things that are callable as functions: user-defined functions, methods, and class instances --- THREE things that are callable as functions: user-defined functions, methods, class instances, and classes ---- FOUR things that are callable as functions --- AMONGST the things that are callable in Python are such things as user-defined functions, methods . . . I'll come in again. The simple thing is just to return a bound method: class Ximenez: def viking(self): return self.spam def getviking(self): return self.viking Depending on the context, you might be able to replace x.getviking() with x.viking in the calling code and save yourself a helper. So that's a method. How about a user-defined function? You can stick stuff in argument defaults: class Biggles: def __init__(self): self.count = 0 def torture(self): print "I have poked you with %d pillows" % self.count self.count = self.count + 1 def get_torture(self): return lambda s=self: s.torture() b = Biggles() x = b.get_torture() x() x() x() Which you can also write, as you did, with a named inner function: def get_torture(self): def function_that_needs_no_name(s=self): s.torture() return function_that_needs_no_name This doesn't work well in every case, for example, when the function you're returning is going to be called with variable numbers of arguments or keyword arguments. For the heavy-duty work --- like the XML/XHTML stuff I posted earlier today --- you need to make class instances that can be called. It's probably overkill here, but here's how to do it: class TortureMaster: def __init__(self, torturer): self.torturer = torturer def __call__(self): self.torturer.torture() class Fang: def __init__(self, racktype): self.racktype = racktype self.count = 0 def torture(self): print ("I have tied you to the %s rack %d times" % (self.racktype, self.count)) self.count = self.count + 1 def get_torture(self): return TortureMaster(self) b = Fang('dish') x = b.get_torture() x() x() x() There may be other ways to solve the problem, but I haven't figured out how to do it by returning a class or a built-in function from get_torture. I guess you can tell I'm from Perl land. <wink> I'd recommend using lambdas when you don't need fancy parameter handling or statements in the body, inner functions when you don't need fancy parameter handling, and class instances when you need fancy parameter handling. >I-used-foo-so-Tim-won't-help-ly-yrs, reading-too-many-Python-scripts-ly y'rs - kragen -- <kragen at pobox.com> Kragen Sitaker <http://www.pobox.com/~kragen/> Perilous to all of us are the devices of an art deeper than we ourselves possess. -- Gandalf the Grey [J.R.R. Tolkien, "Lord of the Rings"]
- Previous message (by thread): Class scoping problem...
- Next message (by thread): Class scoping problem...
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list