我今天偶然发现了这一点,当时我注意到一段Python代码使用built-in function all
作为变量标识符来存储列表理解的结果而且它没有#39 ; t抛出错误,所以我尝试了以下内容:
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)
赢了&#39} t被意外评估为int(123)
?
答案 0 :(得分: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
另一种方法是让每个内置名称都成为一个保留关键字,这样你就可以获得一个允许的名称列表,并且没有灵活性来重新定义这些对象。例如,Python 2.7有144个这样的名称。
在此上下文中,请参阅此blog post by Guido van Rossum on why None
, True
and False
are now keywords in Python 3:
因为你不能在任何Python程序中的任何地方使用它们作为变量或函数名称,所以使用Python的每个人都必须知道语言中的所有保留字,即使它们不需要它们。出于这个原因,我们试图保留较小的保留字列表,并且在向该语言添加新的保留字之前,核心开发人员会出现很多问题。