Consider the following class in Python 3:
class Foo(AnotherClass):
id_counter = 0
def __init__(self):
super().__init__()
self.id = Foo.id_counter
Foo.id_counter += 1
Is there a keyword (similar to Python's super in this case) that can be used to access class variables in place of putting the class name Foo?
type(self) or self.__class__ will return the actual class of self, which might be a subclass of Foo or Foo:
class Foo(AnotherClass):
id_counter = 0
def __init__(self):
super().__init__()
self.id = type(self).id_counter
type(self).id_counter += 1
Related
I have a project with 3 classes, I will represent them as in the code below, in the first it will run class 1, and it must change the value of class 2, and when calling the variable in class 3 you should read the value we put in class 1...
but the code I made did not change That value
class class1(QMainWindow):
def __init__(self):
self.models = class2()
self.models.variable = 200
class class2(QWidget):
variable = 0
def __init__(self):
super().__init__()
class class3:
def __init__(self):
super().__init__()
self.models = class2()
print(self.models.variable) # Here I want to show 200 but the value that appears is 0
There must be 3 classes as in the order, also class 1 must not be called in class 3
It sounds like you want to make class2 as a namespace to hold variable. So just do that:
class class1(QMainWindow):
def __init__(self):
self.models = class2()
class2.variable = 200
class class2(QWidget):
variable = 0
def __init__(self):
super().__init__()
class class3:
def __init__(self):
super().__init__()
self.models = class2()
print(class2.variable)
i have the following code:
class A:
def __init__(self, name,val):
self.name = name
self.val = val
class B(A):
super(A)__init__ // here i want to have just a variable self.name. that means val=0
def outputName(self):
print(f"name = {self.name}")
class C(A):
super(A)__init__ // here i want to habe just a variable self.val. that means name = 0
def outputVal(self):
print(f"val= {self.val}")
n = B('martin')
v = C(25)
outputName(n)
outputVal(v)
My Question: How can i specify that i just want name in class B in val in class C?
an another solution that i know is e.g. n=B('Martin',0) and v =C(0,25) but i think it is nonesense
Any idea how i can right it better?
Here you just need to feed a specific variable to super(). Minor notes: since you have a single inheritance, you don't need to specify which class you're instantiating when calling super(). Also, don't forget the "dot" in super().__init__() and, most importantly, don't forget to define __init__() in subclasses:
class A:
def __init__(self, name, val):
self.name = name
self.val = val
class B(A):
def __init__(self, name):
super().__init__(name=name, val=None) # Only initialise name variable of the base class
def outputName(self):
print(f"name = {self.name}")
class C(A):
def __init__(self, val):
super().__init__(name=None, val=val) # Same here but with val instead.
def outputVal(self):
print(f"val= {self.val}")
Or, alternatively, as Tim has suggested you can make class A have default values in init:
class A:
def __init__(self, val=None, name=None):
I am trying to pass a value from one function in a class to another function in a class. Below is some simplified code of what I'm trying to achieve.
class test:
def __init__(self):
self.differentvalue = 0
def set(self, value):
print(value)
self.differentvalue = value #this is not the same value as defined above - i.e. this is a new variable created in foo class i believe
class foo:
def __init__(self):
test.set(self, 5)
if __name__ == '__main__':
foo()
I do not want __init__ to be called so test().set(5) is not an option.
Cheers,
Sean
You have two options
Option #1, best option if you need to keep a different context for differtvalue for each instance of Test
class Test:
def __init__(self):
self.differentvalue = 0
def set(self, value):
self.differentvalue = value
class foo:
def __init__(self):
test = Test()
test.set(5)
Option #2, best if you need to keep the latest value for differentvalue across all Test classes
class Test:
__DIFFERENTVALUE = 0
def __init__(self):
pass
#staticmethod
def set(value):
Test.__DIFFERENTVALUE = value
class foo:
def __init__(self):
Test.set(5)
You could define a class variable with a value of None, then upon calling the setter for the first time, assign a value to it. Further calls to the setter will not change the value.
In the following example, an __init__ method is not required in Test.
class Test:
differentvalue = None
#classmethod
def set(cls, value):
if value is not None and Test.differentvalue is None:
Test.differentvalue = value
class foo:
def __init__(self):
Test.set(5)
if __name__ == '__main__':
foo()
print(Test.differentvalue)
Test.set(12)
print(Test.differentvalue)
output:
5
5 # the value did not change
I have a parent class with 3 items in it. I am trying to create a child class that when called updates a set item in the parent class.
class NOS:
def __init__(self):
self.Bike = 0
self.car = 0
self.plane = 0
class buy(NOS):
def __init__(self, mode):
NOS.__init__(self)
self.mode = mode
def buy_comp(self, value):
self.mode += value
if i called it like below
a = buy('bike')
a.buy_comp(4)
I am trying to get to a situation where bike would equal 4. The above did not work. Neither did the below where i tried to use buy as a function instead of a class.
def buy(self, mode, value):
self.mode += value
a= NOS()
a.buy('bike', 5)
Here i got the error - AttributeError: 'NOS' object has no attribute 'bike'
In the first example you posted, your child class "buy" is not actually a child class, because it is not inheriting from "NOS".
Not exactly sure what you're trying to achieve. Maybe this is helpful?
class Parent:
def __init__(self):
self.foo = "Parent Foo"
class Child(Parent):
def __init__(self):
Parent.__init__(self)
def set_foo(self, new_foo):
self.foo = new_foo
child = Child()
print(child.foo)
child.set_foo("New Foo")
print(child.foo)
Output:
Parent Foo
New Foo
EDIT - Oh, I think I get it now. Something like this maybe?
class NOS:
def __init__(self):
self.bike = 0
self.car = 0
self.plane = 0
class Buy(NOS):
def __init__(self, item_name):
NOS.__init__(self)
self.item_name = item_name
def buy_comp(self, amount):
try:
old_value = getattr(self, self.item_name)
except NameError:
# No such item exists
pass
else:
setattr(self, self.item_name, old_value + amount)
a = Buy("bike")
print(a.bike)
a.buy_comp(4)
print(a.bike)
However, I think that if you're relying on getattr and setattr, there's bound to be a better way. I have a feeling that this may be an instance of an XY problem. Can you tell us more about the actual use case? I'm sure there's a more elegant solution you could benefit from.
I'm having some trouble with changing the value of a class at runtime and then instantiating it into an object, then storing that object inside of another class and putting that into python dictionary.
Here is a small code snippet I wrote to illustrate the problem:
import unittest
class cls1(object):
def __init__(self, obj):
self.obj = obj
class cls2(object):
def __init__(self):
self.var = 1
class Testdict(unittest.TestCase):
def __init__(self):
self.objs = dict()
def runTest(self):
obj2 = cls2()
obj1 = cls1(cls2())
self.objs["test1"] = obj1
self.assertEqual(self.objs["test1"].obj.var, 1)
cls2.var = 2
self.assertEqual(cls2.var, 2)
obj1 = cls1(cls2())
self.objs["test2"] = obj1
self.assertEqual(self.objs["test1"].obj.var, 1)
self.assertEqual(self.objs["test2"].obj.var, 2)
if __name__ == "__main__":
d = Testdict()
d.runTest()
Why would cls2 not instantiate with having it's var equal to 2?
I hope this question makes some sense.
What you're showing can't work. Ever.
class Cls2(object):
def __init__(self):
self.var = 1
That's an instance variable. It's not a class variable. You can't access that .var with Cls2.var That variable only exists within each unique instance of the class.
Cls2.var = 2
Does not change the self.var instance variable. That creates a new class variable in the Cls2 class.
You'd need to do something like this.
class Cls2(object):
default= 1
def __init__(self):
self.var = Cls2.default
Now you can do
Cls2.default= 2
And the rest of whatever it is you're doing should work.
Your test would work if cls2 didn't overwrite cls.var when it is instantiated.
Try this:
class cls2(object):
def __init__(self):
try:
self.var
except:
self.var = 1
The try statement just checks to see if you've already set var.