支持 python 包的两个版本,客户端无需更改代码
Support two versions of a python package without clients needing to change code
我试图在不影响客户端代码的情况下支持 python 包的多个版本。
考虑以下回购:
.
|-- client_code.py
`-- lib
|-- __init__.py
`-- foo.py
client_code.py:
from lib.foo import f
...
f()
我想 client_code.py
保持不变。我首先尝试做这样的事情:
lib
|-- __init__.py
|-- v1
| |-- __init__.py
| `-- foo.py
`-- v2
|-- __init__.py
`-- foo.py
lib/__init__.py:
import os
if os.environ.get("USE_V2", "0") == "0": # Or some other runtime check
from .v1 import foo
else:
from .v2 import foo
但是客户端代码失败并出现以下错误:
Traceback (most recent call last):
File "client_code.py", line 1, in <module>
from lib.foo import f
ImportError: No module named foo
我知道以下选项可行,但它们需要客户更改代码:
if os.environ.get("USE_V2", "0") == "0":
from lib.v1.foo import f
else:
from lib.v2.foo import f
f()
if os.environ.get("USE_V2", "0") == "0":
import lib.v1.foo as foo
else:
import lib.v2.foo as foo
foo.f()
这样的事情可能吗?
问题的更一般版本在这里:
我不确定它是否最优雅,但这似乎可行。
├── client.py
└── lib
├── __init__.py
├── foo.py
├── v1
│ └── foo.py
└── v2
└── foo.py
foo.py
import os
if os.environ.get("USE_V2", "0") == "0":
from lib.v1.foo import *
else:
from lib.v2.foo import *
v1/foo.py
def f():
print("I'm v1.f")
v2/foo.py
def f():
print("I'm v2.f")
client.py
from lib.foo import f
f()
运行 输出:
$ env | grep USE_V2
USE_V2=1
$ python client.py
I'm v2.f
$ unset USE_V2
$ python client.py
I'm v1.f
有实际的foo.py import *
看起来很糟糕,但这只是懒惰的方法。鉴于 v1 和 v2 的内容有些不同,您可以 foo.py adapt 导入以在两种情况下呈现统一的 API。或者您可以说准备 V2 中不再存在的 functools.partial
版本的 V1 函数。
__init__.py
是空的,在 Python 下甚至不需要存在 3.
我试图在不影响客户端代码的情况下支持 python 包的多个版本。
考虑以下回购:
.
|-- client_code.py
`-- lib
|-- __init__.py
`-- foo.py
client_code.py:
from lib.foo import f
...
f()
我想 client_code.py
保持不变。我首先尝试做这样的事情:
lib
|-- __init__.py
|-- v1
| |-- __init__.py
| `-- foo.py
`-- v2
|-- __init__.py
`-- foo.py
lib/__init__.py:
import os
if os.environ.get("USE_V2", "0") == "0": # Or some other runtime check
from .v1 import foo
else:
from .v2 import foo
但是客户端代码失败并出现以下错误:
Traceback (most recent call last):
File "client_code.py", line 1, in <module>
from lib.foo import f
ImportError: No module named foo
我知道以下选项可行,但它们需要客户更改代码:
if os.environ.get("USE_V2", "0") == "0":
from lib.v1.foo import f
else:
from lib.v2.foo import f
f()
if os.environ.get("USE_V2", "0") == "0":
import lib.v1.foo as foo
else:
import lib.v2.foo as foo
foo.f()
这样的事情可能吗?
问题的更一般版本在这里:
我不确定它是否最优雅,但这似乎可行。
├── client.py
└── lib
├── __init__.py
├── foo.py
├── v1
│ └── foo.py
└── v2
└── foo.py
foo.py
import os
if os.environ.get("USE_V2", "0") == "0":
from lib.v1.foo import *
else:
from lib.v2.foo import *
v1/foo.py
def f():
print("I'm v1.f")
v2/foo.py
def f():
print("I'm v2.f")
client.py
from lib.foo import f
f()
运行 输出:
$ env | grep USE_V2
USE_V2=1
$ python client.py
I'm v2.f
$ unset USE_V2
$ python client.py
I'm v1.f
有实际的foo.py import *
看起来很糟糕,但这只是懒惰的方法。鉴于 v1 和 v2 的内容有些不同,您可以 foo.py adapt 导入以在两种情况下呈现统一的 API。或者您可以说准备 V2 中不再存在的 functools.partial
版本的 V1 函数。
__init__.py
是空的,在 Python 下甚至不需要存在 3.