簡體   English   中英

如何在Python類中實現子方法?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM