[英]Redefining python built-in function
我正在研究一個python程序,作者編寫了一個看起來像這樣的函數
def blah():
str = "asdf asdf asdf"
doStuff(str)
這似乎有效,即使str是內置函數,也不應該用作變量。
這里到底發生了什么? 我的猜測是str將不再可用作函數,但僅限於他編寫的blah()函數的范圍。 那是對的嗎? 這不會在全球范圍內重新定義str,對吧?
在內部,函數的局部變量表將包含str
的條目,該條目將是該函數的本地條目。 您仍然可以通過做訪問函數內的內置類builtins.str
在PY3和__builtin__.str
中的Py2。 函數外部的任何代碼都不會看到任何函數的局部變量,因此內置類在其他地方可以安全使用。
這里還有另一個警告/角落案例,在這個問題中有描述。 本地表條目是在編譯時創建的,而不是在運行時創建的,因此即使在為其分配"asdf asdf asdf"
之前,也無法在函數中使用str
的全局定義:
def blah():
x = str(12)
str = "asdf asdf asdf"
doStuff(str)
將失敗並出現UnboundLocalError
。
這似乎有效,即使str是內置函數,也不應該用作變量。
是的,這是事實。 Python並不能阻止你在腳下射擊自己。 作為開發人員,您可以確保不要覆蓋內置名稱。
這里到底發生了什么? 我的猜測是str將不再可用作函數,但僅限於他編寫的
blah()
函數的范圍。 那是對的嗎? 這不會在全球范圍內重新定義str
,對吧?
你在這里也部分正確。 如果str
的值被覆蓋為local,則僅影響當前作用域。 str
的全球價值保持不變。 但是,如果str
在全局范圍內被覆蓋,則它會影響所有子范圍。 這背后的原因是Python解釋器如何在運行時編譯值。 使用一個簡單的示例可以觀察到此行為:
>>> def foo():
... str = 0
... return str
...
>>> foo()
0
>>> str(0)
'0'
>>>
第一個例子有效,因為str
只在foo()
的范圍內被覆蓋。 然而,第二個示例失敗,因為str
被全局覆蓋:
>>> str = 0
>>> def foo():
... return str(0)
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in foo
TypeError: 'int' object is not callable
>>>
您總是可以導入builtins
函數(Python 2中的__builtins__
),並將str
的值重置為其原始含義:
>>> str = 0
>>> str
0
>>> import __builtins__
>>> str = __builtins__.str
>>> str
<type 'str'>
>>> str(0)
'0'
>>>
另外,正如@Brad Solomon所說,你可以簡單地使用del str
來恢復內置的str
值:
>>> str = 0
>>> str
0
>>> del str
>>> str
<class 'str'>
>>>
在你的情況下, str
只是一個變量,並沒有什么能阻止你在該函數之外通常使用str()
:
>>> str = 'Hello world!'
>>> print str
Hello world!
str(str)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
編輯:
這是一個簡單的演示:
def salut():
str = 'Hello world!'
return str
if __name__ == '__main__':
s = salut()
print str(s) #nothing prevents you from using 'str' outside 'salut()'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.