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
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.
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.
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 :)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With