【问题标题】:How to get the file path of a module from a function executed but not declared in it?如何从已执行但未在其中声明的函数中获取模块的文件路径?
【发布时间】:2012-10-30 10:33:08
【问题描述】:

如果我想要当前模块的路径,我会使用__file__

现在假设我想要一个函数来返回它。我做不到:

def get_path():
    return __file__

因为它会返回声明函数的模块的路径。

即使函数不是在模块的根目录调用而是在任何嵌套级别调用,我也需要它工作。

【问题讨论】:

  • 你想要的有点像欺骗常见的Python模块处理。也许你可以用不同的问题陈述你真正的问题,看看是否有一种更 Pythonic 的方式来做你真正想做的事情?
  • @e-satis 我很好奇,如果你只是将__file__ 传递给def get_path(path): return path 会不会有效?
  • @erikb85:感谢您的帮助,但在这种情况下,我完全知道自己想做什么,以及这样做的利弊。
  • @Kay Zhu:会的,但我的目的是创建一个速记,它不会很好,不得不这样做。

标签: python filepath


【解决方案1】:

我会这样做:

import sys

def get_path():
    namespace = sys._getframe(1).f_globals  # caller's globals
    return namespace.get('__file__')

【讨论】:

  • _getframe 是处理整个帧堆栈还是只选择它需要的一个?
  • 它只是将调用堆栈上的一帧返回给它的调用者。
  • 我应该说在这种情况下它只是回到一帧,因为1 参数被传递给它。
【解决方案2】:

在这种情况下从globals dict 获取它:

def get_path():
    return globals()['__file__']

根据评论进行编辑:给定以下文件:

# a.py
def get_path():
    return 'Path from a.py: ' + globals()['__file__']

# b.py
import a

def get_path():
    return 'Path from b.py: ' + globals()['__file__']

print get_path()
print a.get_path()

运行它会给我以下输出:

C:\workspace>python b.py
Path from b.py: b.py
Path from a.py: C:\workspace\a.py

在绝对/相对路径不同(为简洁起见,让我们省略)旁边,它对我来说看起来不错。

【讨论】:

  • 你试过了吗?这将给出与return __file__ 相同的结果。
  • 我得到了和朱凯一样的结果
  • 真的吗?给出了所述的确切代码?这似乎与Python docs 相矛盾。引用:返回一个表示当前全局符号表的字典。这始终是当前模块的字典(在函数或方法中,这是定义它的模块,而不是调用它的模块)(强调我的) .
  • @jro - 请再次阅读问题。 e-satis 查找调用模块的路径,而不是定义模块。
  • @Gil:知道了,谢谢。由于 e-satis 已经回答了他自己的问题,我将把它留给那些像我一样误解它的人:)。
【解决方案3】:

我找到了一种使用检查模块的方法。我对这个解决方案没意见,但是如果有人找到一种方法来做到这一点而不倾倒整个堆栈跟踪,它会更干净,我会感激地接受他的回答:

def get_path():
    frame, filename, line_number, function_name, lines, index =\
        inspect.getouterframes(inspect.currentframe())[1]
    return filename

【讨论】:

  • 啊,我想我现在明白了你的问题,感谢@Gil。另一种方法可能是致电traceback.extract_stack()[0][0]?
  • 一个稍微更简单的方法是使用def get_path(): return inspect.stack()[1][1],尽管这也会转储整个堆栈跟踪
  • @jro: extract_stack 是否也转储了整个堆栈跟踪?
  • @e-satis:你可以provide a limit来调用函数。我假设这阻止了进一步的跟踪,但我没有事实支持这一点。
猜你喜欢
  • 1970-01-01
  • 2014-10-07
  • 1970-01-01
  • 1970-01-01
  • 2022-08-10
  • 2018-09-28
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
相关资源
最近更新 更多