如何将文件“源”到python脚本中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36959031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to "source" file into python script
提问by Martin Vegter
I have a text file /etc/default/foo
which contains one line:
我有一个/etc/default/foo
包含一行的文本文件:
FOO="/path/to/foo"
In my python script, I need to reference the variable FOO.
在我的 python 脚本中,我需要引用变量 FOO。
What is the simplest way to "source" the file /etc/default/foo
into my python script, same as I would do in bash?
将文件“源”/etc/default/foo
到我的 python 脚本中的最简单方法是什么,就像我在 bash 中所做的那样?
. /etc/default/foo
回答by jil
You could use execfile:
你可以使用execfile:
execfile("/etc/default/foo")
But please be aware that this will evaluate the contents of the file as is into your program source. It is potential security hazard unless you can fully trust the source.
但请注意,这将按原样评估文件内容到您的程序源中。除非您可以完全信任来源,否则这是潜在的安全隐患。
It also means that the file needs to be valid python syntax (your given example file is).
这也意味着该文件需要是有效的 python 语法(您给定的示例文件是)。
回答by Hack-R
Same answer as @jil however, that answer is specific to some historical version of Python.
但是,与@jil 的答案相同,该答案特定于 Python 的某些历史版本。
In modern Python (3.x):
在现代 Python (3.x) 中:
exec(open('filename').read())
replaces execfile('filename')
from 2.x
execfile('filename')
从 2.x替换
回答by Foon
Just to give a different approach, note that if your original file is setup as
只是为了提供不同的方法,请注意,如果您的原始文件设置为
export FOO=/path/to/foo
You can do source /etc/default/foo; python myprogram.py
(or . /etc/default/foo; python myprogram.py
) and within myprogram.py
all the values that were exported in the sourced' file are visible in os.environ, e.g
您可以执行source /etc/default/foo; python myprogram.py
(或. /etc/default/foo; python myprogram.py
)并且在myprogram.py
源文件中导出的所有值在 os.environ 中可见,例如
import os
os.environ["FOO"]
回答by larsks
If you know for certainthat it only contains VAR="QUOTED STRING"
style variables, like this:
如果您确定它只包含VAR="QUOTED STRING"
样式变量,如下所示:
FOO="some value"
Then you can just do this:
然后你可以这样做:
>>> with open('foo.sysconfig') as fd:
... exec(fd.read())
Which gets you:
这让你:
>>> FOO
'some value'
(This is effectively the same thing as the execfile()
solution
suggested in the other answer.)
(这实际上与execfile()
另一个答案中建议的解决方案相同。)
This method has substantial security implications; if instead of FOO="some value"
your file contained:
这种方法具有重大的安全隐患;如果不是FOO="some value"
您的文件包含:
os.system("rm -rf /")
Then you would be In Trouble.
那你就麻烦了。
Alternatively, you can do this:
或者,您可以这样做:
>>> with open('foo.sysconfig') as fd:
... settings = {var: shlex.split(value) for var, value in [line.split('=', 1) for line in fd]}
Which gets you a dictionary settings
that has:
这会为您提供一本字典settings
,其中包含:
>>> settings
{'FOO': ['some value']}
That settings = {...}
line is using a dictionary comprehension. You could accomplish the same thing in a few more lines with a for
loop and so forth.
该settings = {...}
行使用的是字典理解。你可以用for
循环等多行几行来完成同样的事情。
And of course if the file contains shell-style variable expansion like ${somevar:-value_if_not_set}
then this isn't going to work (unless you write your very own shell style variable parser).
当然,如果文件包含 shell 样式的变量扩展,${somevar:-value_if_not_set}
那么这将不起作用(除非您编写自己的 shell 样式变量解析器)。
回答by Harlin
Keep in mind that if you have a "text" file with this content that has a .py as the file extension, you can always do:
请记住,如果您有一个包含 .py 作为文件扩展名的内容的“文本”文件,您可以随时执行以下操作:
import mytextfile
print(mytestfile.FOO)
Of course, this assumes that the text file is syntactically correct as far as Python is concerned. On a project I worked on we did something similar to this. Turned some text files into Python files. Wacky but maybe worth consideration.
当然,这假设文本文件就 Python 而言在语法上是正确的。在我参与的一个项目中,我们做了类似的事情。将一些文本文件转换为 Python 文件。古怪但也许值得考虑。
回答by Ascam
There are a couple ways to do this sort of thing.
有几种方法可以做这种事情。
You can indeed
import
the file as a module, as long as the data it contains corresponds to python's syntax. But either the file in question is a.py
in the same directory as your script, either you're to useimp
(orimportlib
, depending on your version) like here.Another solution (that has my preference) can be to use a data format that any python library can parse (JSON comes to my mind as an example).
您确实可以
import
将文件作为模块,只要它包含的数据对应于 python 的语法。但是,要么有问题的文件.py
与您的脚本位于同一目录中,要么您要使用imp
(或importlib
,取决于您的版本),就像这里。另一种解决方案(有我的偏好)可以是使用任何 python 库都可以解析的数据格式(以 JSON 为例)。
/etc/default/foo :
/etc/default/foo :
{"FOO":"path/to/foo"}
And in your python code :
在你的 python 代码中:
import json
with open('/etc/default/foo') as file:
data = json.load(file)
FOO = data["FOO"]
## ...
file.close()
This way, you don't risk to execute some uncertain code...
这样,您就不会冒险执行一些不确定的代码......
You have the choice, depending on what you prefer. If your data file is auto-generated by some script, it might be easier to keep a simple syntax like FOO="path/to/foo"
and use imp
.
你有选择,取决于你喜欢什么。如果您的数据文件被一些脚本自动生成的,它可能是更容易保持一个简单的语法喜欢FOO="path/to/foo"
和使用imp
。
Hope that it helps !
希望它有帮助!
回答by Hai Vu
The Solution
解决方案
Here is my approach: parse the bash file myself and process only variable assignment lines such as:
这是我的方法:自己解析 bash 文件并仅处理变量赋值行,例如:
FOO="/path/to/foo"
Here is the code:
这是代码:
import shlex
def parse_shell_var(line):
"""
Parse such lines as:
FOO="My variable foo"
:return: a tuple of var name and var value, such as
('FOO', 'My variable foo')
"""
return shlex.split(line, posix=True)[0].split('=', 1)
if __name__ == '__main__':
with open('shell_vars.sh') as f:
shell_vars = dict(parse_shell_var(line) for line in f if '=' in line)
print(shell_vars)
How It Works
这个怎么运作
Take a look at this snippet:
看看这个片段:
shell_vars = dict(parse_shell_var(line) for line in f if '=' in line)
This line iterates through the lines in the shell script, only process those lines that has the equal sign (not a fool-proof way to detect variable assignment, but the simplest). Next, run those lines into the function parse_shell_var
which uses shlex.split
to correctly handle the quotes (or the lack thereof). Finally, the pieces are assembled into a dictionary. The output of this script is:
此行遍历 shell 脚本中的行,仅处理具有等号的行(不是检测变量分配的万无一失的方法,而是最简单的方法)。接下来,将这些行运行到用于正确处理引号(或缺少引号)的函数parse_shell_var
中shlex.split
。最后,这些片段被组装成字典。这个脚本的输出是:
{'MOO': '/dont/have/a/cow', 'FOO': 'my variable foo', 'BAR': 'My variable bar'}
Here is the contents of shell_vars.sh:
这是shell_vars.sh的内容:
FOO='my variable foo'
BAR="My variable bar"
MOO=/dont/have/a/cow
echo $FOO
Discussion
讨论
This approach has a couple of advantages:
这种方法有几个优点:
- It does not execute the shell (either in bash or in Python), which avoids any side-effect
- Consequently, it is safe to use, even if the origin of the shell script is unknown
- It correctly handles values with or without quotes
- 它不执行 shell(在 bash 或 Python 中),从而避免了任何副作用
- 因此,即使 shell 脚本的来源未知,也可以安全使用
- 它正确处理带或不带引号的值
This approach is not perfect, it has a few limitations:
这种方法并不完美,它有一些局限性:
- The method of detecting variable assignment (by looking for the presence of the equal sign) is primitive and not accurate. There are ways to better detect these lines but that is the topic for another day
It does not correctly parse values which are built upon other variables or commands. That means, it will fail for lines such as:
FOO=$BAR FOO=$(pwd)
- 检测变量赋值的方法(通过寻找等号的存在)是原始的并且不准确。有一些方法可以更好地检测这些线条,但这是另一天的主题
它不能正确解析基于其他变量或命令的值。这意味着,对于以下行,它将失败:
FOO=$BAR FOO=$(pwd)