在Python解释器中从特定文件路径调用.py脚本

5
我刚开始学习Python。当我在Python交互模式下使用命令行时,如何从C:\ X \ Y \ Z目录调用测试脚本?当文件不在当前工作目录中时,如何指定文件的完整路径?
我可以使用Windows运行命令“python -i c:\ X \ Y \ Z \ filename.py”调用测试脚本,并且它可以正常运行。但是我希望能够从Python终端调用它,使用“>>>”提示符。
(我搜索了两个小时,但找不到答案,尽管这似乎是初学者的常见问题和易于解决的事情。)
谢谢
5个回答

3

由于您在文件路径中使用反斜杠,Python会将其解释为“转义字符”。在Python中编写文件路径时,请确保使用正斜杠。

with open("C:/X/Y/Z/filename.py", "r") as file:
    exec(file.read())

双斜杠也可以使用,但我更喜欢正斜杠的清晰外观。


2
如果您想将其导入到REPL中:
import sys
sys.path.append('c:\X\Y\Z')
import filename

1

执行它

Python 2.x:

execfile("C:\\X\Y\\Z")

Python 3+:

with open("C:\\X\Y\\Z", "r") as f:
    exec(f.read())

然而,这是非常糟糕的做法 - 它从字符串中执行代码(在某个时候),而不是使用首选和更安全的导入模块的方式。当您导入模块,并且在“-f __name__ == '__main__'”之后有一些代码时,那些部分将无法工作(因为导入的模块中的__name__不是__main__,如果您将其作为单个脚本运行,则会出现该情况)。

出于许多原因,这是不好的,某种程度上与 Python 之禅密切相关,但如果您是初学者,这应该对您有所启发:

当您在交互模式下执行任何操作时,您都在某个名称空间中工作(如果您不知道此术语,请在 Python 语言参考中查找)。当您执行 exec()/execfile() 而没有提供 globals()/locals() 时,您可能会得到修改后的命名空间。

修改后的命名空间?

这是什么意思?我们来看一个像这样的脚本:

radius = 3
def field_of_circle(r):
    return r*r*3.14
print(field_of_circle(radius))

现在,您有以下会话:
>>>radius = 5
>>>execfile("script_above.py")
28.26
>>>print(radius)
3

你看到发生了什么吗?在交互式会话中由您定义的变量将被脚本末尾的值覆盖。对于修改已导入的外部模块也是如此。让我们来看一个非常简单的模块:

x = 1

和执行的脚本:

import very_simple_module
very_simple_module.x = 3

现在,这是一个解释器交互会话:

>>>import very_simple_module
>>>print(very_simple_module.x)
1
>>>execfile("executed_script.py")
>>>print(very_simple_module.x)
3

运行另一个解释器

交互式会话非常有用,但对于运行Python脚本并不是最佳选择。

除非你想要使用Python shell作为系统shell。然后,你可以使用子进程(在标准库中)或sh(可以在PyPI上找到):

>>>import subprocess
>>>subprocess.call(["python", "C:\\X\Y\\Z"], shell=True)
>>>from sh import python
>>>python("C:\\X\Y\\Z")

如果要修改交互式解释器的命名空间,这些内容不会有问题。

将脚本视为模块

另外,还有一种选择:在交互式会话中添加带有脚本的目录到pythonpath,并导入命名为脚本的模块:

>>>import sys
>>>if "C:\\X\\Y" not in sys.path:
    sys.path.append("C:\\X\\Y")
>>>import Z

请记住,解释器启动时所在的目录自动添加到pythonpath中,因此如果您在与脚本相同的目录中运行python,则只需使用上面第三行的代码。

解释器的命名空间不会改变,但是在"-f __name__ == '__main__':"之后的代码将不会执行。仍然可以访问脚本变量:

>>>radius = 5
>>>import first_example_script
>>>print(radius)
5
>>>print(first_example_script.radius)
3

此外,你可能会遇到模块名称冲突的问题。例如,如果你的脚本名为sys.py,则此解决方案将无效,因为Python会先导入内置sys模块。

1

如果你正在使用IPython(而且你应该使用它,它比普通的交互式Python更有用),你可以使用魔术函数run(或者用%前缀:%run):

run C:\\X\\Y\\Z\\filename.py
%run C:\\X\\Y\\Z\\filename.py

点击此链接以获取有关魔术函数的更多信息。

顺便提一下,它甚至可以自动完成文件名。


1
如果您想在解释器中执行文件中的代码,可以使用execfile
execfile('C:/X/Y/Z/filename.py')

(/ 在所有操作系统中都作为路径分隔符,如果你使用 \,则需要对它们进行转义 ('C:\\X\\Y\\Z\\filename.py')或使用原始字符串字面值 (r'C:\X\Y\Z\filename.py'))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接