2017-11-10 97 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