[英]Get relative path of caller in Python
我有這個功能:
def relative_path(*paths):
return os.path.join(os.path.dirname(__file__), *paths)
如何更改它以返回相對於調用者的路徑?
例如,如果我從另一個腳本調用relative_path('index.html')
,是否可以從隱式調用它的位置獲取相對於腳本的路徑,或者我是否需要修改relative_path
以傳遞__file__
以及這樣?
def relative_path(__file__, *paths):
return os.path.join(os.path.dirname(__file__), *paths)
在Python中調用函數模塊的Get __name__中的解決方案
file1.py
import os
import inspect
def relative_path(*paths):
return os.path.join(os.path.dirname(__file__), *paths)
def relative_to_caller(*paths):
frm = inspect.stack()[1]
mod = inspect.getmodule(frm[0])
return os.path.join(os.path.dirname(mod.__file__), *paths)
if __name__ == '__main__':
print(relative_path('index.html'))
子/ sub_file.py
import sys
sys.path.append(r'/Users/xx/PythonScripts/!scratch')
import file1
if __name__ == '__main__':
print(file1.relative_path('index.html'))
print(file1.relative_to_caller('index.html'))
運行sub_file.py會給出以下輸出:
/Users/xx/PythonScripts/!scratch/index.html
/Users/xx/PythonScripts/!scratch/sub/index.html
在上面的鏈接中對問題的評論中有一些警告......
請注意,跟蹤堆棧在這里是可能的,但它可能會導致一些嚴重的麻煩(比如混淆'垃圾收集器',或者甚至可能無法在雞蛋中工作)
我相信最干凈的方法是將調用者傳遞給rel_path函數。
但是,正如您所知,在python中通常有一種丑陋的做法。 你可以這樣做:
考慮以下兩個腳本:
# relpath.py
import os
def rel_path(path):
if os.path.isfile(__name__):
return os.path.relpath(path, start=__name__)
print("Warning: %s is not a file: returning path relative to the current working dir" % __name__, file=sys.stderr)
return os.path.relpath(path)
# caller.py
import importlib.util
spec = importlib.util.spec_from_file_location(name=__file__, location="/workspace/relpath.py")
rel = importlib.util.module_from_spec(spec)
spec.loader.exec_module(rel)
print(rel.rel_path("/tmp"))
我們在這里做了什么:當使用importlib.util加載模塊時,我們傳遞了name=__file__
,它為我們的模塊提供了包含調用者腳本路徑的名稱。 因此,我們不需要將它作為參數傳遞給relpath.py 。
請注意,這是不干凈的解決方案,可能無法讀取為以后的開發人員閱讀你的代碼。 我只想展示python的可能性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.