今天,当我发现一段Python代码使用内置函数 all作为变量标识符来存储列表推导的结果并且没有引发错误时,我偶然发现了这一点,因此我尝试了以下操作:
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)偶然评估?
str
int
str(123)
int(123)
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撰写的博客文章,内容为为什么None,True并且False现在是Python 3中的关键字:
None
True
False
因为您永远无法在任何Python程序中的任何地方将它们用作变量名或函数名,所以使用Python的每个人都必须了解该语言中的所有保留字,即使它们不需要它们。因此,我们尝试使保留字的列表保持较小,并且核心开发人员在向该语言添加新的保留字之前会费力工作。