[英]How to implement a submethod in a Python-class?
如果不能表達清楚自己的意思,我表示歉意。 我想做的是這樣的:
class someClass(object):
def aMethod(self, argument):
return some_data #for example a list or a more complex datastructure
def aMethod_max(self, argument):
var = self.aMethod(argument)
#do someting with var
return altered_var
或者我可以做:
def aMethod(self, argument):
self.someVar = some_data
return some_data #for example a list or a more complex datastructure
def aMethod_max(self, argument):
if not hasattr(self, someVar):
self.aMethod(argument)
#do someting with self.var
return altered_var
但是我認為這太復雜了,希望有一個更優雅的解決方案。 我希望現在很清楚,我想完成什么。
因此,我對以下段落中的內容進行了幻想。
class someClass(object):
someMethod(self):
#doSomething
return result
subMethod(self):
#doSomething with the result of someMethod
Foo = someClass()
Foo.someMethod.subMethod()
或者someMethod的參數類似
Foo.someMethod(argument).subMethod()
我將如何在python中做類似的事情?
編輯:還是這樣?
subMethod(self):
var = self.someMethod()
return doSomething(var)
讓我們將問題中已經給出的現有解決方案(例如,您稱其為“復雜”和“模糊”的解決方案)與建議的替代方案進行比較。
現有的解決方案意味着您將能夠編寫:
foo.subMethod() # foo.someMethod() is called internally
但是您建議的替代方法意味着您必須編寫:
foo.someMethod().subMethod()
這顯然更糟。
另一方面,如果subMethod
必須能夠修改任何方法的結果,而不僅僅是someMethod
,那么現有的解決方案將意味着您必須編寫:
foo.subMethod(foo.anyMethod())
唯一的缺點是您必須兩次鍵入foo
,而不是一次。
結論:總體而言,現有解決方案比您建議的替代方案更簡單,更輕松-因此,請堅持使用現有解決方案。
當someMethod的結果是someClass的實例時,可以進行方法鏈接 。
簡單的例子:
>>> class someClass:
... def someMethod(self):
... return self
... def subMethod(self):
... return self.__class__
...
>>> x=someClass()
>>> x
<__main__.someClass instance at 0x2aaaaab30d40>
>>> x.someMethod().subMethod()
<class __main__.someClass at 0x2aaaaab31050>
您可以使用裝飾器實現類似的功能:
def on_result(f):
def decorated(self,other,*args,**kwargs):
result = getattr(self,other)(*args,**kwargs)
return f(result)
return decorated
用法:
class someClass(object):
def someMethod(self,x,y):
#doSomething
result = [1,2,3,x,y] # example
return result
@on_result
def subMethod(self):
#doSomething with the result of someMethod
print self # example
Foo = someClass()
Foo.subMethod("someMethod",4,5)
輸出:
[1, 2, 3, 4, 5]
如您所見,第一個參數是要鏈接的方法的名稱,其余參數將傳遞給它,無論其簽名是什么。
編輯:再三考慮,這是沒有意義的,因為您可以隨時使用
Foo.submethod(Foo.someMethod(4,5))...
也許我不明白您要達到的目標。 subMethod是否僅必須鏈接到特定方法? 也許這是句法形式
a.b().c()
這對你很重要嗎? (在這種情況下,請參閱小二郎的回答)
不知道我是否理解正確,但是也許您的意思是:
Foo.subMethod(Foo.someMethod())
這會將someMethod()的結果傳遞給subMethod()。 您必須更改當前對subMethod()的定義才能接受someMethod()的結果。
從到目前為止的反饋中,我知道subMethod將僅鏈接到someMethod ,對嗎? 也許您可以通過結合裝飾器和閉包來實現:
def on_result(other):
def decorator(f):
def decorated(self,*a1,**k1):
def closure(*a2,**k2):
return f(self,getattr(self,other)(*a1,**k1),*a2,**k2)
return closure
return decorated
return decorator
class someClass(object):
def someMethod(self,a,b):
return [a,2*b]
@on_result('someMethod')
def subMethod(self,result,c,d):
result.extend([3*c,4*d])
return result
Foo = someClass()
print Foo.subMethod(1,2)(3,4) # prints [1,4,9,16]
裝飾器有點“丑陋”,但是一旦編寫,它的用法就非常優雅,恕我直言(此外,這兩種方法的簽名中都沒有矛盾之處)。
注意:我使用的是Python 2.5,這是我知道編寫帶有參數的裝飾器的唯一方法。 也許有更好的方法,但是我太懶了,現在無法查找...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.