如何根据某些条件动态地向类中添加函数。
对于ex,我有一个类作为follwos:
class A(object):
def __init__(self,type):
self.type = type
现在基于'type'值我希望将类B或C类的函数添加到A类。
对于前。
lass B(object):
def fun1(self):
print 'fun1'
def fun2(self):
print 'fun2'
class C(object):
def fun3(self):
print 'fun3'
def fun4(self):
print 'fun4'
如果类A的'type'属性值为'B',则将类B的函数(即fun1和fun2)动态添加到类A,否则如果'type'属性值为'C',则添加类C的函数到A类(即fun3和fun4)到A类,这样在我的代码中我可以访问这些函数,如A.fun1()或A.fun3。
我猜这个元编程可能会让我知道这一点,但我不知道如何做到这一点。请指导。
此外,我必须创建A类对象,并能够通过A类对象使用这些函数。
a = class A(type='B')
a.fun1() #should work
请帮忙,因为我无法弄清楚这一点。
这是我的代码的一部分。
class Group(object):
def __init__(self,type):
if type == 'source'
self.mgr = SManager(self) #grp_mgr
elif type == 'target'
self.mgr = TManager(self)
def __getattr__(self,name):
if hasattr(self.mgr,name):
return getattr(self.mgr,name)
return AttributeError
class SManager(object):
def __init__(self,groupobj):
self.some_list = []
self.groupobj = groupobj
def doProcess(self):
#this function accesses self.groupobj
pass
def get_valid_list(self):
#this function accesses self.groupobj
pass
但是有了这个我得到以下错误。
if hasattr(self.mgr,name):
File "c:\workspace\project\dev.py", line 27, in __ge
tattr__
if hasattr(self.mgr,name):
File "c:\workspace\project\dev.py", line 27, in __ge
tattr__
if hasattr(self.mgr,name):
File "c:\workspace\project\dev.py", line 27, in __ge
tattr__
if hasattr(self.mgr,name):
File "c:\workspace\project\dev.py", line 27, in __ge
tattr__
if hasattr(self.mgr,name):
File "c:\workspace\project\dev.py", line 27, in __ge
tattr__
if hasattr(self.mgr,name):
RuntimeError: maximum recursion depth exceeded while calling a Python object
我无法弄清楚我在哪里弄错了。在合并之前我尝试使用一个简单的代码片段,但是当我在实际代码中执行相同操作时,它会抛出错误。 请帮忙
答案 0 :(得分:3)
答案 1 :(得分:1)
Roman的回答可能是最认真的方法。但是,嘿,让我们忽略这一点,想想你可以做的一些疯狂的事情!
你可以使用一个功能,但这太容易了:
def A(type):
if type == 'B':
return B()
elif type == 'C':
return C
您可以覆盖__getattr__
,以便在所选类的实例上查找缺少的属性:
class A(object):
def __init__(self, type):
if type == 'B':
self.type = B()
if type == 'C':
self.type = C()
def __getattr__(self, name):
if hasattr(self.type, name):
return getattr(self.type, name)
return AttributeError
或者你可以覆盖__new__
,并返回一个疯狂的新类,或者你感兴趣的类的实例:
class A(object):
bases = {'B': B, 'C': C}
def __new__(cls, type):
class Cls(A.bases[type]):
pass
return Cls()
可能还有很多其他被误导的事情!
答案 2 :(得分:1)
正如我在问题评论中已经说过的那样:你可能根本不需要元类。
但是既然你没有提供更多信息,那么你可以用元类来解决这个问题:
class MetaX(type):
def __add__(cls, other):
name = '{}+{}'.format(cls.__name__, other.__name__)
return type(cls)(name, (cls, other), dict())
class X(object): # metaclass=MetaX in py3k
__metaclass__ = MetaX
def __add__(self, other):
cls = type(self) + type(other)
return cls
就是这样,你只需要继承X
。
示例:
class A(X):
def func_a(self):
print "I'm in func_a"
class B(X):
def func_b(self):
print "I'm in func_b"
class C(X):
def func_c(self):
print "I'm in func_c"
L = A + B
l = L()
l.func_a() # -> I'm in func_a
l.func_b() # -> I'm in func_b
P = A + C
p = P()
p.func_a() # -> I'm in func_a
p.func_c() # -> I'm in func_c
编辑:您真正需要的内容取决于您的实际代码的样子。
你在问题中描述的是一个动态继承,如果这是你真正需要的,那么IMO一个元类是正确的工具并覆盖__getattr__它只是一个黑客。
如果你不想构建一个完整的元类,你可以构建只使用某种类工厂:
def get_enhanced_A(typ) # you can't use type as a keyword here
dct = {'B': B, 'C': C}
return type('A+{}'.format(typ), (A,dct[typ]), dict())
我不知道这两个选项中的哪一个看起来更好。