How can i do inheritance with three levels (father, child, grandchild) - python

I have the under
from abc import ABCMeta, abstractmethod
class Operation(object):
__metaclass__ = ABCMeta
def __init__(self, a, use_sftp):
print "OPERATION"
self.a = a
self.use_sftp = use_sftp
self.y = 5
#abstractmethod
def execute(self):
pass
class OperationExecutor(object):
def __init__(self, a, use_sftp):
print "EXECUTOR"
self.a = a
self.use_sftp = use_sftp
def batatas(self, operation):
op = operation(self.a, self.use_sftp)
return op.execute()
class FTP(Operation):
__metaclass__ = ABCMeta
def __init__(self, a, use_sftp):
print "FTP"
self.op = super(FTP, self).__init__(a, use_sftp)
self.b = 2
self.c = 3
self.x = 10
def execute(self):
if self.use_sftp:
return SFTP(self.a, self.use_sftp).execute()
else:
return LFTP(self.a, self.use_sftp).execute()
class SFTP(FTP):
def execute(self):
return self.a + self.b + self.c + self.x + self.y
class LFTP(FTP):
def execute(self):
return self.a * self.b * self.c * self.x * self.y
def main():
executor = OperationExecutor(1, True)
print executor.batatas(FTP)
if __name__ == '__main__':
main()
i want to run in the following order:
EXECUTOR,
FTP,
OPERATION
or similar, but i have the following:
EXECUTOR,
FTP,
OPERATION,
FTP,
OPERATION
This is because "init" is called twice. I don't want the "init" to be run more than once
Operation (father) ---> FTP (child) ---> SFTP/LFTP (grandchild)

Related

Access to class that intantiated another class

Considering I have the following classes:
class A:
def __init__(self, origin, value):
self.origin = origin
self.origin.b1 = value
class B:
def __init__(self):
self.b1 = 0
self.b2 = A(self, 1)
print(self.b1)
b = B()
I wish to know if there is any way of avoiding passing the self when instancing class A, thus getting the origin (class B) of the instance from within the class A (replacing of course the "???"):
class A:
def __init__(self, value):
self.origin = ???
self.origin.b1 = value
class B:
def __init__(self):
self.b1 = 0
self.b2 = A(1)
print(self.b1)
b = B()

Decorator and Inheritance with parameters

There is a decorator with inheritance. It works well:
class bar(object):
def __init__(self,val):
self.val = val
#staticmethod
def decor(func):
def increment(obj, x):
return func(obj, x) + obj.val
return increment
class foo(bar):
def __init__(self):
bar.__init__(self)
#bar.decor
def add(self, x):
return x
But I want to add a parameter in the class foo:
class foo(bar):
def __init__(self,B):
bar.__init__(self)
self.B = B
And I want to input B into the decorator as an parameters, I've tried a scratch:
class bar(object):
def __init__(self,val):
self.val = val
#staticmethod
def decor(B):
def wrap(func):
def increment(obj, x):
return func(obj, x) + obj.val + B
return increment
return wrap
class foo(bar):
def __init__(self,B):
bar.__init__(self)
self.B = B
#bar.decor(B)
def add(self, x):
return x
But it didn't work. What am I doing wrong?
class bar(object):
def __init__(self, val):
self.val = val
#staticmethod
def decor(func):
def increment(obj, x):
return func(obj, x) + obj.val + obj.B
return increment
class foo(bar):
def __init__(self,val,B):
bar.__init__(self,val)
self.B = B
#bar.decor
def add(self, x):
return x
aa = foo(4, 1.5)
a = aa.add(1)
print(a)

Python: is it possible to link two variable belonging to two different classes?

I would like to connect two variables totwo different classes but I don't know if what I'm trying to do is possible or not.
for instance, if I have those two classes:
class one():
def __init__(self):
self.a = 0
def compute(self):
self.a = self.a + 1
class two():
def __init__(self):
self.a = 0
self.C_one = one()
self.link()
def link(self):
self.a = self.C_one.a
def compute(self):
self.C_one.compute()
print('C_one a=',self.C_one.a )
print('C_two a=',self.a )
C_two = two()
for i in range(5):
C_two.compute()
In the class two I would like connect the variable a with the variable a of class one, so I don't have to explicitly call self.a = self.C_one.a each time I execute C_two.compute
The code in example give me this:
C_one a= 1
C_two a= 0
C_one a= 2
C_two a= 0
C_one a= 3
C_two a= 0
C_one a= 4
C_two a= 0
C_one a= 5
C_two a= 0
Which is not the result I expect.
Somebody know if I can do that in python?
update
From the example below
class one():
def __init__(self):
self.a = 0
def compute(self):
self.a = self.a + 1
class two():
def __init__(self):
self.a = 0
class three():
def __init__(self):
self.C_one = one()
self.C_two = two()
self.b = 0
def compute(self):
self.C_one.compute()
#self.C_two.a = self.C_one.a
print('C_one a=',self.C_one.a )
print('C_two a=',self.C_two.a )
C_three = three()
for i in range(5):
C_three.compute()
is it possible to use the answer of deceze and replace the commented line #self.C_two.a = self.C_one.awith a property ? Like that classes one and two are linked in the class three.
answer from deceze
class one():
def __init__(self):
self.a = 0
def compute(self):
self.a = self.a + 1
class two():
def __init__(self,one):
self.C_one = one
#property
def a(self):
return self.C_one.a
class three():
def __init__(self):
self.C_one = one()
self.C_two = two(self.C_one)
self.b = 0
def compute(self):
self.C_one.compute()
print('C_one a=',self.C_one.a )
print('C_two a=',self.C_two.a )
C_three = three()
for i in range(5):
C_three.compute()
Define two.a as a property:
class two:
def __init__(self):
self.C_one = one()
#property
def a(self):
return self.C_one.a
...

Override and extend method defined in parent class in Python

I want to redefine the method Old.do(self) in New.do(self, x) so that it takes one argument as below:
#!/usr/bin/env python3
class Old(object):
def __init__(self):
self.a = 0
self.do()
def do(self):
print(self.a)
class New(Old):
def __init__(self):
Old.__init__(self)
b = 1
self.do(b)
def do(self, b):
print(self.a + b)
if __name__ == '__main__':
new = New()
I can do it with the name mangling:
#!/usr/bin/env python3
class Old(object):
def __init__(self):
self.a = 0
self.__do()
def do(self):
print(self.a)
__do = do
class New(Old):
def __init__(self):
Old.__init__(self)
b = 1
self.do(b)
def do(self, b):
print(self.a + b)
if __name__ == '__main__':
new = New()
or I can do it with an explicit reference to the base class:
#!/usr/bin/env python3
class Old(object):
def __init__(self):
self.a = 0
Old.do(self)
def do(self):
print(self.a)
class New(Old):
def __init__(self):
Old.__init__(self)
b = 1
self.do(b)
def do(self, b):
print(self.a + b)
if __name__ == '__main__':
new = New()
Is there any other way to get the same result? Can super() do this?
Thanks
You can do what you trying with super, like this:
class Old(object):
def __init__(self):
self.a = 1
Old.do(self, self.a)
def do(self, a):
print(a)
class New(Old):
def __init__(self):
super(New, self).__init__()
self.b = 2
self.do(self.b)
def do(self, b):
print(self.a + b)
new = New()
the first call will return 1, and the second call 3

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 ...

Categories

Resources