1

我试图找出在运行时可靠地发现py给定模块的文件在文件系统上的位置的最佳方法。我需要这样做,因为我计划将一些关于某些方法的配置数据外部化(在这种情况下,用于验证来自模块中定义的接口的服务调用的响应的模式)以保持清洁和易于维护。

系统的简化说明:

package
|
|-service.py
|
|-call1.scm
|
|-call2.scm

service.py (_call()是基类上的一个方法,尽管这与问题无关)

class FooServ(AbstractService):
    def call1(*args):
        result = self._call('/relative/uri/call1', *args)
        # additional call specific processing
        return result
    def call2(*args):
        result = self._call('/relative/uri/call2', *args)
        # additional call specific processing
        return result

call1.scm 和 call2.scm 定义响应模式(在当前情况下,使用草案 JSON 模式格式,但同样与问题无关)

在代码库的另一个地方,当实际进行服务调用时,我希望能够检测到的位置,service.py以便我可以遍历文件结构并找到 scm 文件。至少在我的系统上,我认为这会起作用:

# I realize this is contrived here, but in my code, the method is accessed this way
method = FooServ().call1
module_path = sys.modules[method.__self__.__class__.__module__].__file__
schema_path = os.path.join(os.path.dirname(module_path), method.__name__ + '.scm')

但是,我想确保这在所有平台和安装配置上都是安全的,我在进行研究时遇到了这个问题,这让我担心尝试以这种方式执行此操作不会可靠地工作。__file__这会普遍有效,还是模块对象返回文件位置的事实,该位置pyc可能位于文件旁边以外的某个位置py,这会使该解决方案无效?如果它会使其无效,我可以做什么,如果有的话?

4

1 回答 1

1

在您链接的PEP中,它说:

在 Python 3 中,当你导入一个模块时,它的 __file__ 属性指向它的源 py 文件(在 Python 2 中,它指向 pyc 文件)。

所以在 Python 3 中你很好,因为__file__它总是指向.py文件。在 Python 2 中,它可能指向该.pyc文件,但它.pyc只会与.pyPython 2 的文件位于同一目录中。


好的,我认为您指的是这一点:

由于这些发行版无法共享 pyc 文件,因此开发了复杂的机制来将生成的 pyc 文件放在非共享位置,同时仍共享源代码。示例包括基于符号链接的 Debian 制度 python-support [8] 和 python-central [9]。这些方法使得将 Python 应用程序交付给广泛的用户的策略变得更加复杂、脆弱、难以理解和碎片化。

我相信这些机制仅适用于发行版打包的 Python 模块。我认为它们不应该影响在发行版的打包系统之外手动安装的模块。为该发行版打包您的模块的人有责任确保该模块不会被该机制破坏。

于 2012-12-19T19:35:49.493 回答