在Python中向_调用_方法添加验证
我有一个由在Python中向_调用_方法添加验证,python,python-3.x,inheritance,design-patterns,composition,Python,Python 3.x,Inheritance,Design Patterns,Composition,我有一个由Function类派生的大型类层次结构(例如SineFunction将是一个子类),所有这些类都实现了\uuuu调用方法以及其他方法(例如求导法或更专业的数值方法) 根据输入的类型,向每个\uuuu调用\uuuu方法添加公共逻辑的最干净方法是什么?正式地说,我想要 def __call__(self,x): if isinstance(x,Distribution): return FunctionDistribution(x,self) else:
Function
类派生的大型类层次结构(例如SineFunction
将是一个子类),所有这些类都实现了\uuuu调用方法以及其他方法(例如求导法或更专业的数值方法)
根据输入的类型,向每个\uuuu调用\uuuu
方法添加公共逻辑的最干净方法是什么?正式地说,我想要
def __call__(self,x):
if isinstance(x,Distribution):
return FunctionDistribution(x,self)
else:
# Go back to previous logic
对于函数的每个子类
。我可以在调用的每个实现中添加super()
,但那会很痛苦。有什么更容易做到的吗?像这样的怎么样
class BaseFunction(object):
def __call__(self, x):
if isinstance(x, BaseFunction):
return self._call(x)
else:
print("Fallback logic goes here")
def _call(self):
raise NotImplementedError
class ChildFunction(BaseFunction):
def _call(self, x):
print("Child function executed on x")
子类分别定义调用,回退逻辑驻留在父类中
例如:
>>> a = BaseFunction()
>>> b = ChildFunction()
>>> c = 3
>>> b(a)
Child function executed on x
>>> b(c)
Fallback logic goes here
编辑:
顺便说一句,我对您的特定用例不太了解,但我的理解是,isinstance
通常不是理想的选择,最好做一些类似的工作。在这种情况下,您可能需要替换if(isinstance(…
语句,带有try
/,除了块,在该块中,您仅使用接口,就好像x
实现了BaseFunction
接口一样。是的,它可以做到,但是它意味着为每个实现将调用重命名为\u调用
,这很烦人。@Literal我想您确实是这样做的。@Literal如果您已经有了一个使用\uuuuuu call\uuuuu
的实现,那么物理上重命名\uuuu call\uuuuuuu
,但实际上您所做的是实现一个额外的方法\uuuu call\uuuuuuuuuuuuu
,如果不清楚的话,原始的\uuuuuuuuuuuuuuuuuu call
是从基函数继承的。而且,它看起来是一个非常简单的搜索和调用-替换。现在做一次可能比设计一个奇怪的元类在运行时做一些等效的事情要好。每个版本中的FunctionDistribution
都是一样的吗?或者在不同的\uuuuu call\uuuuu
方法中它会有所不同吗?总是有一个参数吗?不确定它是否适用于您的情况,但您可能需要查看在,您可以定义一个带有泛型实现的全局函数,以及特定类型的专门化。它可能与当前基于“functor”的设计很好地匹配,也可能不匹配,但我认为这是工作检查。