Mám tri moduly:
constants
, ktorá obsahuje načítanú konfiguráciu a ďalšie veci v triedemain
, ktorý sa inicializujeconstants
keď je spustenýuser
, ktorý dovážaconstants
a pristupuje k svojej konfigurácii.
constants
modul (zjednodušený) vyzerá takto:
class Constants:
def __init__(self, filename):
# Read values from INI file
config = self.read_inifile(filename)
self.somevalue = config["ex"]["ex"]
def read_inifile(self, filename):
# reads inifile
constants: Constants = None
def populate_constants(filename):
global constants
constants = Constants(filename)
Jednoduchý objekt, ktorý by mal obsahovať konfiguráciu, nič priekopnícke.
Funkcia populate_constants()
je povolaný od main
pri štarte programu.
Teraz sa stane divnosť - keď importujem constants
modul od user
ako je tento, constants
je None
:
from toplevelpkg.constants import constants
print(constants)
None
Ak to však importujem, constants
je inicializovaný podľa očakávania:
from toplevelpkg import constants
print(constants.constants)
<trumpet.constants.Constants object at 0x035AA130>
Prečo to je?
EDIT: v mojom kóde funkcia, ktorá sa pokúša čítať constants
je spustený asynchrónne prostredníctvom await loop.run_in_executor(None, method_needing_import)
, Nie ste si istí, či to môže spôsobiť problémy?
(a ako vedľajšia otázka, je dobré mať objekt na udržiavanie konfigurácie, ktorý analyzuje konfiguračný súbor a poskytuje ho ako svoje členské premenné?)
odpovede:
2 pre odpoveď č. 1Medzi nimi je skutočne rozdiel
from mymodule import obj
(...)
do_something_with(obj)
a
import mymodule
(...)
do_something_with(mymodule.obj)
V prvom prípade sa správa takto:
import mymodule
obj = mymodule.obj
del mymodule
čo znamená, že v tomto bode v súčasnom module obj
je „globálny“ (čo v Pythone v skutočnosti znamená „modul-úroveň“, nie „široká aplikácia“) názov viazaný na čokoľvek mymodule.obj
bol kedy bol importovaný (vo vašom prípade: None
). Od tej doby, mymodule.obj
a modul-local obj
Mená žijú v rôznych menných priestoroch (prvé v mymodule
namespace, druhý v aktuálnom mennom priestore modulu) a rebinding mymodule.obj
odkiaľkoľvek nezmení nič na to, čo má súčasný modul obj
je viazaný na. V skutočnosti je to presne také, ako keby ste to robili:
a = 2
b = a
a = 4
Po treťom vyhlásení b
je samozrejme stále povinný 2
- rebounding a
na 4
nemá vplyv b
.
V druhom prípade (import mymodule
) to, čo je spojené s menným priestorom importujúceho modulu, je celok mymodule
objekt, takže ak mymodule.obj
sa odrazí (zvnútra) mymodule
alebo kdekoľvek inde) zmena bude viditeľná v importujúcom module. V tomto prípade je to ekvivalentné
a = {"x": 2}
b = a
a["x"] = 4
V takom prípade bude zmena viditeľná od b["x"]
od tej doby a
a b
sú stále viazané na ten istý objekt.
wrt / vaša vedľajšia otázka: áno, mať nejaký „konfiguračný“ objekt je celkom bežný model. Možno sa budete chcieť uistiť, že ho môžete zostaviť aj „od nuly“ (myslím, nie nevyhnutne z konfiguračného súboru), aby sa zjednodušilo testovanie jednotiek.