![](/img/trans.png)
[英]How to access the variable declared in package init file when we use 'from package.subpackage import module'?
[英]How to access 'global' variable from subpackage?
我目前正在嘗試發布一些更大的項目。 這就是我決定使用子模塊的原因。 看一下項目結構:
/sandbox
__init.py__
constants.py
/sub1
__init__.py
foo.py
在我的constants.py
文件中,我聲明了一個全局變量:
MYGLOBAL = 42
我想在foo.py
中使用它的值。 該文件有 2 個用於測試的函數:
def foofunc():
return 'I am foo.'
def constfunc():
return 'I am {MYGLOBAL}.'
另外,我將這段代碼放入/sandbox/sub1/__init__.py
:
from .foo import *
from sandbox.constants import *
現在,當我使用我的解釋器時,我嘗試像這樣使用這兩個函數:
>> import sandbox.sub1
>> sandbox.sub1.foofunc()
'I am foo.'
>> sandbox.sub1.MYGLOBAL
42
>> sandbox.sub1.constfunc()
NameError: name 'MYGLOBAL' is not defined
據我了解,全局變量與函數位於同一命名空間中,但不知何故 function 看不到它。
我怎樣才能訪問它? Python 版本是 3.6。
謝謝!
“全局”變量在Python中並不是真正的全局變量,僅在定義它們的模塊的命名空間中可用。
您應該在foo.py
導入constants
,以便可以將MYGLOBAL
用作constants
模塊對象的屬性:
from sandbox import constants
def constfunc():
return f'I am {constants.MYGLOBAL}.'
對這個非常好的問題的遲到回答(已投票)。
這是一件事,可以讓您更好地了解正在發生的事情:
>>> sandbox.sub1.constfunc.__module__
'sandbox.sub1.foo'
>>> sandbox.sub1.constfunc.__globals__['MYGLOBAL']
KeyError: 'MYGLOBAL'
>>> sandbox.sub1.foo.MYGLOBAL = 5
>>> sandbox.sub1.constfunc.__globals__['MYGLOBAL']
5
>>> sandbox.sub1.constfunc()
'I am 5'
換句話說,
“這個 function 實際上屬於哪個模塊,從而決定它可以使用哪些模塊全局變量?”
您錯誤地認為它是sandbox.sub1
,但它實際上是sandbox.sub1.foo
。 原因是因為函數的“父模塊”攜帶了 function object,即使這個 function object 被復制到另一個模塊的“工作區”。
有了這種理解,您可以做幾件事。 一個是根據這里的另一個答案。 另一種解決方案可能是在__init__.py
中執行此操作:
from . import foo
from .. import constants
foo.MYGLOBAL = constants.MYGLOBAL
等等
有趣的事情要注意:
需要注意的一件事是from X import Y as Z
語法實際上等同於說Z = XY
。 這是一個重要的見解,因為它可以幫助您認識到 Z 本身並不是一個“參考”:如果您更改 XY,Z 將不會自動更新。
如果將 X 中的 Y 更改為另一個值,並且想要更新 Z,則需要使用“from X import Y as Z”語法重新導入它。
有趣的是,你不能簡單地做:
sandbox.sub1.constfunc.__module__ = sandbox.constants
並簡單地期望將函數的模塊全局變量“替換”為sandbox.constants
的變量。 這樣做的原因似乎是constfunc.__module__
屬性只是原始父模塊的“副本”,更改它不會影響綁定到 function 的實際父模塊(即,它不會動態地“重新綁定” function 到另一個模塊;但是,由於這是一個內部變量,它可能會在未來的 python 版本中發生變化。誰知道呢。不要依賴它。)
此外, __module__
屬性不用於為 function 創建constfunc.__globals__
字典; 這似乎總是直接反映“父模塊”的全局字典。 因此,簡單地替換sandbox.sub1.constfunc.__module__
變量不會自動替換constfunc.__globals__
字典,但更新sandbox.sub1.foo
會。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.