wim*_*wim 5 python introspection python-import python-3.x
有两个文件:
# the_imported.py
import inspect
imported_by_fname = inspect.currentframe().f_back.f_code.co_filename
print('{} was imported by {}'.format(__name__, imported_by_fname))
Run Code Online (Sandbox Code Playgroud)
和:
# the_importer.py
import the_imported
Run Code Online (Sandbox Code Playgroud)
使用 Python 2.7 执行时:
$ python the_importer.py
the_imported was imported by the_importer.py
Run Code Online (Sandbox Code Playgroud)
使用 Python 3.5 执行时:
$ python3 the_importer.py
the_imported was imported by <frozen importlib._bootstrap>
Run Code Online (Sandbox Code Playgroud)
这到底是怎么回事<frozen importlib._bootstrap>
?发生了什么import
和/或inspect
改变了这种行为?我们怎样才能让 Python 2 文件名自省在 Python 3 上再次运行?
Python 3 中的堆栈中还有更多内容。 importlib
现在负责导入:
# the_imported.py
from inspect import getframeinfo, getouterframes, currentframe
frame = currentframe()
while frame:
print(frame.f_code.co_filename)
frame = frame.f_back
Run Code Online (Sandbox Code Playgroud)
输出:
C:\Users\user\Desktop\the_imported.py
<frozen importlib._bootstrap>
<frozen importlib._bootstrap>
<frozen importlib._bootstrap>
<frozen importlib._bootstrap>
<frozen importlib._bootstrap>
<frozen importlib._bootstrap>
<frozen importlib._bootstrap>
<frozen importlib._bootstrap>
C:\Users\user\Desktop\the_importer.py
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
# the_imported.py
from inspect import getframeinfo, getouterframes, currentframe
frame = currentframe().f_back
while frame.f_code.co_filename.startswith('<frozen'):
frame = frame.f_back
print(frame.f_code.co_filename)
Run Code Online (Sandbox Code Playgroud)
输出:
C:\Users\user\Desktop\the_importer.py
Run Code Online (Sandbox Code Playgroud)
在 Python 3.1 及更高版本中,导入机制是用 Python 实现的,这使得可以访问其调用堆栈。为了说明这一点,我将输入以下代码
from traceback import print_stack
print_stack()
Run Code Online (Sandbox Code Playgroud)
到the_imported.py并导入它。
在 Python 2 上,代码打印
File "the_importer.py", line 2, in <module>
import the_imported
File ".../the_imported.py", line 3, in <module>
print_stack()
Run Code Online (Sandbox Code Playgroud)
但在 Python 3 上,输出更加冗长:
File "the_importer.py", line 2, in <module>
import the_imported
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 677, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File ".../the_imported.py", line 2, in <module>
print_stack()
Run Code Online (Sandbox Code Playgroud)
在 Python 3.3 之前,这些行也包含在 Tracebacks 中。
为了达到所需的结果,您可以沿着调用堆栈查找第一帧,其文件名不以<frozen importlib
.
from traceback import extract_stack
for x in extract_stack():
if not x[0].startswith('<frozen importlib'):
print('{} was imported by {}'.format(__name__, x[0]))
break
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
522 次 |
最近记录: |