2017-04-13 110 views
0

標題可能是誤導或不準確的,所以如果我錯了,請糾正我。跨模塊的Python變量範圍

我有一個包的結構是這樣的:

common 
    __init__.py 
foo.py 

這裏是代碼:

common/__init__.py

name = 'name_common' 

def print_current_file_name(): 
    print('current file name: ' + __file__) 

def print_name(): 
    print('name is: ' + eval('name')) 

foo.py

from common import print_current_file_name, print_name 

name = 'name_foo' 

if __name__ == '__main__': 
    print_current_file_name() 
    print_name() 

如果我這樣做:

>>> python foo.py 

我會得到這樣的:

current file name: /tmp/common/__init__.py 
name is: name_common 

但我期望的結果是:

current file name: /tmp/common/foo.py 
name is: name_foo 

我錯過了什麼?我怎樣才能做到這一點? 我甚至不知道哪些關鍵字應該google ...

eval的使用很奇怪,但這些代碼僅用於演示目的。

回答

0

這並不代表Python如何使用變量,或者我知道的任何語言。

函數的全局範圍總是定義的地方,而不是它的執行位置。 print_name無法訪問foo.py中的name的值。

相反,您應該將它作爲參數傳入。或者,根據您實際想要執行的操作,您可能需要創建一個類,該類在類級別定義name的值。

+0

我同意,但我只是想知道是否有任何的方式來實現這一目標(不使用'class') – amigcamel

+2

@amigcamel你描述動態範圍的語言(突出的例子是Scheme和shell); Python是靜態範圍的。 – chepner

0

其實這是可能的。

我發現了一個類似的問題:
How to use inspect to get the caller's info from callee in Python?

而且我認爲這是內置庫inspect來了。

common/__init__.py

from os.path import abspath 
import inspect 


name = 'name_common' 

def print_current_file_name(): 

    print('current file name: ' + abspath(inspect.getfile(inspect.currentframe().f_back))) 
    # or 
    print('current file name: ' + abspath(inspect.currentframe().f_back.f_globals['__file__'])) 

def print_name(): 
    print('name is: ' + inspect.currentframe().f_back.f_globals['name']) 

最後,

$ python foo.py 
current file name: /tmp/common/foo.py 
name is: name_foo