跨模块的Python变量范围

时间:2017-04-13 15:27:06

标签: python variables scope

标题可能会误导或不准确,所以如果我错了,请纠正我。

我有一个像这样结构的包:

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很奇怪,但这些代码仅用于演示目的。

2 个答案:

答案 0 :(得分:0)

这根本不是变量如何在Python中运行,或者是我所知道的任何语言。

函数的全局范围始终是定义它的位置,而不是它的执行位置。 print_name无法在foo.py中访问name的值。

相反,您应该将其作为参数传递。或者,根据您实际想要做的事情,您可能希望创建一个在类级别定义name值的类。

答案 1 :(得分: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