How to pass value from class to class - Python - python

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

Related

Can we pass the class object inside its own method?

I have a class A object method which uses another class B object's method, which the argument is class A object.
class A():
def calculate(self):
B = B.calculator(A)
class B():
def calculator(self, A):
...do something with A.attributes
It is possible to just pass attributes into the object, but I would see this possibility as the last priority. I am definitely a bit oversimplify my case, but I am wondering if there is a way to pass the entire class
Edit:
Sorry for the confusion. At the end I am trying to call class A object and A.calculate(), which will call class B obj and calculator function.
class A():
def __init__(self, value):
self.value = value
def calculate(self):
Bobj = B()
Bobj.calculator(A)
class B():
def calculator(self, A):
...do something with A.value
def main():
Aobj = A(value)
Aobj.calculate()
Your scenario does not currently indicate that you want to use any information from B when calculating A. There are a few ways of getting the functionality that you want.
Scenario: B stores no information and performs calculation. B should be a function
def B(value):
```do something with value```
return
class A():
def __init__(self, value):
self.value = value
def calculate(self):
return B(self.value)
def main():
Aobj = A(value)
Aobj.calculate()
Scenario: B stores some other information, but internal B information is not needed for the calculation. B should have a static method
class B():
#staticmethod
def calculate(value):
```do something with value```
return
class A():
def __init__(self, value):
self.value = value
def calculate(self):
return B.calculate(self.value)
def main():
Aobj = A(value)
Aobj.calculate()

How to create class from which I can use "get"?

In Python, I am trying to create a class that has attributes which I can "get" (sorry if this wording is not exactly correct).
Basically I am trying to define some class p which has attributes var1 and var2. So then I can use p.get("var1") and p.get("var2") to get the values of these respective attributes. How can I define something like this?
You can define a class with get() method and check if the instance has the attribute with built-in getattr() method as following:
class MyClass:
def get(self, property, default=None):
return getattr(self, property, default)
var1 = 'var1'
var2 = 'var2'
myInstance = MyClass()
print(myInstance.get('var1'))
print(myInstance.get('var3', 'NonExisting Attribute'))
Here's a working repl.it project that I just created: https://repl.it/#HarunYlmaz/OvalLiveMethod
You can also check if the instance has the attribute with hasattr() method:
class MyClass:
def get(self, property, default=None):
if hasattr(self, property):
return getattr(self, property)
else:
return default
# Or you can raise an exception here
For instance object
class Test:
def __init__(self):
self.a = 1
self.b = 2
def get(self, var):
return eval('self.%s' % var)
t = Test()
a = t.get('a')
print(a) ## output: 1
For class object
class Test:
a = 1
b = 2
#classmethod
def get(cls, var):
return eval('cls.%s' % var)
a = Test.get('a')
print(a) # output: 1

How to execute code on a change in a instance variable?

I have an instance variable from a class and I want to execute some code when there is a change in my variable.
I'm aware of the property and Observer pattern event handling but I don't think it helps in my case.
Example:
class Thing:
def __init__(self):
self.thing = []
self.thing2 = ""
def code_that_executes(self):
self.thing2 = self.thing[0]
s = Thing()
s.thing.append("Something") #The event
You can implement setattr on your class. Here is an example:
class A:
def __init__(self):
self.A = 5
def __setattr__(self, name, value):
if name == "A":
print("A has changed to: {0}".format(value))
Now when you have an object `foo = Foo()` and call `foo.bar = 5` you get the result:
bar changed to 5
See https://docs.python.org/3/reference/datamodel.html#object.setattr
Note:This will print during the init call as well.

Accessing class methods inside another class at same scope

Trying to get a work around for getting access to a class method in another class while being inside a class. Code below will probably explain my goal.
class Access(object):
def __init__(self):
pass
def select(self, value):
Store.keep(value)
class Store(object):
def __init__(self):
self.store_value = 0
def keep(self, value):
self.store_value = value
x = Access()
y = Store()
x.select(10)
y.store_value
##Want the output of 10
I don't see any way to do what you want without Access having a reference to a Store object.
The closest thing you can do is
class Access(object):
def __init__(self):
pass
def select(self, value):
Store.keep(value)
class Store(object):
#classmethod
def keep(cls, value):
cls.store_value = value
x = Access()
y = Store()
x.select(10)
print y.store_value #will print 10
#but
z = Store()
print z.store_value #will print 10 too
Where store_value is shared by all instances of Store.
You could pass an instance to select also and use Store.keep(inst, value):
class Access(object):
def __init__(self):
pass
def select(self, inst, value):
Store.keep(inst, value)
class Store(object):
def __init__(self):
self.store_value = 0
def keep(self, value):
self.store_value = value
x = Access()
y = Store()
x.select(y, 10)
print(y.store_value)
10

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