簡體   English   中英

支持 python package 的兩個版本,無需客戶端更改代碼

[英]Support two versions of a python package without clients needing to change code

我正在嘗試在不影響客戶端代碼的情況下支持 python package 的多個版本。

考慮以下回購:

.
|-- client_code.py
`-- lib
    |-- __init__.py
    `-- foo.py

客戶端代碼.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()

這樣的事情可能嗎?

問題的更通用版本在這里: 支持 python package 的兩個版本,無需客戶端更改代碼

我不確定它是最優雅的,但這似乎有效。

├── 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")

客戶端.py

from lib.foo import f

f()

運行 output:

$ 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調整導入以在兩種情況下呈現統一的 API。 或者你可以說准備一個 V1 function 的functools.partial版本,它不再存在於 V2 中。

__init__.py是空的,甚至不需要存在於 Python 3 下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM