爲什麼以下有效?在Python中,爲什麼裸函數對象有效的代碼?
#!/usr/bin/python
def spam():
pass
spam
我明白函數是對象,但我認爲上面的代碼永遠不會有用,而且總是出錯的結果。爲什麼它不會在引用垃圾郵件功能對象的行上導致錯誤?
爲什麼以下有效?在Python中,爲什麼裸函數對象有效的代碼?
#!/usr/bin/python
def spam():
pass
spam
我明白函數是對象,但我認爲上面的代碼永遠不會有用,而且總是出錯的結果。爲什麼它不會在引用垃圾郵件功能對象的行上導致錯誤?
每個表達式都是一個有效的語句。使用局部變量(不管它指的是什麼)是一個有效的表達式。由於後期的綁定和動態性,你不能在編譯時檢測它是否指向一個函數或其他東西(儘管在這種情況下你不需要知道,因爲只引用一個本地從不做任何事情)。運行時檢查將會非常昂貴而沒有收益。
這會導致禁止聲明<local variable>;
。具體禁止這種情況是不一致的,需要額外的工作,並沒有幫助很多恕我直言。我沒有看到無法完成的技術原因,所以可能歸結爲BDFL不希望爲此特殊情況。
首先,spam
和spam()
當然是根本不同的陳述。如果你看看a = spam
和a = spam()
之間的差異,這變得清楚。第一個存儲函數在變量a
中,第二個存儲當時發生的函數的一個調用的返回值。兩者都是有用但不同的操作。
只是提到spam
這樣的功能沒有做一些有用的事情,沒有。但是在python中只聲明值並不是被禁止的。在您的論證之後,單一聲明4
也應該是非法的,就像任何有價值的。這實際上會在任何地方使用pydoc字符串,因爲它們只是提到了一個無用的值(從執行的角度來看)。
所以我認爲它可能被禁止使用這樣的價值觀,但它不是,現在它甚至有用法。
你說過我想說得好多了。我刪除了我的和你的+1! – 2012-11-28 17:41:01
您可以爲docstrings特殊情況。我相信OP所掌握的是,讓Python捕獲「忘記調用函數」錯誤的附加價值是值得處理裸表達式的(非常輕微的)成本。 –
@RussellBorogove是的,你可以,我猜,它可以幫助你檢測代碼中的許多錯誤。儘管如此,它不知道爲什麼,對我來說不會感到非常焦慮。並且它不太適合交互式Python提示符,在那裏向你顯示每個「提到的」值(我經常在那裏輸入類似「垃圾郵件」的東西,找出它們來自哪裏,不知道, – kratenko
在一般情況下,引用裸表達式會產生副作用。代碼:
class Nugget(object):
@property
def spam(self):
print "does merely referencing a property invoke it?"
n = Nugget()
n.spam # no explicit invocation
實際上是否打印消息。在你的例子中給你一個錯誤會打破這種情況的普遍性。
它爲什麼會導致錯誤?這是一個絕對有效的Python語法。 –
設計時很有用。 – asheeshr
語言應該如何知道什麼是「有用的」,什麼不是? – YXD