一尘不染

为什么要在Python中为内置函数分配值?

python

今天,当我发现一段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

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

或者更好的是,如何确保内置函数str的确是真实的str而不是不说,int因此str(123)不会被int(123)偶然评估?


阅读 247

收藏
2021-01-20

共1个答案

一尘不染

Python希望您对您的代码负责,这就是为什么。Python没有私有属性,没有受保护的类,并且几乎没有关于可以使用的名称的限制。

是的,这意味着您可能会意外重命名内置文件。为代码创建单元测试,使用lint,通常,您将很快学会发现意外使用所需的内置组件。这与意外地在代码中重用其他名称没有什么不同。

请注意,您只是 掩盖
了内置名称。找不到全局下一个名称的查找将在内置名称空间中进行,因此,如果您设置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

另一种选择是使每个内置名称成为保留关键字,从而使您可以使用的名称列表大大减少,并且在重新定义这些对象时没有灵活性。例如,Python
2.7有144个这样的名称。

在这种情况下,请参阅Guido van Rossum撰写的博客文章,内容为为什么NoneTrue并且False现在是Python
3中的关键字

因为您永远无法在任何Python程序中的任何地方将它们用作变量名或函数名,所以使用Python的每个人都必须了解该语言中的所有保留字,即使它们不需要它们。因此,我们尝试使保留字的列表保持较小,并且核心开发人员在向该语言添加新的保留字之前会费力工作。

2021-01-20