[Tutor] Local variable look up outside the function and method
Martin A. Brown
martin at linux-ip.net
Sun May 12 10:12:01 EDT 2019
Hello Arup,
> In the following the function, x is reachable outside the scope of foo function.
> In [1]: x = 10
> In [2]: def foo():
> ...: return x
> In [3]: print(foo())
> 10
> But why it is not the case when the look up happens inside a
> instance method of a class?
>
> In [1]: class Foo:
> ...: x = 10
> ...: def bar(self):
> ...: return x
> In [2]: Foo().bar()
> ---------------------------------------------------------------------------
> NameError Traceback (most recent call last)
> <ipython-input-2-77cc08b8637b> in <module>
> ----> 1 Foo().bar()
>
> <ipython-input-1-202509464a3d> in bar(self)
> 2 x = 10
> 3 def bar(self):
> ----> 4 return x
>
> NameError: name 'x' is not defined
>
> I figured I have to access it like:
>
> In [1]: class Foo:
> ...: x = 10
> ...: def bar(self):
> ...: return self.__class__.x
> ...:
> ...: print(Foo().bar())
> 10
>
> Just want to know how these search happens in 2 contexts.
Probably the following is the best section of the documentation to
read:
https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables
Here's also a little sample that may help. By the way, I wouldn't
normally be doing things like "unset self.x" and creating those
peculiar methods, but I thought it might be instructive in this
case. This is using the same sort of technique you were with your
class called Foo. (I don't know all of the reasons why to inherit
from object, but I usually do...)
class Foo(object):
x = 10 # -- class variable
def __init__(self):
self.y = 20 # -- instance variable named 'y'
def setinstancex(self, x):
self.x = x
def removeinstancex(self):
del self.x
def report(self):
return (self.x, self.y)
if __name__ == '__main__':
f = Foo()
print('# -- f.x retrieves class value, f.y instance value')
print('f.x = %s, f.y = %s, Foo.x = %s' % (f.x, f.y, Foo.x))
print()
f.setinstancex(3.14159)
print('# -- f.x retrieves instance value, f.y instance value')
print('f.x = %s, f.y = %s, Foo.x = %s' % (f.x, f.y, Foo.x))
print()
print('# -- warning, we are about to change the value for Foo.x')
print()
Foo.x = 6.022141e-23
print('# -- f.x retrieves class value, f.y instance value')
print('f.x = %s, f.y = %s, Foo.x = %s' % (f.x, f.y, Foo.x))
print()
f.removeinstancex()
print('# -- f.x retrieves class value, f.y instance value')
print('f.x = %s, f.y = %s, Foo.x = %s' % (f.x, f.y, Foo.x))
print()
Good luck,
-Martin
--
Martin A. Brown
http://linux-ip.net/
More information about the Tutor
mailing list