【问题标题】:inspect who imported me检查谁进口了我
【发布时间】:2017-04-18 03:55:43
【问题描述】:

有两个文件:

# 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))

还有:

# the_importer.py
import the_imported

使用 Python 2.7 执行时:

$ python the_importer.py 
the_imported was imported by the_importer.py

使用 Python 3.5 执行时:

$ python3 the_importer.py 
the_imported was imported by <frozen importlib._bootstrap>

&lt;frozen importlib._bootstrap&gt; 到底是怎么回事? import 和/或 inspect 发生了什么改变了这种行为?我们如何才能让 Python 2 文件名自省在 Python 3 上再次运行?

【问题讨论】:

    标签: python python-3.x python-import introspection


    【解决方案1】:

    在 Python 3.1 和更新版本中,import machinery 在 Python 中实现,这使得访问其调用堆栈成为可能。为了说明这一点,我将输入以下代码

    from traceback import print_stack
    print_stack()
    

    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()
    

    但在 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()
    

    在 Python 3.3 之前,这些行 were also included in tracebacks

    要达到预期的结果,您可以在调用堆栈上查找第一帧,其文件名不是以&lt;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
    

    【讨论】:

      【解决方案2】:

      在 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
      

      输出:

      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
      

      你可以这样做:

      # 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)
      

      输出:

      C:\Users\user\Desktop\the_importer.py
      

      【讨论】:

        猜你喜欢
        • 2021-08-16
        • 2015-12-22
        • 1970-01-01
        • 2017-01-06
        • 2012-08-04
        • 2013-12-11
        • 2014-04-21
        • 2018-06-20
        • 2014-06-23
        相关资源
        最近更新 更多