Python - Calling a variable exists in 3 classes - python

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)

Related

Inheritance of variables from a subclass

In the code below, I have a class (MainClass) that contains two subclasses (Class1 and Class2).
class MainClass():
def __init__(self):
self.teste = 'abcdefg'
class Class1():
def __init__(self):
self.a = 'a'
self.b = 'b'
self.c = 'c'
class Class2(Class1):
def __init__(self):
super().__init__()
self.d = 'a'
self.e = 'b'
self.f = 'c'
Class2 when receiving Class1 as inheritance, automatically inherits the variables of Class1.
Now I would like to do the same and take these other variables to my MainClass.
I managed to do some things by assigning it to a specific variable like self.values (eg: self.values.a), however, I need these variables to be inside the main class for access. (eg: self.a)
Another way that worked was, doing this workaround: `self.dict.update(self.Class2.dict)
However, I am not convinced of the method. I would like to know if there is a better way to "inherit" this subclass in my main class. Is there any way using something like super().__init__() or something like that to accept my subclass?
Thanks!
What about if instead of inheritance you use composition, by this I mean creating an instance of Class2 in you constructor (init) method inside your main class, something like this:
# Define Class1 and Class2 at global scope
class Class1():
def __init__(self):
self.a = 'a'
self.b = 'b'
self.c = 'c'
class Class2(Class1):
def __init__(self):
super().__init__()
self.d = 'a'
self.e = 'b'
self.f = 'c'
class MainClass():
def __init__(self, *args, **kwargs):
self.class_2 = Class2(*args, **kwargs)
def some_function(self):
some_operation = self.class_2.a * self.class_2.b
# Now you can access class2 variables like this (self.class_2.some_variable)
UPDATE
Whay did you nested your classes inside your main class, can't you define them at global scope?
De-indent Class1 and Class2 so that they're no longer inside MainClass. Then MainClass can inherit either of them.
class Class1:
def __init__(self):
self.a = 'a'
self.b = 'b'
self.c = 'c'
class Class2(Class1):
def __init__(self):
super().__init__()
self.d = 'a'
self.e = 'b'
self.f = 'c'
class MainClass(Class2):
def __init__(self):
super().__init__()
self.teste = 'abcdefg'

Changes to attribute in a class be activated in another class

class Main:
def __init__(self):
self.number = 10
class Sub1(Main):
def __init__(self):
super().__init__()
def addnum(self):
self.number += 1
print(self.number)
class Sub2(Main):
def __init__(self):
super().__init__()
def func(self):
print(self.number)
sub2 = Sub2()
sub1 = Sub1()
sub1.addnum()
sub2.func()
In class Main, attribute number=10 is created
In class Sub1, function addnum increases number by 1
In class Sub2, function func prints the number, it prints 10, how do I make it print 11?
So how can changes to an attribute in a class be activated in another class?
So you want number to be shared across Main, Sub1, and Sub2, so that if an instance of Sub1 modifies number instances of Main and Sub2 can access that new number. You really don't want to do this, if you need to share variables across classes you're better off using a container that all those classes can access. For example:
class Container:
number = 10
class Main:
def __init__(self):
self.container = Container()
def set_number(self, new_num):
self.container.number = new_num
class New:
def __init__(self, main):
self.container = main.container
def addone(self):
self.container.number += 1
main = Main()
new = New(main)
new.addone()
print(main.container.number) # 11
main.set_number(1000)
print(new.container.number) # 1000
This is just a much cleaner and easier approach.

Acessing a property from a parent object

In python, I'm creating an object inside a class:
class A:
def __init__(self):
self.one = 1
self.two = B()
Now I define class B, and I want to access self.one from inside B()
class B()
def __init__(self):
self.three = "hello"
# here I want to change self.one from class A to self.one + 1
# how to do it without doing self.two = B(self.one) on class A
# definition?
something = A()
is there a way to reference the parent object property, or do we have to pass the value when creating the object ?
A is not a parent object, parent object is the object from which you inherit. B has no knowledge about A, you have to modify your classes structure, for example by passing reference to parent in B's constructor (which you say you do not want to do, althouth it is not entirely clear what do you mean by "without doing self.two = B(self.one)", as this would pass copy of self.one, not a reference, but this is the way to do it)
class A:
def __init__(self):
self.one = 1
self.two = B(self)
class B()
def __init__(self, parent):
self.three = "hello"
self.parent = parent
print self.parent.one # or do whatever you want with it
If you really have to do this, you can use introspection, but this is ugly, hacky, bad way of achieving the result
import inspect
class A():
def __init__(self):
self.one = 1
self.two = B()
class B():
def __init__(self):
self.three = "hello"
self.parent = inspect.currentframe().f_back.f_locals['self']
print self.parent.one

Python keyword to access class variable

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

Problem with Python nested objects being stored in a dictionary

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.

Categories