Python 中模塊間全局變量的使用上的注意


最近用Python寫代碼,需要用到模塊間的全局變量。

網上四處搜索,發現普遍做法是把全局變量放到一個獨立的模塊中,使用時,導入此全局變量模塊即可。

但是在實際使用過程中發現了些小問題:在使用如下代碼導入全局變量模塊時,各個模塊獲取到的全局變量都是初始值。

from module import global_var

但是如果使用「模塊名.全局變量名」來訪問時,卻又是正常的:

import module

print module.global_var

為了弄清其中的原委,我寫了個測試程序來仔細查看其中的細節:

 

 

1. import module

global_var.py

GLOBAL_VAR = [1, 2, 3]

m1.py

import global_var
import m2

print 'm1: before appending:          ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
global_var.GLOBAL_VAR.append('m1')
print 'm1: after appending:           ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR

print 'm1: before calling m2.append():', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
m2.append()
print 'm1: after calling m2.append(): ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR

print '-----------------'

print 'm1: before assigning:          ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
global_var.GLOBAL_VAR = ['m1']
print 'm1: after assigning:           ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR

print 'm1: before calling m2.assign():', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
m2.assign()
print 'm1: after calling m2.assign(): ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR

m2.py

import global_var

def append():
    print 'm2: before assiging:           ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
    global_var.GLOBAL_VAR.append('m2')
    print 'm2: after assiging:            ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR

def assign():
    print 'm2: before assiging:           ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR
    global_var.GLOBAL_VAR = ['m2']
    print 'm2: after assiging:            ', id(global_var.GLOBAL_VAR), global_var.GLOBAL_VAR

運行結果:

Mac-pastgift:pytest pastgift$ python global_test_import/m1.py
m1: before appending:           4457308312 [1, 2, 3]
m1: after appending:            4457308312 [1, 2, 3, 'm1']
m1: before calling m2.append(): 4457308312 [1, 2, 3, 'm1']
m2: before assiging:            4457308312 [1, 2, 3, 'm1']
m2: after assiging:             4457308312 [1, 2, 3, 'm1', 'm2']
m1: after calling m2.append():  4457308312 [1, 2, 3, 'm1', 'm2']
-----------------
m1: before assigning:           4457308312 [1, 2, 3, 'm1', 'm2']
m1: after assigning:            4457444848 ['m1']
m1: before calling m2.assign(): 4457444848 ['m1']
m2: before assiging:            4457444848 ['m1']
m2: after assiging:             4457308312 ['m2']
m1: after calling m2.assign():  4457308312 ['m2']

在這種方式下,如果是改變對象本身的操作(append),各個模塊內部的操作都是針對於同一個對象。

而賦值操作,雖然全局變量所指向的對象改變了,但是全局變量本身依然在各個模塊內部能夠正確訪問,這正是我所希望的效果。

 

 

2. from module import GLOBAL_VAR

global_var.py

GLOBAL_VAR = [1, 2, 3]

m1.py

from global_var import GLOBAL_VAR
import m2

print 'm1: before appending:          ', id(GLOBAL_VAR), GLOBAL_VAR
GLOBAL_VAR.append('m1')
print 'm1: after appending:           ', id(GLOBAL_VAR), GLOBAL_VAR

print 'm1: before calling m2.append():', id(GLOBAL_VAR), GLOBAL_VAR
m2.append()
print 'm1: after calling m2.append(): ', id(GLOBAL_VAR), GLOBAL_VAR

print '-----------------'

print 'm1: before assigning:          ', id(GLOBAL_VAR), GLOBAL_VAR
GLOBAL_VAR = ['m1']
print 'm1: after assigning:           ', id(GLOBAL_VAR), GLOBAL_VAR

print 'm1: before calling m2.assign():', id(GLOBAL_VAR), GLOBAL_VAR
m2.assign()
print 'm1: after calling m2.assign(): ', id(GLOBAL_VAR), GLOBAL_VAR

m2.py

from global_var import GLOBAL_VAR

def append():
    global GLOBAL_VAR

    print 'm2: before assiging:           ', id(GLOBAL_VAR), GLOBAL_VAR
    GLOBAL_VAR.append('m2')
    print 'm2: after assiging:            ', id(GLOBAL_VAR), GLOBAL_VAR

def assign():
    global GLOBAL_VAR

    print 'm2: before assiging:           ', id(GLOBAL_VAR), GLOBAL_VAR
    GLOBAL_VAR = ['m2']
    print 'm2: after assiging:            ', id(GLOBAL_VAR), GLOBAL_VAR

運行結果:

Mac-pastgift:pytest pastgift$ python global_test_from_import/m1.py
m1: before appending:           4539998360 [1, 2, 3]
m1: after appending:            4539998360 [1, 2, 3, 'm1']
m1: before calling m2.append(): 4539998360 [1, 2, 3, 'm1']
m2: before assiging:            4539998360 [1, 2, 3, 'm1']
m2: after assiging:             4539998360 [1, 2, 3, 'm1', 'm2']
m1: after calling m2.append():  4539998360 [1, 2, 3, 'm1', 'm2']
-----------------
m1: before assigning:           4539998360 [1, 2, 3, 'm1', 'm2']
m1: after assigning:            4540135112 ['m1']
m1: before calling m2.assign(): 4540135112 ['m1']
m2: before assiging:            4539998360 [1, 2, 3, 'm1', 'm2']
m2: after assiging:             4540135040 ['m2']
m1: after calling m2.assign():  4540135112 ['m1']

這次,運行結果和上次略有不同。

改變對象本身的操作(append)和之前的例子一樣,全局變量始終指向相同的對象。

但是賦值操作就比較奇怪了。注意標紅部分,每個模塊第一次獲取到的這個「全局變量」都是相同id的對象。即使這個「全局變量」在其他模塊中已經被重新賦值,但在本模塊中依然指向的是最原始的id。

顯然,這個算不上是「全局變量」了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM