我正在尝试找出在运行时可靠地发现给定模块的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
文件旁边的某个位置,使这个解决方案无效?如果它会使它无效,那么我可以做什么呢?
答案 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模块。我不认为它们应该影响在分发包装系统之外手动安装的模块。无论是谁为您的分发包装模块,都要负责确保模块不会被机制破坏。