If there is method t1
in file a.py
and there is a file b.py
, which calls method t1
from a.py
file. How do I get full/absolute path to b.py
file inside t1
method?
With inspect module (just like here: how to get the caller's filename, method name in python ), I can get relative path to file, but it seems it does not contain absolute path (or there is some other attribute object, to access to get it?).
As an example:
a.py:
def t1():
print('callers absolute path')
b.py:
from a import t1
t1() # should print absolute path for `b.py`
Using sys._getframe()
:
a1.py :
import sys
def t1():
print(sys._getframe().f_code)
a2.py :
from a1 import t1
t1() # should print absolute path for `b.py`
Hence :
py -m a2.py
OUTPUT :
<code object t1 at 0x0000029BF394AB70, file "C:\Users\dirtybit\PycharmProjects\a1.py", line 2>
EDIT :
Using inspect
:
a1.py :
import inspect
def t1():
print("Caller: {}".format(inspect.getfile(inspect.currentframe())))
a2.py :
from a1 import t1
t1() # should print absolute path for `b.py`
OUTPUT :
Caller: C:\Users\dirtybit\PycharmProjects\a1.py
You can get it with the os
module in python.
>>> import a
>>> os.path.abspath(a.__file__)
Using the os module you can do the following:
a.py
import os
def t1(__file__):
print(os.path.abspath(__file__))
b.py
from a import t1
t1(__file__) # shoult print absolute path for `b.py`
With this, you could call t1(__file__
and get the absolute path for any file.
import os
import inspect
def get_cfp(real: bool = False) -> str:
"""Return caller's current file path.
Args:
real: if True, returns full path, otherwise relative path
(default: {False})
"""
frame = inspect.stack()[1]
p = frame[0].f_code.co_filename
if real:
return os.path.realpath(p)
return p
Running from another module:
from module import my_module
p1 = my_module.get_cfp()
p2 = my_module.get_cfp(real=True)
print(p1)
print(p2)
Prints:
test_path/my_module_2.py
/home/user/python-programs/test_path/my_module_2.py
The trick consists in recovering both the current working directory and the relative path wrt that directory to the caller file (here b.py
). The join does the rest.
a.py:
import os
import sys
def t1():
namespace = sys._getframe(1).f_globals
cwd = os.getcwd()
rel_path = namespace['__file__']
abs_path= os.path.join(cwd,rel_path)
print('callers absolute path!',abs_path)
b.py:
from a import t1
t1() # prints absolute path for `b.py`
The trick does not work for jupyter notebooks unfortunately..
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.