代码之家  ›  专栏  ›  技术社区  ›  Massimo

python:内置函数重新定义,使用不同的参数

  •  1
  • Massimo  · 技术社区  · 6 年前

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

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

    python2.6:在运行时,我得到

    解决方案

    from __future__ import print_function
    

    我想因为现在我的print声明和新的print函数是一样的。

    python2.4:在运行时,我得到 语法错误

    没有

    从未来导入打印功能
    

    所以,为了 print (或任何其他内置):是否可以使用不同的声明(args和kwargs)对新函数进行monkey修补?


    换句话说。

    from __future__ import print_function 用函数替换关键字。总的来说,我想知道怎么做。请不要只关注 打印 ,这是一个方便的例子。

    2 回复  |  直到 6 年前
        1
  •  3
  •   ShadowRanger    6 年前

    全部 from __future__ import print_function print 打印 无缝地成为对构成合法变量名的任何其他非关键字的引用(它们通过LEGB查找,并在LEGB的B中找到,即内置范围)。这种行为在Python解释器的深层是硬编码的;如果不构建Python的自定义版本,或者从事一些远远超出任何合理问题范围的其他骇人听闻的黑客行为,就无法对任何其他关键字实现类似的效果。

    __builtin__ 有一个 打印 从未来导入打印功能 (因此可以参考 相对于 关键字 打印 __builtin__.print (如果它没有被本地、嵌套或全局范围中的某个对象所覆盖)。它仍然是 对于 每一个 模块,但在没有 __future__ 导入,引用 打印 在编译时解析为关键字,并替换为实现特殊 打印 (同样的方法 del return 表现;因为同样的原因,你不能给这些东西中的任何一个命名变量(它们是关键字),所以没有导入的模块永远没有机会查找 打印 功能

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

    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
    
        2
  •  3
  •   user2357112    6 年前

    在Python 2中, print 打印 因为同样的原因你不能重新定义 if while , def ,或任何其他语言关键字;它们是语言语法的一部分,由解析器处理,而不是通过查找函数。

    from __future__ import print_function 也由解析器处理。它看起来像一个普通的导入,实际上它确实导入了一个东西,但是它导入的东西与语句的主要功能无关,即告诉解析器停止处理 打印 作为关键字。

    禁用关键字时, 打印 被视为遵循普通名称查找规则的普通名称。这样的查找可以找到 print 内置函数,通常由关键字隐藏。

    您不能定义自己的魔术导入;它们必须内置到解释器本身中。因为你不能定义你自己的魔法导入,而且 __future__ 导入会将关键字转换为非关键字,因此无法进行泛化。

    (人们有时会说 list dict


    至于猴子补丁内置函数(不是关键字)与原来不同的签名,你可以这样做。这可能是个坏主意,但你可以做到。这个过程与通常情况下修补内置程序的过程相同。