I have a class, call it Test, which has a variable var. It uses this variable in its __init__ mathod, and maybe looks something like this:
class Test(object):
var = 0
def __init__(self):
print(self.var)
In order to change this variable before I initialise the class, this seemed logical
test = Test
test.var = 42
test.__init__(test)
...and behaves like I expected it to. (printing 42)
However, when the code looks like this:
class Test(Canvas):
var = 0
def __init__(self, parent):
Canvas.__init__(self, parent)
self.pack()
print(self.var)
test = Test
test.var = 42
test.__init__(test, frame) #tkinter frame I had made elsewhere
... it throws an error at the canvas.__init__ line, complaining that
TypeError: _options() missing 1 required positional argument: 'cnf'
I doubt this is a problem with the cnf parameters, as the class works fine when called 'normally', as in test = Test(). I have a feeling the parameters are being passed differently.
Can someone shed some light?
Thanks in advance
You seem to have a misunderstanding of how python classes work.
In your code you're doing test = Test, which does nothing but make test point to the class Test. It does not create an instance of Test.
If you want to change the value of a class value, there's no need to do an assignment to a temporary variable first. For example. to create a class that has var set to zero, and you later want to change it to 42, you can do it this way:
class Test(object):
var = 0
...
Test.var = 42
Also, you should never call __init__ directly, except perhaps when calling the function of the superclass with the __init__ of a subclass. Instead, you create an instance of the class which will automatically call the __init__ for you:
test = Test()
This all works the same whether you inherit from a tkinter class or any other class.
When you run the following example, it will print out 42:
import tkinter as tk
class Test(tk.Canvas):
var = 0
def __init__(self, parent):
tk.Canvas.__init__(self, parent)
self.pack()
print(self.var)
Test.var = 42
root = tk.Tk()
test = Test(root)
Note that because this is a class variable, changing it once will change it for all instances.
Related
I am trying to write a function taking a string as an argument and using this argument as a class object.
Note that my explanantion might be strangely formulated sice I could not find an answer online. The MWE below should clarify what I mean, the problematic line is indicated.
Edit: in the MWE, "print" is an example. I need to be able to call the object to update it, print it or, in the case of a list, append to it. I need access to the object itself, not the value of the object.
MWE
# Create a class
class myClass():
def __init__(self):
self.one = "Test"
self.two = "Plop"
# Define function
def myFunction (parameter):
print(myObject.parameter)##### This line is currently not possible.
# Use class
myObject = myClass()
# Use function
myFunction("one")
I am not trying to append a new object to the class, only to call an existing object.
Is this even possible?
Looks like you need the built-in function called getattr
my_object = myClass()
def my_function(parameter):
print(getattr(my_object, parameter, None))
also this is not the best practice to call objects from outer scope like that. i'd suggest to use dict magic methods:
class MyClass:
def __init__(self):
self.one = "Test"
self.two = "Plop"
def __getitem__(self, parameter):
return getattr(self, parameter, None)
def __setitem__(self, parameter, value):
return setattr(self, parameter, value)
my_obj = MyClass()
parameter = "x"
print(my_obj[parameter])
my_obj[parameter] = "test"
print(my_obj.x)
You need to use getarttr():
# Create a class
class myClass():
def __init__(self):
self.one = "Test"
self.two = "Plop"
# Use class
myObject = myClass()
# Define function
def myFunction(parameter):
print(getattr(myObject, parameter))##### This line is currently possible.
# Use function
myFunction("one")
i'am new to python and try to get the new value for my bool in a class .
i try create a global, set in the init.
How can i get the new value of the test bool in getnewvalue() ?
Here is my code :
test = False
class myclass():
def changevalue()
test = True
getnewvalue()
def getnewvalue():
print(test)
If you want to have data inside your class, it's a good idea to use the __init__()
and save it like that. More here in the Python tutorial: Class Objects.
And use the __init__ to initialize the class with desired values.
Your code should look something like this:
test = False
class myclass():
def __init__(self, test):
self.test = test # self keyword is used to access/set attrs of the class
# __init__() gets called when the object is created, if you want to call
# any function on the creation of the object after setting the values
# you can do it here
self.changevalue()
def changevalue(self): # if you want to access the values of the class you
# need to pass self as a argument to the function
self.test = not test
self.getnewvalue()
def getnewvalue(self):
print(self.test) # use self to access objects test value
_class = myclass(False)
Or if you just want to have a class with functions, you can do something like this:
test = False
class myclass():
#staticmethod
def changevalue(val)
return not val
#staticmethod
def getnewvalue(test):
print(test)
_class = myclass()
test = _class.changevalue(test)
This way it won't print your value on call because it's just setting your value to return of that function. You'll have to do it yourself but that shouldn't be a problem.
More about staticmethods here: #staticmethod
Add
global test
to both functions. The resulting code would be...
test = False
class myclass():
def changevalue():
global test
test = True
getnewvalue()
def getnewvalue():
global test
print(test)
global allows the function to access variables outside of itself.
Hope this helps!
How can I pass class attribute to a class method so that the attribute will be modified?
class foo:
def __init__(self):
self.diamond = 1
self.gold = 10
self.change(self.diamond)
self.change(self.gold)
def change(self, x):
x+=1
model = foo()
print(model.diamond)
output:
1
I want diamond becomes 2.
Is this a good solution for you?
class foo:
def __init__(self):
self.diamond = 1
def change(self):
self.diamond += 1
model = foo()
model.change()
print(model.diamond)
Let me say this first that you have no class method, or class variable in your example. What you have are instance variables and instance methods, note the self keyword. Now, with that said, you can access and modify your instance variables from any instance method, just like #Almog answered earlier.
The x in your change method is a local variable, basically it's not available outside your method. As for how you modify a variable by passing it to a function, it's not doable with your code I think. You would need something like a dataclass, which you can modify. Check out 'PassByValue' and 'PassByReference' concepts relating to this. Maybe someone else here can help with your particular situation.
I have a class with certain inside variables in it, let's take a simple example
class Example:
def __init__(self):
self.variable = "something"
self.anotherVariable = "somethingElse"
Now the signature in "inspect" only provides me with what's in the brackets, which in this case only the self, but can I somehow get a list of variable names within the class, so if I run that code it will result in:
Output:
(self.variable, self.anotherVariable)
I appreciate all the help :)
I don't think you need inspect:
class Example:
def __init__(self):
self.variable = "something"
self.anotherVariable = "somethingElse"
print(Example.__init__.__code__.co_names)
Output:
('variable', 'anotherVariable')
Another way is like this; invoking dir on object itself:
class Example:
def __init__(self):
self.variable = 1
self.anotherVariable = 2
obj = Example()
print([attrib for attrib in dir(obj) if not attrib.startswith("_")])
O/P
['variable', 'anotherVariable']
There are a few ways to do this I prefer __dict__.
This is built into every class you make unless you override it. Since we’re dealing with a Python dictionary, we can just call its keys method.
Here is an example.
class Example:
def __init__(self):
self.variable = "something"
self.anotherVariable = "somethingElse"
obj = Example()
variables = obj.__dict__.keys()
Output --> ['varTwo', 'varThree', 'varOne']
Hope this helps. There are also few other methods you can check out here :
http://www.blog.pythonlibrary.org/2013/01/11/how-to-get-a-list-of-class-attributes/
So I am recently new to Python, but I seem to be able to program some stuff and get it working. However I've been trying to expand my knowledge of how things work in the language, and putting this simple file together confuses me.
class TestA:
def __init__(self):
self.varNum = 3
def printNum(self):
print(self.varNum)
class TestB:
varNum = 0
def __init__(self):
varNum = 3
def printNum(self):
global varNum
print(varNum)
a = TestA()
a.printNum()
b = TestB()
b.printNum()
The code to TestA prints 3 to the screen properly. However the code for TestB instead gives me a NameError stating that: 'varNum' is not defined. And I get that error whether i have the global varNum line there or not.
I suppose what confuses me, is I see the __init__ function as a class constructor. And when I have programmed with languages such as Java or C# I've declared global variables outside of the constructor so that their scope is the whole class. Is that not a thing in Python? The code I've written I just kind of tagged self. onto everything because I was just trying to get some stuff put together quickly, but I am trying to figure more out about the language now. Is self. the only way in Python to make class scope variables? Or are there other ways?
Thanks for your time :)
In Python, variables declared inside the class definition, but not inside a method are class or static variables:
class TestB:
varNum = 0
This creates a class-level varNum variable, but this is distinct from any instance-level varNum variable, so you could have:
class TestB:
varNum = 0
def __init__(self):
self.varNum = 3
b = TestB()
print(b.varNum) # print 3
print(TestB.varNum) # print 0
Thus, class TestB should work in this way:
class TestB:
varNum = 0
def __init__(self):
self.varNum = 3
def printInstanceNum(self):
print(self.varNum)
def printClassNum():
print(TestB.varNum)
b = TestB()
b.printInstanceNum() # print 3
TestB.printClassNum() # print 0
Note that since there's no any reference to instance object in method printClassNum(), we don't have to put self as an argument. The method could actually become a staticmethod:
class TestB:
varNum = 0
#staticmethod
def printClassNum():
print(TestB.varNum)
Ref
class objects
static method