微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决选择加入 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 举报,一经查实,本站将立刻删除。