Pass String Parameter into Class/Function (Python) - python

If I have a class as such:
class Sample:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
I can create an object by:
temp = Sample(a=100,b=100,c=100)
But what if I have:
my_str = "a=100,b=100,c=100"
How can I temp = Sample(my_str) properly?

You can parse and eval the string like:
Code:
#classmethod
def from_str(cls, a_str):
return cls(**eval("dict({})".format(a_str)))
Test Code:
class Sample:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
#classmethod
def from_str(cls, a_str):
return cls(**eval("dict({})".format(a_str)))
x = Sample.from_str("a=100,b=100,c=100")
print(x.a)
Results:
100

use eval
temp = eval("Sample("+my_str+")")

Although it is definitely an option, using eval can be dangerous. Here is an option which is #StephenRauch's code just without using eval.
>>> class Sample:
... def __init__(self, a, b, c):
... self.a = a
... self.b = b
... self.c = c
...
... #classmethod
... def from_str(cls, a_str):
... result = {}
... for kv in a_str.split(','):
... k, v = kv.split('=')
... result[k] = int(v)
... return cls(**result)
...
>>> x = Sample.from_str('a=100,b=100,c=100')
>>> x.a
100
>>> type(x.a)
<class 'int'>

You can use the below code.
class Sample:
def __init__(self, a, b, c):
self.a = int(a)
self.b = int(b)
self.c = int(c)
mystr = "a=100,b=100,c=100"
temp = Sample(mystr.split(",")[0].split("=")[1],mystr.split(",")[1].split("=")[1],mystr.split(",")[2].split("=")[1])
print(temp.a)
print(temp.b)
print(temp.c)
See it in action here

This works for me:
my_str = "a=100,b=100,c=100"
temp = Sample(int(my_str.split(',')[0].split('=')[1]),
int(my_str.split(',')[1].split('=')[1]),
int(my_str.split(',')[2].split('=')[1]))
print(temp.a)
# prints 100
print(temp.b)
# prints 100
print(temp.c)
# prints 100

Related

Doing assignments from another function without repeating it

I have a class with two functions:
class MyClass():
def function1(self):
a = 123
b = 723
c = 813
return a + b + c
def function2(self):
a = 123
b = 723
c = 813
return a - b - c
My question is... Is it possible for function2 to have the similar a, b, and c variables from function1 without declaring those variables again?
Given your current code, the variables "a", "b" and "c" will be local to the functions. If you want to input them once and not again, you should give them when you build your object, so provide them to the constructor/builder as inputs.
class MyClass():
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def function1(self):
return self.a + self.b + self.c
def function2(self):
return self.a - self.b - self.c
obj = MyClass(5, 3, 2)
print('F1: ', obj.function1())
print('F2: ', obj.function2())
Output:
F1: 10
F2: 0

Deepcopy on two classes containing eachother gives recursion error. Python

When I have a object-structure like this:
from copy import deepcopy
class A:
def __init__(self, b):
self.b = b
def __deepcopy__(self, memodict):
return A(deepcopy(self.b, memodict))
class B:
def __init__(self, a):
self.a = a
def __deepcopy__(self, memodict):
return B(deepcopy(self.a, memodict))
test_a = A(None)
test_b = B(None)
test_a.b = test_b
test_b.a = test_a
copy_a = deepcopy(test_a)
And I try to make a deepcopy of a object I get a "maximum recursion depth exceeded" error.
Which I understand why this happens but I don't know what the best approach would be to solve this?
Help much appreciated
You should not override __deepcopy__, just let deepcopy function do its work.
By the way I had to remove annotation :B because its a foreward reference and gives name error.
from copy import deepcopy
class A:
def __init__(self, b):
self.b = b
class B:
def __init__(self, a):
self.a = a
a = A(None)
b = B(None)
a.b = b
b.a = a
aa = deepcopy(a)
print (aa is a) # -> False
print(aa.b is b) # -> False
print(aa.b.a is aa) # -> True
But if you for any reason want to override the __deepcopy__ you should do it like this:
from copy import deepcopy
class A:
def __init__(self, b):
self.b = b
def __deepcopy__(self, memodict):
a = A(None)
memodict[id(self)] = a
a.b = deepcopy(self.b, memodict)
return a
class B:
def __init__(self, a: A):
self.a = a
def __deepcopy__(self, memodict):
b = B(None)
memodict[id(self)] = b
b.a = deepcopy(self.a, memodict)
return b
a = A(None)
b = B(None)
a.b = b
b.a = a
aa = deepcopy(a)
print(aa is a) # -> False
print(aa.b is b) # -> False
print(aa.b.a is aa) # -> True
ref: https://stackoverflow.com/a/15774013/1951448

Pass an object as a list in subclass' constructor in python

How do I implement the Subclass B for the function getdata() to return the details in the constructor? I could achieve that if the constructor in B takes a single object, but having difficulty if the objects were two or more and passed as a list.
This example shows what I intended. Code lacks the full implementation.
class A(object):
def __init__(self, a):
self.a = a
def geta(self):
return str(self.a)
class B(A):
def __init__(self, b,c, [objA1, objA2]):
self.b = b
self.c = c
super().__init__()
# ...
def geta(self):
return str(self.a)
def getb(self):
return str(self.b)
def getdata(self):
return str(self.geta()) + str(self.getb()) + ...
obja1 = A('John')
obja2 = A('Doe')
obj = B('123', '456', [obja1, obja2])
# Test1 obj.getdata() == "John Doe 123 456"
You could do like this and pass as normal arguments and then convert into list
class B(A):
def __init__(self,b,objA1,objA2):
self.b = b
self.list = [objA1, objA2]
super().__init__()
obj = B("hello", "JOHN","DOE")
like this works aswell, basicaly u say that objs will be a list
class B(A):
def __init__(self,b, objs: list):
self.b = b
self.list = objs
super().__init__()
obj = B("hello", ["JOHN","DOE"])
So you don't need inheritance here. Composition will be enough.
This code produces output according to your requirements:
class A:
def __init__(self, a):
self.a = a
def __repr__(self):
return str(self.a)
class B:
def __init__(self, b, c, others):
self.b = b
self.c = c
self.others = others
def getdata(self):
items = self.others + [self.b, self.c]
return ' '.join([str(item) for item in items])
obja1 = A('John')
obja2 = A('Doe')
obj = B('123', '456', [obja1, obja2])
print(obj.getdata())
Output:
John Doe 123 456

How do I loop dict and use the value as functions of an object?

I have a dictionary of values and initialize an object.
The dictionary values contains all the modules of the object, so how can I achieve something like this?
test_action = {
'1': 'addition',
'2': 'subtraction'
}
class test:
def __init__(self, a,b,c):
self.a = a
self.b = b
self.c = c
def addition(self):
return self.a + self.b + self.c
def subtraction(self):
return self.a - self.b - self.c
def main():
xxx = test(10,5,1)
for key,action in test_action.items():
print(xxx.action())
You should refer to the functions as objects rather than strings, so that:
class test:
def __init__(self, a,b,c):
self.a = a
self.b = b
self.c = c
def addition(self):
return self.a + self.b + self.c
def subtraction(self):
return self.a - self.b - self.c
test_action = {
'1': test.addition,
'2': test.subtraction
}
xxx = test(10,5,1)
for key, action in test_action.items():
print(key, action(xxx))
would output:
1 16
2 4
def main():
xxx = test(10,5,1)
for key,action in test_action.items():
if hasattr(xxx, action):
print "perforning: {}".format(action)
print xxx.__getattribute__(action)()
#op
perforning: addition
16
perforning: subtraction
4

How to create a simple function within a class in Python?

I am starting to work with classes in Python, and am learning how to create functions within classes. Does anyone have any tips on this sample class & function that I am testing out?
class test:
def __init__(self):
self.a = None
self.b = None
self.c = None
def prod(self):
return self.a * self.b
trial = test
trial.a = 4
trial.b = 5
print trial.prod
Ideally the result would be to see the number 20.
You need to:
Create an instance of test.
Invoke the prod method of that instance.
Both of these can be accomplished by adding () after their names:
trial = test()
trial.a = 4
trial.b = 5
print trial.prod()
Below is a demonstration:
>>> class test:
... def __init__(self):
... self.a = None
... self.b = None
... self.c = None
... def prod(self):
... return self.a * self.b
...
>>> trial = test()
>>> trial.a = 4
>>> trial.b = 5
>>> print trial.prod()
20
>>>
Without the parenthesis, this line:
trial = test
is simply assigning the variable trial to class test itself, not an instance of it. Moreover, this line:
print trial.prod
is just printing the string representation of test.prod, not the value returned by invoking it.
Here is a reference on Python classes and OOP.
Ideally you could also pass in the values to a, b, c as parameters to your object's constructor:
class test:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def prod(self):
return self.a * self.b
Then, constructing and calling the function would look like this:
trial = test(4, 5, None)
print trial.prod()

Categories