2011-07-05 14 views
1

我設計了一個Python庫的API,並已經運行到一個情況,我想我的想象有可能超越Python的相當大的能力。Python API - 創建可選括號的模式?

(我要道歉,誰可能會通過我的設計的紅寶石岬得罪任何Pythonistas)

基本上,有一個與它的一些方法,每個返回self一類,使他們可以鏈接在一起。所以:

>>> a = MyKlass() 
>>> b = a.method_one() 
>>> c = b.method_two() 

將是相同

>>> a = MyKlass() 
>>> c = a.method_one().method_two() 

我的問題是,是否有可能使括號可選。我已經瞭解了一些關於使用__getattr____call__來操縱可調用對象的知識,但尚未能完全實現這一點。現在,我有類的__getattr__對於屬性檢查,然後確定是否name是一個方法或屬性(或者更準確地說,無論是贖回與否)。

我的問題是,如果它是一個可調用的,我需要__getattr__做這樣的事情:

>>> class MyKlass(object): 
>>>  def __getattr__(self, name): 
>>>   # pseudocode, you get the idea... 
>>>   if name is callable: 
>>>    def callme(*args, **kwds): 
>>>     # do stuff 
>>>    return callme 
>>>   else: 
>>>    # just return the attribute 

所以Callable對象。這意味着,雖然,我不能讓括號可選的,因爲可調用對象將返回,但從來沒有叫:

>>> a = MyKlass() 
>>> c = a.method_one.method_two # AttributeError, since a bound function object does not have attribute "method_two" 

我認爲只有這樣,才能做到這一點是要能夠「在代碼中向前看「,並確定name後面是否包含括號。然後,如果name可調用但未調用,則可返回調用name而不帶參數而不返回可調用對象的結果。

我想,這可能是不可行的,但我想我會問大師呢。

+3

如果它不是一個屬性,那麼它不應該被隱式調用。不要那樣做,永遠。特別是在圖書館。 Python不是Ruby。 –

+0

是的...這是沒有用的,並可能會導致大量的混淆,那些誰會使用你的圖書館 – Ant

+0

我聽到你大聲清晰。我將@ FogleBird的答案標記爲公認的答案,但我很感謝你們所有人都將我放在了直線和狹窄的地方。 –

回答

4

我認爲你是爲想要做到這一點堅果。你有什麼理由?接受參數的方法呢? (請參閱下面的示例。)

如果您使用__getattribute__而不是__getattr__,它似乎適用於無參數的方法。

工作例如:

class Test(object): 
    def __getattribute__(self, name): 
     attr = super(Test, self).__getattribute__(name) 
     if callable(attr): 
      return attr() 
     return attr 
    def f(self): 
     print 'f' 
     return self 
    def g(self): 
     print 'g' 
     return self 
    def h(self, x): 
     print x 
     return self 

t = Test() 
t.f.g # Works fine 
t.f().g # Fails - the parens aren't optional, they must be left off now 
t.f.g.h(1) # Fails - unable to provide an argument 

要解決的爭論問題,您可以檢查功能,只能調用它,如果它不採取(不是自其他)任何參數。請參閱:http://docs.python.org/library/inspect.html

請你幫個忙,並停止走這條路。

+0

我要去的是,如果你不需要傳遞任何參數,括號是可選的,如果你確實需要傳遞參數,則需要括號。所以'a.method_one.method_two'實際上會調用'a.method_one()。method_two()',而'a.method_one(name ='blah')。method_two'實際上會調用'a.method_one(name ='blah' ).method_two()' –

3

如果沒有括號,你必須在函數的引用,與他們您有它調用的結果。這是Python語法的基本部分(這種一致性是件好事!)。

你總是可以使用Python的property函數(或關聯的裝飾器)來使一個方法在引擎蓋下作爲一個屬性的別名來實現你想要的。但是,這表明你正在編寫非常副作用的代碼,這是一個糟糕的想法。

像這樣的鏈接在jQuery中很流行,因爲jQuery的唯一目的是在DOM中引起副作用。通常,這在其他地方並不合理,因爲它會使您的應用程序非常難以調試和測試。