选择加入 BC 对单个模块中的方法进行重大更改的方法

问题描述

我正在寻找让用户选择加入 BC 更改的机制,其工作方式类似于 __future__,但可以由库指定。也就是说:

  • 它是词法范围的(仅影响模块,不影响您从模块调用的任何函数
  • 它适用于方法(不仅仅是函数
  • 它不需要我以其他方式编辑我的代码,除了选择加入

为了说明的目的,让我们假设我们是一个数字库,希望对名为 from __future__ import division方法进行与 Python 在 https://www.python.org/dev/peps/pep-0238/ 中的 div on班级:

class Number:
    # old behavior
    def div(self,other):
       if self.is_floating_point() or other.is_floating_point():
           return self.item() / other.item()
       else:
           return self.item() // other.item()

    # desired new behavior
    def div(self,other):
       return float(self.item()) / float(other.item())

在 Python 中,他们添加一个新的 future pragma,改变了 __div____truediv__ 之间 / 运算符的含义。我们不是 Python,所以我们不能那样做。我们可以模拟这个吗?

许多让人们选择新行为的经典机制都未能满足上述一项或多项标准。我们来看几个:

函数指定不同的名称,并以旧名称导入新函数如果 div 是顶级函数,这可能会起作用:

# number.py
def div(self,other):
    ... old behavior ...

def div_v2(self,other):
    ... new behavior ...

# client
from number import div_v2 as div

但是div是一个方法,这些不是传统意义上的导入。

添加一个全局标志来切换行为。

DIV_NEW_BEHAVIOR = False

class Number:
    # old behavior
    def div(self,other):
       if DIV_NEW_BEHAVIOR:
           ... new behavior ...
       else:
           ... old behavior ...

然而,这是一个全有或全无的标志;如果我在顶级 main.py 文件中切换它,它将影响所有代码。这与 __future__ 编译指示形成对比,后者适用于它所应用到的模块。将标志转换为上下文管理器也不起作用,因为如果您设置上下文管理器,然后调用一个模块中定义的函数,即使该模块没有选择加入,该标志仍​​将被设置。>

制作新版本的课程。

class Number:
    def div(self,other):
        ... old behavior ...

class Number_v2:
    def div(self,other):
        ... new behavior ...

希望很明显为什么这是一个坏主意?就像,如果你在 Python PEP 中提出要解决真正的除法问题,我们应该制作两种类型的整数,一种是旧的除法,另一种是真正的除法,你会被嘲笑街道?在任何情况下,这都不符合词法范围的要求,因为 Number_v2 会“感染”后续使用,即使它们在模块之外。


__future__ 是一种几乎理想的机制,用于在底层库实现可以支持旧的和新的操作模式时进行可选的 BC 破坏性更改。但它仅适用于 Python 语言实现者。其他图书馆作者呢?

(这是 https://stackoverflow.com/posts/66926637 的转贴,有更多示例)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)