2017-04-13 10 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 

私は何を逃したのですか?どうすればこの権利を行えますか? 私も

evalの使用は奇妙です...キーワードは、私がグーグルべきか分かりませんが、これらのコードは、デモンストレーションのみを目的だけです。

答えて

0

これは、Pythonや、私が知っている言語で変数がどのように機能するかはまったくありません。

関数のグローバルスコープは、定義されている場所であり、実行される場所ではありません。 print_nameがfoo.pyのnameの値にアクセスする方法はありません。

代わりに、パラメータとして渡す必要があります。また、実際に何をしたいかによっては、クラスレベルでnameの値を定義するクラスを作成することもできます。

+0

私は同意するが、( 'class'を使用せずに)これを達成するためにどのような方法があります場合、私はちょうど思ったんだけど – amigcamel

+2

動的スコープ言語(顕著な例はSchemeとシェルです)。 Pythonは静的スコープです。 – chepner

0

実際これも可能です。

私は同様の質問が見つかりました:
How to use inspect to get the caller's info from callee in Python?

をそして私は、これは、組み込みのライブラリinspectがために何が来るのかと思います。あなたが記述している@amigcamel

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 
関連する問題