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/
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to