Use a class variable in a class method - python

After I ran the code below, I got NameError: name 'result' is not defined. I tried to use class variable in a class method. Why does it give me an error?
class Test():
def __init__(self):
self.a=self.test1()
self.result = Test.test2()+Test.test3()
def test1(self):
a=100
return a
result = Test.test3()+100
#classmethod
def test2(cls):
b=200
return b
#staticmethod
def test3():
print("Testing3 is calling ")
c=500+Test.result
return c
Error:
result = Test.test3()+100
File "<ipython-input-29-29d4025016c1>", line 18, in test3
c=500+result
NameError: name 'result' is not defined

At the time the line of code in question is evaluated, result is not a class variable. It's been defined as an instance variable here:
def __init__(self):
self.a=self.test1()
self.result = Test.test2()+Test.test3()
but the line of code that defines Test.result as a class variable:
result = Test.test3()+100
has not yet finished executing at the time that it calls test3(), which itself has a dependency on Test.result.

Related

Python:Error calling class variable in a staticmethod

I am trying to call a class variable within a staticmethod, but when I called I am getting an error "hello" is not defined. any advise ?
class hello:
random1 = []
#staticmethod
def sub(x):
hello.random1.append(x -1)
sub.__func__(2)
if __name__ == "__main__":
print(hello.random1)
hello doesn't exist as a global name until you dedent out of the class definition (at which point the class is created and assigned to the global name hello). Change the code to:
class hello:
random1 = []
#staticmethod
def sub(x):
hello.random1.append(x -1)
hello.sub(2)
so sub is invoked after hello exists, and it will work.

Class variables - missing one required positional argument

I have two scripts. The first containing a class, with class variables defined and a function using those class variables. The second script calls the class and function within a function of it's own.
This sort of set up works fine for functions inside a class, however adding class variables is causing me the below error. Can anyone explain why, please and what I need to do to fix?
Thanks
obj1.py:
class my_test_class():
def __init__(self):
self.test1 = 'test1'
self.test2 = 'test2'
self.test3 = 'test3'
def test_func(self, var):
new_var = print(var, self.test1, self.test2, self.test3)
obj2.py
from obj1 import *
def import_test():
target_var = my_test_class.test_func('my test is:')
print(target_var)
import_test()
Error:
Traceback (most recent call last):
File "G:/Python27/Test/obj2.py", line 9, in <module>
import_test()
File "G:/Python27/Test/obj2.py", line 6, in import_test
target_var = my_test_class.test_func('my test is:')
TypeError: test_func() missing 1 required positional argument: 'var'
As the commentors have pointed out, since the test_func is a class method, we need to call it using a class instance object.
Also print function returns None, so doing new_var = print(var, self.test1, self.test2, self.test3) assigns new_var=None, so if you want to return the variable, you need to assign new_var = ' '.join([var, self.test1, self.test2, self.test3]), which creates a string with a whitespace between all the words, and return new_var
Combining all of this, the code comes out as follows
class my_test_class():
def __init__(self):
self.test1 = 'test1'
self.test2 = 'test2'
self.test3 = 'test3'
def test_func(self, var):
#Assign value to new_var and return it
new_var = ' '.join([var, self.test1, self.test2, self.test3])
return new_var
def import_test():
#Create instance of my_test_class
test_class = my_test_class()
#Call test_func using instance of my_test_class
print(test_class.test_func('my test is:'))
import_test()
The output will be my test is: test1 test2 test3

Python Variables across Class functions - how to call them?

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

Attribute Error in class attribute

I have written a class called cl:
class cl :
def __int__(self):
self.a = 0
def increment(self):
self.a +=1
def print_a(self):
print ("value : "+str(self.a))
I have written another class called test. However, I got an error when calling methods.
from cl import *
class test :
def __int__(self):
self.b = 0
self.c = cl()
def main(self):
self.c.increment()
self.c.print_a()
self.c.increment()
self.c.print_a()
d = test()
d.main()
What I got is this:
Traceback (most recent call last):
File "test_file.py", line 19, in <module>
d.main()
File "test_file.py", line 12, in main
self.c.increment()
AttributeError: test instance has no attribute 'c'
Can anyone explain why that happens and what is the issue with my code? I am a high school student. Can you explain to me? And can you help me to fix this?
You're misspelling __init__ with __int__:
class cl :
def __int__(self):
self.a = 0
Should be
class cl :
def __init__(self):
self.a = 0
Note that encompassing a main method inside of the test class is really an anti-pattern in Python; the form of
def main():
...
if __name__ == "__main__":
main()
is preferred and is more Pythonic.
For some reference on the if __name__ == "__main__" pattern, see:
https://stackoverflow.com/a/419185/1730261
https://docs.python.org/3/library/main.html
main function does not belong the class test , it belongs the test.py which your test class in, so the self in main is test.py , not test

python className not defined NameError

I have a class which i need to instantiate in order to call a method that it contains. When I access it from another class it works fine but when i run from terminal it says :
File "myClass.py", line 5, in <module>
class MyClass:
File "myClass.py", line 23, in ToDict
td=MyClass()
NameError: name 'MyClass' is not defined
Pasting the code:
class MyClass:
def convert(self, fl):
xpD = {}
# process some stuff
return xpD
if __name__ == "__main__":
source = sys.argv[1]
td = MyClass()
needed_stuff = td.convert(source)
print(needed_stuff)
The problem is that your if __name__ == "__main__" block is inside of your class definition. This will cause an error, as the code within the if will be run as part of the class being created, before the class been bound to a name.
Here's a simpler example of this error:
class Foo(object):
foo = Foo() # raises NameError because the name Foo isn't bound yet
If you format your code like this (that is, with the if unindented at the top level), it should work correctly:
class MyClass:
def convert(self, fl):
xpD = {}
# process some stuff
return xpD
if __name__ == "__main__":
source = sys.argv[1]
td = MyClass()
needed_stuff = td.convert(source)
print(needed_stuff)

Categories

Resources