【问题标题】:Moving code out of __init__.py but keeping backwards compatibility将代码移出 __init__.py 但保持向后兼容性
【发布时间】:2011-03-25 00:21:15
【问题描述】:

我正在开发一个 Python 项目,以前的开发人员将大部分代码放在基础 __init__.py 文件中。我希望能够将代码从文件中移出到子目录中的新文件中。

spam/
    __init__.py
    foobar/
        __init__.py
        eggs.py

因此导入垃圾邮件模块将使用 foobar/eggs.py 中的代码。

我希望保持 100% 的兼容性,因为当前实现垃圾邮件的代码无法更改。

【问题讨论】:

    标签: python backwards-compatibility


    【解决方案1】:

    100% 的兼容性可能是不可能的。一些东西(比如pickle)真的很关心定义在哪里。

    您可以通过导入__init__.py 文件中的类/函数来获得大部分兼容性。

    【讨论】:

    • 当然……那行得通。我不知道为什么我没有想到这一点。谢谢。
    • 提供更多关于提到的泡菜问题的细节:旧泡菜将适用于新布局(他们将看到__init__.py 的参考导入)但用新布局生成的泡菜不会'不能与旧版本的代码一起使用(因为 spam.foobar 及其内容在这些版本中不存在)。其他接受任意类实例的序列化方案也可能存在类似问题。
    【解决方案2】:

    在 spam/__init__.py 中添加 from foobar import * 应该足以让所有内容都处于与之前相同的范围内。或者,如果您需要更改名称或限制导出的内容,您可以在同一个文件中重新定义需要导出的所有内容,例如 foo = foobar.newfoo

    当然,这留下了让所有东西都在全局范围内的问题,但如果你需要它在外部看起来相同,你就无能为力了。

    【讨论】:

      【解决方案3】:

      在垃圾邮件的 __init__.py 中,您可以将 foobar.egg 内容作为本地导入,然后任何从垃圾邮件中导入它的人仍然可以访问它

      from foobar.eggs import apples_newname as apples_oldname
      # or (but import * isn't recommended except for extreme cases)
      from foobar.eggs import *
      

      您还可以在垃圾邮件 __init__.py 中编写包装函数,在特定情况下只需调用鸡蛋等效项以扩展兼容性

      import foobar.eggs
      def apples_newname(*args, **kwargs):
          foobar.eggs.apples_oldname(*args, **kwargs)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-17
        • 2010-09-12
        • 2011-02-09
        • 1970-01-01
        • 1970-01-01
        • 2010-09-29
        相关资源
        最近更新 更多