Reputation: 532
Instead of using a global variable, I'm trying to make an instance of a variable in a class, as it seems to be best practice. How do I reference this variable across other functions in the class? I would have thought that Test.running_sum
would work or at least running_sum
in test_function
, but I'm not having any luck with either. Thanks very much!
class Test:
def __init__(self):
self.root = None
running_sum = 0
def test_function(self):
print(Test.running_sum)
return
x = Test()
x.test_function()
Error:
Traceback (most recent call last):
File "so.py", line 1, in <module>
class Test:
File "so.py", line 10, in Test
x = Test()
NameError: name 'Test' is not defined
Upvotes: 1
Views: 67
Reputation: 37
In your __init__
function, you've created a local variable.
That variable will no longer exist after the function has completed.
If you want to create a variable specific to the object x
then you should create a self.running_sum
variable
class Test:
def __init__(self):
self.root = None
self.running_sum = 0
def test_function(self):
print(self.running_sum)
If you want to create a variable specific to the class Test
then you should create a Test.running_sum
variable.
class Test:
running_sum = 0
def __init__(self):
self.root = None
def test_function(self):
print(Test.running_sum)
Upvotes: 1
Reputation: 77900
As an object attribute: each object gets its own.
Test
is the class; self
is the Test
object that invoked the method.
class Test:
def __init__(self):
self.root = None
self.running_sum = 0
def test_function(self):
self.running_sum += 1
print(self.running_sum)
return
x = Test()
y = Test()
x.test_function()
y.test_function()
Output: 1 1
As a class attribute: all objects share the same variable.
self.__class__
is the class of the invoking object (i.e. Test
).
class Test:
running_sum = 0
def __init__(self):
self.root = None
def test_function(self):
self.__class__.running_sum += 1
print(self.__class__.running_sum)
return
x = Test()
y = Test()
x.test_function()
y.test_function()
Output:
1
2
Upvotes: 2
Reputation: 8091
Use self
parameter provided in the method signature.
Note that what you wrote is not a method, but an external function using class Test
. To write a method of Test
, the def
should be at one level of indentation inside class Test
as following:
class Test:
def __init__(self):
self.running_sum = 0
def test_function(self):
print(self.running_sum)
There are several things to add if you want an explanation behind this "best practice".
Assuming you write the following code:
class Test:
numbers = []
def add(self, value):
self.numbers.append(value)
The Test.numbers
list is instantiated once and shared accross all instances of Test
. Therefore, if 2 different instances add to the list, both act on the same list:
a = Test()
b = Test()
a.add(5)
b.add(10)
assert a.numbers == b.numbers == Test.numbers
When creating instance variables in the __init__
function, __init__
will be run at each instantiation, and therefore, the list will no longer be shared because they will be created for each individual instances.
class Test:
def __init__(self):
self.numbers = []
def add(self, number):
self.numbers.append(number)
a = Test()
b = Test()
a.add(5)
b.add(10)
assert a != b
Upvotes: 5
Reputation: 7146
how do I reference this variable across other functions in the class
Several things I see wrong here. First of all, you are calling running_sum
on the class itself which doesn't make sense since you are declaring running_sum
as an attribute of an instance of Test
. Second, from the way you formatted your question, it seems that test_function
is outside of the class Test
which doesn't make sense since you are passing self
to it, implying it is an instance method. To resolve you could do this:
class Test:
def __init__(self):
self.running_sum = 0
def test_function(self):
print(self.running_sum)
Then again this also is weird... Why would you need a "test_function" when you can simply test the value of running_sum
by simply doing:
x = Test()
x.running_sum
Upvotes: 1