How would I access variables from one class to another? - python

I am writing a program that is utilizing multiple classes. I have one class that is dedicated to determining values for a set of variables. I would then like to be able to access the values of those variables with other classes. My code looks as follows:
class ClassA(object):
def __init__(self):
self.var1 = 1
self.var2 = 2
def methodA(self):
self.var1 = self.var1 + self.var2
return self.var1
class ClassB(ClassA):
def __init__(self):
self.var1 = ?
self.var2 = ?
object1 = ClassA()
sum = object1.methodA()
print sum
I use classA to initialize 2 variables (var1 and var2). I then use methodA to add them, saving the result as var1 (I think this will make var1 = 3 and var2 = 2). What I want to know is how would I have ClassB then be able to get the values for var1 and var2 from ClassA?

var1 and var2 are instance variables. That means that you have to send the instance of ClassA to ClassB in order for ClassB to access it, i.e:
class ClassA(object):
def __init__(self):
self.var1 = 1
self.var2 = 2
def methodA(self):
self.var1 = self.var1 + self.var2
return self.var1
class ClassB(ClassA):
def __init__(self, class_a):
self.var1 = class_a.var1
self.var2 = class_a.var2
object1 = ClassA()
sum = object1.methodA()
object2 = ClassB(object1)
print sum
On the other hand - if you were to use class variables, you could access var1 and var2 without sending object1 as a parameter to ClassB.
class ClassA(object):
var1 = 0
var2 = 0
def __init__(self):
ClassA.var1 = 1
ClassA.var2 = 2
def methodA(self):
ClassA.var1 = ClassA.var1 + ClassA.var2
return ClassA.var1
class ClassB(ClassA):
def __init__(self):
print ClassA.var1
print ClassA.var2
object1 = ClassA()
sum = object1.methodA()
object2 = ClassB()
print sum
Note, however, that class variables are shared among all instances of its class.

Can you explain why you want to do this?
You're playing around with instance variables/attributes which won't migrate from one class to another (they're bound not even to ClassA, but to a particular instance of ClassA that you created when you wrote ClassA()). If you want to have changes in one class show up in another, you can use class variables:
class ClassA(object):
var1 = 1
var2 = 2
#classmethod
def method(cls):
cls.var1 = cls.var1 + cls.var2
return cls.var1
In this scenario, ClassB will pick up the values on ClassA from inheritance. You can then access the class variables via ClassA.var1, ClassB.var1 or even from an instance ClassA().var1 (provided that you haven't added an instance method var1 which will be resolved before the class variable in attribute lookup.
I'd have to know a little bit more about your particular use case before I know if this is a course of action that I would actually recommend though...

var1 and var2 is an Instance variables of ClassA. Create an Instance of ClassB and when calling the methodA it will check the methodA in Child class (ClassB) first, If methodA is not present in ClassB you need to invoke the ClassA by using the super() method which will get you all the methods implemented in ClassA. Now, you can access all the methods and attributes of ClassB.
class ClassA(object):
def __init__(self):
self.var1 = 1
self.var2 = 2
def methodA(self):
self.var1 = self.var1 + self.var2
return self.var1
class ClassB(ClassA):
def __init__(self):
super().__init__()
print("var1",self.var1)
print("var2",self.var2)
object1 = ClassB()
sum = object1.methodA()
print(sum)

we can access/pass arguments/variables from one class to another class using object reference.
#Class1
class Test:
def __init__(self):
self.a = 10
self.b = 20
self.add = 0
def calc(self):
self.add = self.a+self.b
#Class 2
class Test2:
def display(self):
print('adding of two numbers: ',self.add)
#creating object for Class1
obj = Test()
#invoking calc method()
obj.calc()
#passing class1 object to class2
Test2.display(obj)

Just create the variables in a class. And then inherit from that class to access its variables. But before accessing them, the parent class has to be called to initiate the variables.
class a:
def func1(self):
a.var1 = "Stack "
class b:
def func2(self):
b.var2 = "Overflow"
class c(a,b):
def func3(self):
c.var3 = a.var1 + b.var2
print(c.var3)
a().func1()
b().func2()
c().func3()

class ClassA(object):
def __init__(self):
self.var1 = 1
self.var2 = 2
def method(self):
self.var1 = self.var1 + self.var2
return self.var1
class ClassB(ClassA):
def __init__(self):
ClassA.__init__(self)
object1 = ClassA()
sum = object1.method()
object2 = ClassB()
print sum

Related

Dynamically created instances in python

I have definition of parent class "Parent". I have also defined child classes "child1", "child2". In child's some of the functions are overided some not. But the problem is that number of instances will be defined in .ini file. Question is how to dynamically create this instances. I have tried with "type" but it is not working. Below code with comments
`
class Parent:
def __init__(self, var_1):
self.var_1 = var_1
def method1(self):
print("method1")
def method2(self):
print('method2')
class child1(Parent):
def __init__(self, var_1, var2):
self.var2 = var2
super().init(var_1)
def method2(self):
print('method2_own_implementation')
class child2(Parent):
def __init__(self, var_1, var2):
super().__init__(var_1)
self.var2 = var2
def method1(self):
print("method1_own_implementation")
#4 below lines it is how it normally works
A = child1(2, 'XXX')
A.method2()
B = child2(3, 'sfsaf')
B.method1()
#list_nr define that 2 object of both types should be created, how to do it programmatically?
list_nr = ['child1', 'child1', 'child2', 'child2']
i tried with type, but not working as expected
list_classes = {'child1':child1, 'child2':child2}
created_instances = []
for index, type_obj in enumerate(list_nr):
A = type(('type_obj' + str(index)), (list_classes[type_obj],), {'var_1': 3, 'var2': 'xxx'})
created_instances.append(A)
print(created_instances[0].method1())
after executing this receiving error:
print(created_instances[0].method1()) TypeError: method1() missing 1 required positional argument: 'self'
Not sure if I fully understood your question, but I'm guessing you just want created_instances to contain instance of the classes listed in list_nr with the variable var_1 initialized to 3 and var2 initialized to XXX? If so you are overcomplicating it a bit here is a modified version of your code that does so.
class Parent:
def __init__(self, var_1):
self.var_1 = var_1
def method1(self):
print("method1")
def method2(self):
print('method2')
class child1(Parent):
def __init__(self, var_1, var2):
self.var2 = var2
super().__init__(var_1)
def method2(self):
print('method2_own_implementation')
class child2(Parent):
def __init__(self, var_1, var2):
super().__init__(var_1)
self.var2 = var2
def method1(self):
print("method1_own_implementation")
# 4 below lines it is how it normally works
A = child1(2, 'XXX')
A.method2()
B = child2(3, 'sfsaf')
B.method1()
# list_nr define that 2 object of both types should be created, how to do it programmatically?
list_nr = ['child1', 'child1', 'child2', 'child2']
list_classes = {'child1': child1, 'child2': child2}
created_instances = []
for index, type_obj in enumerate(list_nr):
A = list_classes[type_obj](var_1= 3, var2= 'xxx')
created_instances.append(A)
print(created_instances[0].method1())
The main change I've done is change this line
A = type(('type_obj' + str(index)), (list_classes[type_obj],), {'var_1': 3, 'var2': 'xxx'})
to
A = list_classes[type_obj](var_1= 3, var2= 'xxx')
list_classes[type_obj] is the same thing as the class you want class1 or class2 so it's essentially the same as
A = child1(var_1= 3, var2= 'xxx') # or child2 depending on what type_obj is
Also for some unelicited advice. In the future you might want to reduce the question example to the minimal, reproducable example. For your case your problem had nothing to do with method overloading so you didn't need to include the parent in the example.

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'

Calling variable inside self parameter in class method

I wonder if we can call variable initiated in self in class method. For example:
class ABC():
def method1(self):
self.var1 = '123'
#classmethod
def callvar1(cls):
'''print var1'''
I want to achieve the same output like this:
class ABC():
var1 = '123'
def method1(self):
self.var1 = '123'
#classmethod
def callvar1(cls):
print(cls.var1)
How can I access self.var1 in callvar1?
Since callvar1 is a class method, it does not have access to self. This is because the method is not tied to a specific instance of the class, but rather to the class itself. Therefore, when you call the method, it does not know which instance you are referring to. As you did in the second block of the code, you must pass the object whose var1 you would like to print to the function.
Your other option would be to not make it a class method.
Class methods are bound to the class itself rather than a particular instance of it so if you're trying to access self.var1 (an instance variable) inside the class method you're not going to have much fun.
Your best option is to simply make the method not a class method (depending on your use case):
>>> class ABC():
... var1 = '123'
... def method1(self):
... self.var1 = '123'
... def callvar1(self):
... print(self.var1)
...
>>> b = ABC()
>>> b.callvar1()
123
Although another option is to pass an instance of the class to the class method:
>>> class ABC():
... var1 = '123'
... def method1(self):
... self.var1 = '123'
... #classmethod
... def callvar1(cls, inst):
... print(inst.var1)
...
>>> b = ABC()
>>> ABC.callvar1(b)
123
Use the self keyword to access members of the class.
class ABC():
var1 = '123'
def method1(self):
self.var1 = '123'
#classmethod
def callvar1(self):
print(self.var1)

Redefining a "subclass" sort of structure using inheritance

I am developing an object oriented application which is very similar to the following limited working example. I am initiating 2 super classes. Class A and class B. Class A defines variables var1 and var2, and contains methods Add, Multiply, Power. Class B defines variables var1 and var2 and contains methods Subtract, Divide and Add.
Class C instantiates an instance of both class A and class B. It then defines a method f1 which utilizes methods from A_obj and B_obj with different names. Notice that method f2 is using the method Add from A_obj and B_obj. The method has the same name but performs a different computation.
The last few lines of the code instantiate an object of class C and then prints out the results using both functions.
class A():
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
def Add(self):
result = self.var1 + self.var2
return result
def Multiply(self):
result = self.var1*self.var2
return result
def Power(self):
result = self.var1**self.var2
class B():
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
def Subtract(self):
result = self.var1-self.var2
return result
def Divide(self):
result = self.var1/self.var2
return result
def Add(self):
result = self.var1+self.var2+self.var1+self.var2
return result
class C():
def __init__(self, var1, var2, var3, var4):
self.A_obj = A(var1,var2)
self.B_obj = B(var3,var4)
def f1(self):
result = self.A_obj.Add()+self.B_obj.Subtract()
return result
def f2(self):
result = self.A_obj.Add()-self.B_obj.Add()
return result
C_obj = C(1, 2, 3,4)
print(C_obj.f1())
print(C_obj.f2())
My question is, can I achieve this sort of functionality using inheritance? Is inheritance even an appropriate concept to use here? I tried forcing it in a previous question but found out that as soon as you use inheritance variables in subclass C become "globally defined" and are recognized by superclasses A and B. I'd like to make sure everything in class A remains local to A and everything in class B remain local to B.

Calling similar named functions in subclasses from superclass

A follow up from this question, which was not very well formulated. The answer provided some additional insight so now I have constructed a limited working example that explains it better.
Basically we have two subclasses A and B and a class C which inherits from both. Classes A and B both have a function MyFunc but which does different things.
I would like for class C to be able to use both functions and have full control of which function is called since I wish to do different things with each function. The comment in the limited working example below shows what I am trying to do.
class A():
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
def MyFunc(self):
result = self.var1 + self.var2
return result
class B():
def __init__(self, var1):
self.var1 = var1
def MyFunc(self):
result = self.var1**2
return result
class C(A,B):
def __init__(self, var1, var2, var3):
A.__init__(self, var1, var2)
B.__init__(self, var3)
def MyFunc(self):
#in this function I want to call MyFunc from A and MyFunc from B. For example to add their results together
How can I call MyFunc in A and MyFunc in B from MyFunc in C?
You can use name mangling to make attributes from a class available in a child class even if that child defines an attribute with the same name.
class A():
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
def __MyFunc(self):
result = self.var1 + self.var2
return result
MyFunc = __MyFunc
class B():
def __init__(self, var1):
self.var1 = var1
def __MyFunc(self):
result = self.var1**2
return result
MyFunc = __MyFunc
class C(A,B):
def __init__(self, var1, var2, var3):
A.__init__(self, var1, var2)
B.__init__(self, var3)
def MyFunc(self):
return self._A__MyFunc() + self._B__MyFunc()
c = C(1, 2, 3)
print(c.MyFunc())
# 14
I tried to make the solution look as simple as possible using your example suggestion.
def MyFunc(self):
result = 0
result += A.MyFunc(self=self)
result += B.MyFunc(self=self)
return result

Categories