我的课堂结构如下。
class foo(object):
def __call__(self,param1):
pass
class bar(object):
def __call__(self,param1,param2):
pass
我有很多此类的课程。我正在按如下方式使用此可调用类。
classes = [foo(), bar()]
for C in classes:
res = C(param1)
'''here i want to put condition if class takes 1 argumnet just pass 1
parameter otherwise pass two.'''
我想到了一种这样的模式。
class abc():
def __init__(self):
self.param1 = 'xyz'
self.param2 = 'pqr'
def something(self, classes): # classes = [foo(), bar()]
for C in classes:
if C.__class__.__name__ in ['bar']:
res = C(self.param1, self.param2)
else:
res = C(self.param2)
但在上述解决方案中必须维护带有两个参数的类列表,因为我将向文件中添加更多类,因此会变得混乱。
我不知道这是否正确(pythonic)。
params1
都是我要传递的相同参数。对于具有两个必需参数的类,我正在传递包含一些数据的附加参数(params2
)。
附言:对于此问题的任何帮助或新想法,都表示感谢。
UPD:更新了代码。 答案 0 :(得分:1)
基本上,您想在对象的__call__()
方法上使用多态性,但是可调用对象签名不相同存在问题。
一个简单的答案是:您只能对兼容类型使用多态,这意味着您的可调用对象必须具有兼容的签名。
希望有一种快速简便的方法来解决此问题:只需修改方法签名,以便它们接受varargs和kwargs:
class Foo(object):
def __call__(self,param1, *args, **kw):
pass
class Bar(object):
def __call__(self, param1, param2, *args, **kw):
pass
对于无法更改可调用对象签名的情况,仍然有一种解决方法:使用lambda作为代理:
def func1(y, z):
pass
def func2(x):
pass
callables = [func1, lambda y, z: func2(y)]
for c in callables:
c(42, 1138)
请注意,最后一个示例实际上称为the adapter pattern
不相关:此:
if C.__class__.__name__ in ['bar']:
是一种效率低下且令人费解的书写方式:
if C.__class__.__name__ == 'bar':
这本身就是一种效率低下,令人费解且易碎的书写方式:
if type(C) is bar:
这本身就是一种可能的设计气味(有合法的用例来检查对象的确切类型,但通常这确实是设计问题)。