为什么可以在Python中为内置函数赋值?

Vin*_*yak 5 python python-2.7

我今天发现了这个意外的时候,我注意到一个Python代码曾使用内置函数 all作为变量标识符来存储列表理解的结果,并没有抛出一个错误,所以我尝试以下:

type('abc')
Out[1]: str

type('abc') == str
Out[2]: True

str = int

type('abc') == str
Out[4]: False

type('abc')
Out[5]: str

type = [1,2,3]

type('abc')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-a74a7df76db1> in <module>()
----> 1 type('abc')

TypeError: 'list' object is not callable 
Run Code Online (Sandbox Code Playgroud)

希望,当我问为什么在Python中允许这种行为时,这是一个有效的问题.

或者更好的是,我如何确保内置函数str是真的str而不是说,int所以str(123)不会被int(123)意外评估?

Mar*_*ers 6

Python希望您对代码负责,这就是原因.Python没有私有属性,没有受保护的类,几乎没有限制你可以使用的名称.

是的,这意味着您可能会意外地重命名内置内容.为您的代码创建单元测试,使用linter,通常,您将很快学会发现意外使用您需要的内置代码.与您在代码中意外重复使用任何其他名称没有什么不同.

请注意,您只是屏蔽了内置名称; 名称查找无法在内置命名空间中找到全局下一个内容,因此如果设置str为其他内容,则会在内置命令之前找到.只需删除全局:

>>> str = 'foobar'
>>> isinstance('foobar', str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
>>> del str
>>> isinstance('foobar', str)
True
Run Code Online (Sandbox Code Playgroud)

另一种方法是使每个内置名称都成为一个保留关键字,这样你就可以获得一个允许的名称列表,并且没有灵活性来重新定义这些对象.例如,Python 2.7有144个这样的名字.

在此背景下,看到这个博客帖子由Guido van Rossum的为什么None,TrueFalse现在关键字在Python 3:

因为你不能在任何Python程序中的任何地方使用它们作为变量或函数名称,所以使用Python的每个人都必须知道语言中的所有保留字,即使它们不需要它们.出于这个原因,我们试图保留较小的保留字列表,并且在向该语言添加新的保留字之前,核心开发人员会出现问题.