为什么可以为 Python 中的内置函数赋值? [英] Why can you assign values to built-in functions in Python?

查看:49
本文介绍了为什么可以为 Python 中的内置函数赋值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天偶然发现了这一点,当时我注意到一段 Python 代码使用了 内置function all 作为变量标识符来存储列表理解的结果并且它没有抛出错误,所以我尝试了以下操作:

type('abc')出[1]:strtype('abc') == str输出[2]:真str = 整数type('abc') == str出[4]:假类型('abc')出[5]:str类型 = [1,2,3]类型('abc')---------------------------------------------------------------------------TypeError Traceback(最近一次调用最后一次)<ipython-input-7-a74a7df76db1>在 <module>()---->1 类型('abc')类型错误:列表"对象不可调用

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

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

解决方案

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

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

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

<预><代码>>>>str = 'foobar'>>>isinstance('foobar', str)回溯(最近一次调用最后一次):文件<stdin>",第 1 行,位于 <module>类型错误:isinstance() arg 2 必须是类、类型或类和类型的元组>>>删除字符串>>>isinstance('foobar', str)真的

另一种方法是使每个内置名称都成为保留关键字,从而使允许的名称列表大大减少,并且无法灵活地重新定义这些对象.例如,Python 2.7 有 144 个这样的名称.

在这种情况下,请参阅此 Guido van Rossum 关于为什么 NoneTrueFalse 现在是 Python 3 中的关键字的博客文章:

<块引用>

因为你不能在任何地方、任何地方、在任何 Python 程序中使用这些作为变量或函数名称,所以每个使用 Python 的人都必须知道语言中的所有保留字,即使他们不需要它们.出于这个原因,我们尽量保持保留字的列表很小,核心开发人员在向语言添加新的保留字之前会折腾很多.

I found out about this by accident today when I noticed that a piece of Python code had used the built-in function all as a variable identifier to store the result of a list comprehension and it didn't throw an error, so I tried the following:

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 

Hopefully, it's a valid question when I ask why this behavior is allowed in Python.

Or better yet, how do I make sure that a built-in function like str is really str and not say, int so str(123) won't be evaluated as int(123) by accident?

解决方案

Python expects you to take responsibility for your code, is why. Python doesn't have private attributes, no protected classes, and almost no limits on what names you can use.

Yes, that means you can accidentally rename a built-in. Create unittests for your code, use a linter, and generally, you'll quickly learn to spot accidental use of a built-in you needed. It's no different from accidentally re-using any other name in your code.

Note that you are simply masking the built-in names; name lookups that fail to find a global next look at the built-in namespace, so if you set str to something else, that is found before the built-in. Simply delete the global:

>>> 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

The alternative would be to make every built-in name a reserved keyword, leaving you with a much diminished list of names that is allowed, and no flexibility in re-defining those objects. Python 2.7 has 144 such names, for example.

In this context, see this blog post by Guido van Rossum on why None, True and False are now keywords in Python 3:

Because you cannot use these as variable or function names anywhere, ever, in any Python program, everyone using Python has to know about all the reserved words in the language, even if they don't have any need for them. For this reason, we try to keep the list of reserved words small, and the core developers hem and haw a lot before adding a new reserved word to the language.

这篇关于为什么可以为 Python 中的内置函数赋值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆