Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Variable Scope and Classes

In Python, if I define a variable:

my_var = (1,2,3)

and try to access it in __init__ function of a class:

class MyClass:
    def __init__(self):
        print my_var

I can access it and print my_var without stating (global my_var).

If I put my_var right after class MyClass however, I get scope error (no global variable found).

What is the reason for this? How should I do this? Where can I read about this to learn? I did read Python Class page but I did not encounter its explanation.

Thank you

like image 356
Phil Avatar asked Oct 17 '12 19:10

Phil


People also ask

What is the scope of class variable in Python?

A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace. Although scopes are determined statically, they are used dynamically.

What are the 4 types of variable scopes?

You will learn about the four different scopes with the help of examples: local, enclosing, global, and built-in. These scopes together form the basis for the LEGB rule used by the Python interpreter when working with variables.


2 Answers

Complementing @mgilson's answer: Note that Python Class variables are shared among the class instances. And the behaviour might be VERY unexpected and seem weird. In practice it works like this:

class MyClass(object):
    my_var = 10

    def __init__(self):
        print(self.my_var)


m1 = MyClass()
print(m1.my_var)
>>> 10          # this is fine

MyClass.my_var = 20
print(m1.my_var)
>>> 20          # WTF? :) --> shared value

m2 = MyClass()
print(m2.my_var)
>>> 20          # this is expected

m1.my_var = 30
print(MyClass.my_var)
>>> 20          # this is also expected

MyClass.my_var = 40 
print(m1.my_var)
>>> 30           # But WHY? Isn't it shared? --> 
                 # The value WAS shared until m1.my_var = 30 has happened.

print(m2.my_var)
>>> 40           # yep m2.my_var's value is still shared :)
like image 188
Zaur Nasibov Avatar answered Oct 18 '22 18:10

Zaur Nasibov


When you put it right after class MyClass, it becomes a class attribute and you can get access to it via MyClass.my_var or as self.my_var from within the class (provided you don't create an instance variable with the same name).

Here's a little demo:

my_var = 'global'
class MyClass(object):
   my_var = 'class' 
   def __init__(self):
      print my_var #global
      print MyClass.my_var #class
      print self.my_var #class -- Only since we haven't set this attribute on the instance
      self.my_var = 'instance' #set instance attribute.
      print self.my_var #instance
      print MyClass.my_var #class
like image 22
mgilson Avatar answered Oct 18 '22 19:10

mgilson