获取模块的py文件路径的可靠方法

时间:2012-12-19 19:10:43

标签: python cross-platform relative-path file-location

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

系统的简化插图:

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

但是,我想确保这在所有平台和安装配置上都是安全的,我在进行研究时遇到了this,这使我担心尝试以这种方式执行此操作将无法可靠地运行。这是否普遍适用,或者模块对象上的__file__返回pyc文件的位置,该文​​件可能位于py文件旁边的某个位置,使这个解决方案无效?如果它会使它无效,那么我可以做什么呢?

1 个答案:

答案 0 :(得分:1)

在您链接的PEP中,它说:

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

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


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

由于这些发行版不能共享pyc文件,因此开发了精心设计的机制,以便在源代码仍然共享的同时将生成的pyc文件放在非共享位置。例子包括基于符号链接的Debian方案python-support [8]和python-central [9]。这些方法为将Python应用程序交付给广泛的用户提供了更加复杂,脆弱,不可理解和分散的策略。

我相信这些机制仅适用于由发行版打包的Python模块。我不认为它们应该影响在分发包装系统之外手动安装的模块。无论是谁为您的分发包装模块,都要负责确保模块不会被机制破坏。