2017-11-10 72 views
0

假设我有一个叫做pymodule的python模块,它位于一个名为pymodule.py的文件中。python3:导入当前模块的文件的名称?

此外,假设pymodule由多个其他python程序导入,例如program0.py,program1.pyprogram2.py

有没有我在pymodule.py内编写的代码可以在运行时确定它被导入到的文件的名称?在这个例子中,我们最终会得到/path/to/program0.py/path/to/program1.py/path/to/program2.py,这取决于这三个程序中的哪一个正在运行。

当然,可能会有一个嵌套的导入组,其中导入了pymodule,所以在一般情况下,我最好在运行时获取整组导入祖先文件名。

有没有办法在python3中做到这一点?

非常感谢。

回答

0

好的。我想到了。此代码可以驻留在pymodule.py ...

# This is the "parent" of the current module. 
# `sys._getframe(0)` would be `pymodule.py`. 
f = sys._getframe(1) 
while f is not None: 
    print('filename: {}'.format(f.f_code.co_filename) 
    f = f.f_back 

它打印出来,如果/path/to/program0.py运行下列...

filename: <frozen importlib._bootstrap> 
filename: <frozen importlib._bootstrap_external> 
filename: <frozen importlib._bootstrap> 
filename: <frozen importlib._bootstrap> 
filename: <frozen importlib._bootstrap> 
filename: /path/to/program0.py 

因此,所有我需要做的就是忽略与<frozen ...开始项目,我会得到祖先的文件名。这是一个功能...

def ancestor_importers(): 
    ancestors = [] 
    # Start with item number 2 here, because we're 
    # inside of a function. Assume this function 
    # resides at the top level of `pymodule`. If not, 
    # the argument of sys._getframe(2) needs to be 
    # adjusted accordingly. 
    f = sys._getframe(2) 
    while f is not None: 
     fn = f.f_code.co_filename 
     if not fn.startswith('<frozen '): 
      ancestors.append(fn) 
     f = f.f_back 
    return ancestors