python:内置函数重新定义,具有不同的参数

标签 python built-in monkeypatching

<分区>

前言:问题是了解python内部结构,所以请不要用'upgrade python'或'import six'来回答

以“打印”为例

要替换内置的“print”,我可以编写我的 python 函数。

python 2.6:在运行时,我得到语法错误

解决方案

from __future__ import print_function

现在我可以重新定义打印了。 为什么 ? 我想是因为现在我的 print 声明与新的 print 函数相同。

python 2.4:在运行时,我得到语法错误

没有

from __future__ import print_function

那么,对于 print(或任何其他内置函数):是否有可能使用新函数使用不同的声明 - args 和 kwargs 来猴子补丁?


换句话说。

from __future__ import print_function 用函数替换关键字。一般来说,我想了解如何。请不要只关注 print,这是一个方便的示例。

最佳答案

from __future__ import print_function 所做的只是在解析器中切换一个标志,使其停止将 print 视为关键字;一旦完成,对 print 的引用就会无缝地变成对构成合法变量名的任何其他非关键字的引用(它们通过 LEGB 查找,并在 LEGB 的 B 中找到,即内置范围) .这种行为在 Python 解释器中是硬编码的;如果不构建自定义版本的 Python,或者参与其他一些超出任何合理问题范围的令人震惊的骇客行为,就无法对任何其他关键字实现类似的效果。

从 2.6 开始,__builtin__ 有一个 print 函数,所以任何使用 from __future__ import print_function 的模块(因此可以引用name print 而不是 keyword print) 将看到 __builtin__.print (如果它没有被本地、嵌套或全局范围内的某些东西遮蔽)。对于每个模块,它仍然存在,但是在没有__future__ 导入的模块中,对print 的引用被解析为关键字在编译时替换为实现特殊 print 语句 的原始字节码(与 delreturn 相同行为;出于同样的原因,您不能命名变量,它们是关键字),因此没有导入的模块永远没有机会查找 print function.

这不会推广到其他情况,因为 __future__ 没有其他情况,其中一个功能可以将关键字转换为非关键字。对于所有其他实际的内置函数,能够在每个模块的基础上覆盖它们就像在全局范围内分配名称一样简单(为该模块隐藏它),例如:

def abs(x):
    return x  # Who needs absolute value anyway?
# From here on out, references to abs in this module see your override, not the built-in

虽然可以在全局范围内重新分配内置函数,但这是一个糟糕的想法(因为使用它的每个其他模块都可能依赖于内置函数的原始行为)。也就是说,这并不难:

import __builtin__

def abs(x):
    return x  # Who needs absolute value anyway?

__builtin__.abs = abs
# *Every* module now sees your terrible monkeypatch, on your own head be it

关于python:内置函数重新定义,具有不同的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52374770/

相关文章:

ruby - 我如何猴子修补 ruby​​ 的 URI.parse 方法

python - 分组数据框的 Seaborn 群图

python - python中字符串到元组的转换

python - 如何重命名内置函数,例如 "if"-> "hehe"、 "elif"-> "haha"、 "else"-> "hihi"?

Python all() 和 bool() 空案例?

python - cmp 根据评估方法返回两个不同的结果

python - 在测试执行期间防止记录文件 IO

javascript - 从调用该变量的方法获取变量而不使用参数

python - 当相关列不存在时 SQLAlchemy 忽略过滤器

python - 帮我用 f-string 修复这个代码吗?