Python produce function names from string - python

I would like to use functions based on strings passed in argument as below. The code gives the following error: AttributeError: 'Obj' object has no attribute 'funA'
The functions funA and funB are defined within fun because they are only used within fun and nowhere else
class Obj(object):
def __init__(self):
self.A = 2
self.B = 3
def fun(self, ar):
def funA(self):
print self.A
def funB(self):
x = self.B + 4
print self.B
for letter in ar:
name = 'fun' + letter
getattr(self, name)()
obj_instance = Obj()
obj_instance.fun(['A', 'B'])

As an alternative you can try the following code. It gives you the opportunity to check whether a function exists or not.
class Obj(object):
def __init__(self):
self.A = 2
self.B = 3
def fun(self, ar):
def funA():
print self.A
def funB():
x = self.B + 4
print self.B
print x
for letter in ar:
name = 'fun' + letter
if name in locals():
locals()[name]()
obj_instance = Obj()
obj_instance.fun(['A', 'B'])

I wouldn't recommend it, but if you really need it, then you can do it this way:
class Obj(object):
def __init__(self):
self.A = 2
self.B = 3
def fun(self, ar):
def funA(self):
print self.A
def funB(self):
x = self.B + 4
print self.B
for letter in ar:
name = 'fun' + letter + '()'
exec(name)
obj_instance=Obj()
obj_instance.fun(['A', 'B'])
exec() executes any string that you put in parentheses as if it was python code.

Related

Python3 How to call to method from one class in other class

I have two classes A and B, I want to run a method from class A in class B. I wrote the code but it's not working, I am getting the following error:
AttributeError: 'B' object has no attribute 'testPrint'
My classes:
class A:
def __init__(self):
self.v = 'A'
def test_1(self):
i = 1
print('Function test_1 in class A: ')
x = self.testPrint(i) # i think error is here
return x
def testPrint(self, i):
return 'testPrint: '+i
class B:
def __init__(self):
self.v = 'B'
def b1(self):
print('wywolanie funkcji z klasy b')
f = A.test_1(self)
return f
Run the program
b = B()
b.b1()
You need to instanciate class A:
class A:
def __init__(self):
self.v = 'A'
def test_1(self):
i = 1
print('Function test_1 in class A: ')
x = self.testPrint(i) # i think error is here
return x
def testPrint(self, i):
return 'testPrint: %s' % i
class B:
def __init__(self):
self.v = 'B'
def b1(self):
print('wywolanie funkcji z klasy b')
f = A().test_1()
return f
b = B()
res = b.b1()
print (res)
Returns (Python3):
wywolanie funkcji z klasy b
Function test_1 in class A:
testPrint:1

NameError: name 'addition' is not defined

I am getting NameError: name 'addition' is not defined while running following code
class Arithmetic:
def __init__(self, a, b):
self.a = a
self.b = b
def addition(self):
c = a + b
print"%d" %c
def subtraction(self):
c=a-b
print "%d" % c
add = addition(5, 4)
add.addition()
If you want to use your 'addition' method, you first need to instantiate an Arithmetic() object and use dot notation to call their functions. Make sure you properly indent your code because not only is it breaking a lot of PEP 8 rules but it just looks plain messy. In your first definition, don't forget you have to type __init__ not init. Here's the code which should be applied:
class Arithmetic(object):
def __init__(self, a, b):
self.a = a
self.b = b
def addition(self):
c = self.a + self.b
print c
def subtraction(self):
c = self.a - self.b
print c
a = Arithmetic(5, 4)
a.addition()
a.subtraction()
You first have to create object of class and then you can access class function.
Try this:
a = Arithmatic()
a.addition(5,4)
Check out this piece of code:
class Arithmetic():
def init(self, a, b):
self.a = a
self.b = b
def addition(self):
c = self.a + self.b
print"addition %d" %c
def subtraction(self):
c = self.a - self.b
print"substraction %d" %c
obj = Arithmetic()
obj.init(5, 4)
obj.addition()
obj.subtraction()

Python3.4: unable to access the variables in the method which is definded in the same class

Have written a simple code like this:
class Operations:
#global a,b
a=1
b=2
def __init__(self):
print(self,"object has been created")
def add(self):
#a = 2
#b = 3
return a+b
obj1=Operations()
sum=obj1.add()
print(sum).
when i run this code, am getting this error NameError: name 'a' is not defined.
can you please explain why variables a and b are not accessible in the method 'add' which is defined in the same class?
Note:when am declaring variables as a global, am able to access the variables inside the 'add' method.
You need to use the self keyword.
What does self do?
a = 1
class Operations:
a = 2
def fun1(self):
return a
def fun2(self):
return self.a
obj = Operations()
print(obj.fun1())
print(obj.fun2())
Output:
1
2
Solution for you case:
class Operations:
a=1
b=2
def __init__(self):
print(self,"object has been created")
def add(self):
return self.a + self.b
obj1=Operations()
print(obj1.add())
Output:
<__main__.Operations object at 0x100663588> object has been created
3
Use the class reference
Value= self.a + self.b
Is this the answer that you need? if you're writing a class, use self.value instead global value:
class Operations:
def __init__(self):
self.a = 1
self.b = 2
print(self, "object has been created")
def add(self):
return self.a + self.b
obj1 = Operations()
print(obj1.add())

How to pass a function as a parameter to a class in python

I want to pass a function to a class when I initialize it. Here's a toy example I came up with and it works:
def addition(self):
return self.a + self.b
def multiplication(self):
return self.a * self.b
class Test:
def __init__(self, a, b, fcn):
self.a = a
self.b = b
self.fcn = fcn
t = Test(3, 3, addition)
print t.fcn(t)
t = Test(3, 3, multiplication)
print t.fcn(t)
Is it possible to simply call t.fcn() as you would any other class method?
did you try it?
the answer is yes
def do_op(x,y,fn):
return fn(x,y)
def add(a,b):
return a+b
print do_op(5,4,add)
same with a class
class whatever:
def __init__(self,fn):
self.fn = fn
def do_it(self,*args,**kwargs):
return self.fn(*args,**kwargs)
#if you wanted the fn to have self as the first argument
#return self.fn(self,*args,**kwargs) #just pass self as first argument
x = whatever(add)
print x.do_it(5,8)
further along what you are asking for (if im reading it right)
def add(self):
return self.a + self.b
class whatever:
def __init__(self,fn,a,b):
self.__dict__[fn.__name__] = fn
self.a,self.b = a,b
def do_it(self):
return self.fn(self)
x = whatever(add,6,7)
x.do_it()
or perhaps you want something like
from functools import partial
def add(self):
return self.a + self.b
class whatever:
def __init__(self,fn,a,b):
self.__dict__[fn.__name__] = partial(fn,self)
self.a,self.b = a,b
x = whatever(add,5,6)
x.add()
this kind of introspection is somewhat risky in deployed code ...

How to implement this mechanism:

i want to implement a dynamic relation mechanism with python something like:
a:=10
b:=30
c:=a+b
print c
a+=20
print c
output:
40
60
c is always result of a+b.
so if a or b change, then c automatically updates value. i write a code in C# and do this by set and get mechanism. now want to translate it to python code for using in another program (FontLab Studio 5). I'm not so familiar with Python. does he have a get,set feature like C#? if not ho to implement one?
This is probably overkill, but it illustrates how you should create getters/setters in Python and achieve the functionality you want:
class Calc(object):
def __init__(self, a = 0, b = 0):
self._a = a
self._b = b
#property
def a(self):
return self._a
#a.setter
def a(self, value):
self._a = value
#property
def b(self):
return self._b
#b.setter
def b(self, value):
self._b = value
#property
def c(self):
return self._a + self._b
def __str__(self):
return str(self.c)
calc = Calc()
calc.a = 1
calc.b = 2
print calc.c
calc.a += 10
print calc.c
If you don't want to make a and b a property, the code can be simplified:
class Calc(object):
def __init__(self, a = 0, b = 0):
self.a = a
self.b = b
#property
def c(self):
return self.a + self.b
def __str__(self):
return str(self.c)
In your situation, c actually is a function which must be called.
You could use something like this:
a = 10
b = 30
c = lambda: a + b
print c()
a += 20
print c()
If you dislike that the method call is made explicit for c, you could use a general Calc object, which hides this implementation:
class Calc(object):
def __init__(self):
object.__setattr__(self, '_params', dict())
def __getattr__(self, name):
param = self._params[name]
if callable(param):
return param()
else:
return param
def __setattr__(self, name, value):
self._params[name] = value
def __delattr__(self, name):
del self._params[name]
And then you could do:
c = Calc()
c.a = 10
c.b = 30
c.c = lambda: c.a + c.b
print c.c
c.a += 20
print c.c
New-style Python classes support properties.
something like this:
class C:
def __init__(self):
self.x = 0
self.y = 0
def get(self):
return self.x + self.y
def __str__(self):
return self.__unicode__()
def __unicode__(self):
return str(self.get())
c = C()
c.x = 1
print c
c.y =2
print c
With new style classes and annotations you can probably make it better.

Categories

Resources