【问题标题】:Renaming python package with backwards compatibility (for pickle)重命名具有向后兼容性的python包(用于pickle)
【发布时间】:2020-11-21 08:50:40
【问题描述】:

我有一个 Python 包 foo(包括 GitHub 存储库),我想尽快公开它并注册为 pypi 包。不幸的是,名称 foo 确实已经存在于 pypi 注册表中,所以我想将包重命名为 bar,包括 repo。

但是,我使用 foo 包创建了结果文件并使用 pickle 保存,这很耗时,因此我不想使用重命名的包重新计算它们。有没有办法重命名包,但之后仍然能够正确访问文件(作为重命名包的对象)?

除了重命名的包目录和setup.py 的更改以及一些导入之外,代码本身将保持不变(模块、类、函数等)。我只想离开

foo/
├── docs/
├── tests/
├── setup.py
└── foo/
    ├── __init__.py
    ├── file1.py
    └── file2.py

bar/
├── docs/
├── tests/
├── setup.py
└── bar/
    ├── __init__.py
    ├── file1.py
    └── file2.py

有没有办法做到这一点?

非常感谢任何帮助!

【问题讨论】:

    标签: python module package rename pickle


    【解决方案1】:

    其他人可能有更好的主意,但我尝试了一些方法,但我认为没有一种方法可以完全按照您的意愿行事。你可以做的是正确地重命名模块,然后做一些hackery来继续使用你的腌制文件,假设我已经正确理解你的情况并且腌制文件是你对模块所做的工作,而不是模块的一部分模块本身,即使那样同样的方法也应该有效。您的包裹名称必须具有合理的唯一性,并且您选择的新名称的长度必须完全相同。如果是这样,您将能够通过对腌制数据进行文本替换来打开使用前一个模块腌制的文件......很可能。我当然会在尝试之前制作所有腌制数据的备份副本,但是如果我创建一个包含具有 A 类的模块测试的包栏,然后保存该类的实例化的腌制副本,则无法加载如果我重命名包 Bar.但是:

    f = open('pickletest.pk','rb')
    pickle.loads(f.read().replace(b'bar',b'Bar'))
    

    确实有效。当然,重要的是 b'bar' 不会出现在腌制数据中的任何地方,如果您使用的实际模块名称相对唯一,那么这是一个合理的假设,而不是包名称。如果您重命名包 bar2,则如果不对腌制文件进行进一步修改,它将无法工作。您可以进一步解析 pickle 语言,以确保您正在做的事情不会导致任何问题,但这将是很多工作。

    编辑:

    只是稍微研究了一下,如果你真的想安全起见,你可以编写一个自定义 unpickler 来使用你的遗留数据,这样可以防止你的模块名称出现在文本数据元素或其他东西中,并且会允许您根据需要重命名模块,而无需手动解析腌制流see here and note that the numpy step wouldn't be relevant to you.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-04
      • 2014-08-10
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多