简体   繁体   English

Python:来自其他文件工作目录的execfile?

[英]Python: execfile from other file's working directory?

I have some code that loads a default configuration file and then allows users to supply their own Python files as additional supplemental configuration or overrides of the defaults: 我有一些代码加载默认配置文件,然后允许用户提供自己的Python文件作为额外的补充配置或覆盖默认值:

# foo.py

def load(cfg_path=None):
    # load default configuration
    exec(default_config)

    # load user-specific configuration
    if cfg_path:
        execfile(cfg_path)

There is a problem, though: execfile() executes directives in the file specified by cfg_path as if it were in the working directory of foo.py , not its own working directory. 但是有一个问题: execfile()cfg_path指定的文件中执行指令,就好像它位于foo.py的工作目录中,而不是它自己的工作目录。 Thus, import directives might fail if the cfg_path file does, say, from m import x where m is a module in the same directory as cfg_path . 因此,如果cfg_path文件例如from m import x ,则import指令可能会失败,其中m是与cfg_path相同的目录中的cfg_path

How do I execfile() from the working directory of its argument, or otherwise achieve an equivalent result? 如何从其参数的工作目录中执行execfile() ,或以其他方式获得等效结果? Also, I've been told that execfile is deprecated in Python 3 and that I should be using exec , so if there's a better way that I should be doing this, I'm all ears. 另外,我被告知在Python 3中不推荐使用execfile ,而且我应该使用exec ,所以如果有更好的方法我应该这样做,我会全力以赴。

Note: I don't think solutions which merely change the working directory are correct. 注意:我认为仅仅改变工作目录的解决方案是正确的。 That won't put those modules on the interpreter's module-lookup path, as far as I can tell. 据我所知,这不会将这些模块放在解释器的模块查找路径上。

os.chdir lets you change the working directory as you wish (you can extract the working directory of cfg_path with os.path.dirname ); os.chdir允许您根据需要更改工作目录(可以使用os.path.dirname提取cfg_path的工作目录); be sure to first get the current directory with os.getcwd if you want to restore it when you're done exec'ing cfg_path . 如果你想在执行cfg_path时恢复它,请务必首先使用os.getcwd获取当前目录。

Python 3 does indeed remove execfile (in favor of a sequence where you read the file, compile the contents, then exec them), but you need not worry about that, if you're currently coding in Python 2.6, since the 2to3 source to source translation deals with all this smoothly and seamlessly. Python 3确实删除了execfile (支持你读取文件的序列, compile内容,然后exec它们),但你不必担心,如果你目前在Python 2.6编码,因为2to3源代码源代码翻译可以顺利无缝地处理所有这些。

Edit : the OP says, in a comment, that execfile launches a separate process and does not respect the current working directory. 编辑 :OP在评论中说, execfile启动一个单独的进程,并且不尊重当前的工作目录。 This is false, and here's an example showing that it is: 这是错误的,这是一个示例,表明它是:

import os

def makeascript(where):
  f = open(where, 'w')
  f.write('import os\nprint "Dir in file:", os.getcwd()\n')
  f.close()

def main():
  where = '/tmp/bah.py'
  makeascript(where)
  execfile(where)
  os.chdir('/tmp')
  execfile(where)

if __name__ == '__main__':
  main()

Running this on my machine produces output such as: 在我的机器上运行它会产生如下输出:

Dir in file: /Users/aleax/stko
Dir in file: /private/tmp

clearly showing that execfile does keep using the working directory that's set at the time execfile executes. 清楚地表明execfile 确实继续使用execfile执行时设置的工作目录。 (If the file executed changes the working directory, that will be reflected after execfile returns -- exactly because everything is taking place in the same process!). (如果执行的文件改变工作目录,会后反映execfile回报- !正是因为一切发生在同一个进程)。

So, whatever problems the OP is still observing are not tied to the current working directory (it's hard to diagnose what they may actually be, without seeing the code and the exact details of the observed problems;-). 因此,OP仍然观察到的任何问题都与当前工作目录无关 (很难诊断它们实际可能是什么,没有看到代码和观察到的问题的确切细节;-)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM