简体   繁体   English

重新定义python内置函数

[英]Redefining python built-in function

I'm working on a python program and the author has written a function that looks like this 我正在研究一个python程序,作者编写了一个看起来像这样的函数

def blah():
    str = "asdf asdf asdf"
    doStuff(str)

This seems to work, even though str is a built in function and shouldn't be used as a variable. 这似乎有效,即使str是内置函数,也不应该用作变量。

What is actually happening here? 这里到底发生了什么? My guess is str will no longer be usable as a function, but only in the scope of the blah() function he's written. 我的猜测是str将不再可用作函数,但仅限于他编写的blah()函数的范围。 Is that correct? 那是对的吗? This won't redefine str globally, right? 这不会在全球范围内重新定义str,对吧?

Internally, the function's local variable table will contain an entry for str , which will be local to that function. 在内部,函数的局部变量表将包含str的条目,该条目将是该函数的本地条目。 You can still access the builtin class within the function by doing builtins.str in Py3 and __builtin__.str in Py2. 您仍然可以通过做访问函数内的内置类builtins.str在PY3和__builtin__.str中的Py2。 Any code outside the function will not see any of the function's local variables, so the builtin class will be safe to use elsewhere. 函数外部的任何代码都不会看到任何函数的局部变量,因此内置类在其他地方可以安全使用。

There is another caveat/corner case here, which is described in this question . 这里还有另一个警告/角落案例,在这个问题中有描述。 The local table entry is created at compile-time, not at runtime, so you could not use the global definition of str in the function even before you assign "asdf asdf asdf" to it: 本地表条目是在编译时创建的,而不是在运行时创建的,因此即使在为其分配"asdf asdf asdf"之前,也无法在函数中使用str的全局定义:

def blah():
    x = str(12)
    str = "asdf asdf asdf"
    doStuff(str)

will fail with an UnboundLocalError . 将失败并出现UnboundLocalError

This seems to work, even though str is a built in function and shouldn't be used as a variable. 这似乎有效,即使str是内置函数,也不应该用作变量。

Yes, that is true. 是的,这是事实。 Python doesn't stop you from shooting yourself in the foot. Python并不能阻止你在脚下射击自己。 It's up to you as the developer to make sure your not overwriting builtin names. 作为开发人员,您可以确保不要覆盖内置名称。

What is actually happening here? 这里到底发生了什么? My guess is str will no longer be usable as a function, but only in the scope of the blah() function he's written. 我的猜测是str将不再可用作函数,但仅限于他编写的blah()函数的范围。 Is that correct? 那是对的吗? This won't redefine str globally, right? 这不会在全球范围内重新定义str ,对吧?

Your are partially correct here as well. 你在这里也部分正确。 If the value of str is overwritten local, then only the current scope is affected. 如果str的值被覆盖为local,则仅影响当前作用域。 The global value of str remains unchanged. str的全球价值保持不变。 However, if str is over written in the global scope, then it affects all sub-scopes. 但是,如果str全局范围内被覆盖,则它会影响所有子范围。 The reason behind this is how the Python interpreter compiles values at run-time. 这背后的原因是Python解释器如何在运行时编译值。 This behavior can be observed using a simple example: 使用一个简单的示例可以观察到此行为:

>>> def foo():
...     str = 0
...     return str
... 
>>> foo()
0
>>> str(0)
'0'
>>>

The first example works because str is only overwritten in the scope of foo() . 第一个例子有效,因为str只在foo()的范围内被覆盖。 This second example fails however because str is overwritten globally: 然而,第二个示例失败,因为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
>>> 

You can always import builtins ( __builtins__ in Python 2) though, and reset the value of str to its original meaning: 您总是可以导入builtins函数(Python 2中的__builtins__ ),并将str的值重置为其原始含义:

>>> str = 0
>>> str
0
>>> import __builtins__
>>> str = __builtins__.str
>>> str
<type 'str'>
>>> str(0)
'0'
>>> 

Also, as @Brad Solomon stated, you can simply use del str to recover the builtin str value: 另外,正如@Brad Solomon所说,你可以简单地使用del str来恢复内置的str值:

>>> str = 0
>>> str
0
>>> del str
>>> str
<class 'str'>
>>> 

In your case, str is just a variable and nothing prevents you from the usual use of str() outside that function: 在你的情况下, 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

EDIT: 编辑:

Here is a simple demo: 这是一个简单的演示:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM