2 回答

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊
這樣的問題可能存在爭(zhēng)議。但我通常會(huì)說是的,這是“不好的做法”,因?yàn)樽兏锏姆秶陀绊懘_實(shí)變得模糊。請(qǐng)注意,您描述的用例實(shí)際上不是關(guān)于共享配置,而是關(guān)于程序函數(shù)、對(duì)象、模塊交換數(shù)據(jù)的不同部分,因此它是(元)變量的一些變體global。
讀取通用配置值可能沒問題,但一路更改它們...您可能會(huì)忘記在導(dǎo)入模塊/修改值時(shí)發(fā)生的情況以及順序。例如假設(shè)config.py和 兩個(gè)模塊m1.py:
import config
print(config.x)
config.x=1
和m2.py:
import config
print(config.x)
config.x=2
和 amain.py就這樣做:
import m1
import m2
import config
print(config.x)
或者:
import m2
import m1
import config
print(config.x)
您在每個(gè)模塊以及其他任何模塊(包括main.py此處)中找到配置的狀態(tài)取決于導(dǎo)入發(fā)生的順序以及誰在何時(shí)分配什么值。即使對(duì)于完全在您控制之下的程序,這也可能很快變得令人困惑(以及錯(cuò)誤的根源)。
對(duì)于運(yùn)行時(shí)數(shù)據(jù)以及在對(duì)象和模塊之間傳遞信息(您的示例確實(shí)是這樣,而不是在模塊之間預(yù)定義和共享的配置),我建議您考慮在自定義狀態(tài)(配置)對(duì)象中描述信息并將其傳遞通過適當(dāng)?shù)慕涌?。但?shí)際上可能只需要一個(gè)函數(shù)/方法參數(shù)即可。確切的形式取決于您到底想要實(shí)現(xiàn)什么以及您的整體設(shè)計(jì)是什么。
在您的示例中,other.py之前調(diào)用或?qū)霑r(shí)的行為有所不同top.py,在最小的示例中可能仍然看起來很明顯且易于管理,但實(shí)際上并不是一個(gè)非常合理的設(shè)計(jì)。任何閱讀代碼的人(包括未來的你)都應(yīng)該能夠遵循其邏輯,而這個(gè) IMO 打破了它的流程。
對(duì)于您所描述的內(nèi)容,最簡(jiǎn)單(也是程序性的)示例,現(xiàn)在我希望能夠更好地理解,那就是重新other.py創(chuàng)建您當(dāng)前的行為:
def do_stuff(value):
print(value) # We did something useful here
if __name__ == "__main__":
do_stuff(None) # Could also use config with defaults
您top.py可能是入口點(diǎn)并協(xié)調(diào)導(dǎo)入和執(zhí)行:
import other
x = get_the_value()
other.do_stuff(x)
您當(dāng)然可以引入一個(gè)接口來配置do_stuff一個(gè)dict或一個(gè)自定義類,即使使用默認(rèn)實(shí)現(xiàn)config.py:
class Params:
def __init__(self, x=None):
self.x = x
和你的other.py:
def do_stuff(params=config.Params()):
print(params.x) # We did something useful here
在你的上top.py你可以使用:
params = config.Params(get_the_value())
other.do_stuff(params)
但您也可以擁有任何特定于用例的值源:
class TopParams:
def __init__(self, url):
self.x = get_value_from_url(url)
params = TopParams("https://example.com/value-source")
other.do_stuff(params)
x甚至可以是property您每次訪問它時(shí)檢索的內(nèi)容...或者在需要時(shí)懶惰地檢索然后緩存...同樣,這實(shí)際上是您需要做什么的問題。

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個(gè)贊
“從一個(gè)模塊修改另一個(gè)模塊的屬性是一種不好的做法嗎?”
這被認(rèn)為是不好的做法——違反了德米特法則,這實(shí)際上意味著“與朋友交談,而不是與陌生人交談”。
對(duì)象應(yīng)該公開行為和功能,但應(yīng)該隱藏?cái)?shù)據(jù)。DataStructures 應(yīng)該公開數(shù)據(jù),但不應(yīng)該有任何方法(公開的)。德米特定律不適用于此類數(shù)據(jù)結(jié)構(gòu)。OOP 純粹主義者可能會(huì)使用 setter 和 getter 來覆蓋此類 DataStructures,但它實(shí)際上在 Python 中沒有增加任何價(jià)值。
我保留配置的首選方法是(此處不使用 attrs):
# conf_xy.py
"""
config is code - so why use damned parsers, textfiles, xml, yaml, toml and all that
if You just can use testable code as config that can deliver the correct types, etc.
as well as hinting in Your favorite IDE ?
Here, for demonstration without using attrs package - usually I use attrs (read the docs)
"""
class ConfXY(object):
? ??
? ? def __init__(self) -> None:
? ? ? ? self.x: int = 1
? ? ? ? self.z: float = get_z_from_input()
? ? ? ? ...
conf_xy=ConfXY()
# other.py
from conf_xy import conf_xy
...
y = conf_xy.x * 2
...?
添加回答
舉報(bào)