Phil
Phil

Reputation: 14681

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

Upvotes: 8

Views: 9384

Answers (4)

Zaur Nasibov
Zaur Nasibov

Reputation: 22679

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 :)

Upvotes: 12

mgilson
mgilson

Reputation: 310287

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

Upvotes: 11

kindall
kindall

Reputation: 184455

If you write:

class MyClass(object):
    my_var = (1, 2, 3)

you are defining an attribute of MyClass, not a variable. In your __init__ method, then, it is MyClass.my_var.

Upvotes: 2

retracile
retracile

Reputation: 12349

Once it's inside the class definition, it's no longer global, it's now in the class object's namespace. You can access it with self.my_var within __init__ though...

Upvotes: 1

Related Questions