我找不到如何将YAML文件中的变量添加到没有重复项的Python文件中的方法。
我使用Pelican — static sites generator。 It use .py
files for configuration。问题:
我尝试将配置转移到YAML文件→我遇到了这个问题。
main.py
:
"""First Python file."""
# [INFO] Using ruamel.yaml — superset of PyYAML:
# https://stackoverflow.com/a/38922434/5951529
import ruamel.yaml as yaml
SETTINGS_FILES = ["kira.yaml", "kristina.yaml"]
for setting_file in SETTINGS_FILES:
VARIABLES = yaml.safe_load(open(setting_file))
# [INFO] Convert Python dictionary to variables:
# https://stackoverflow.com/a/36059129/5951529
locals().update(VARIABLES)
# [INFO] View all variables:
# https://stackoverflow.com/a/633134/5951529
print(dir())
publishconf.py
:"""Second Python file."""
import ruamel.yaml as yaml
# [NOTE] Another value in list
SETTINGS_FILES = ["kira.yaml", "katya.yaml"]
for setting_file in SETTINGS_FILES:
VARIABLES = yaml.load(open(setting_file))
locals().update(VARIABLES)
print(dir())
kira.yaml
:DECISION: Saint Petersburg
kristina.yaml
:SPAIN: Marbella
katya.yaml
:BURIED: Novoshakhtinsk
DECISION
中的SPAIN
和main.py
变量:$ python main.py
['DECISION', 'SETTINGS_FILES', 'SPAIN', 'VARIABLES', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__warningregistry__', 'setting_file', 'yaml']
DECISION
中的BURIED
和publishconf.py
变量:$ python publishconf.py
['BURIED', 'DECISION', 'SETTINGS_FILES', 'VARIABLES', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__warningregistry__', 'setting_file', 'yaml']
main.py
和publishconf.py
中的重复循环:
for setting_file in SETTINGS_FILES:
VARIABLES = yaml.load(open(setting_file))
locals().update(VARIABLES)
我不能使用重复项吗?
config.py
:
"""Config Python file."""
# [INFO] Using ruamel.yaml — superset of PyYAML:
# https://stackoverflow.com/a/38922434/5951529
import ruamel.yaml as yaml
MAIN_CONFIG = ["kira.yaml", "kristina.yaml"]
PUBLISHCONF_CONFIG = ["kira.yaml", "katya.yaml"]
def kirafunction(pelicanplugins):
"""Function for both Python files."""
for setting_file in pelicanplugins:
# [INFO] Convert Python dictionary to variables:
# https://stackoverflow.com/a/36059129/5951529
variables = yaml.safe_load(open(setting_file))
globals().update(variables)
def main_function():
"""For main.py."""
kirafunction(MAIN_CONFIG)
def publishconf_function():
"""For publishconf.py."""
kirafunction(PUBLISHCONF_CONFIG)
main.py
:"""First Python file."""
import sys
from config import main_function
sys.path.append(".")
main_function()
# [INFO] View all variables:
# https://stackoverflow.com/a/633134/5951529
print(dir())
publishconf.py
:"""Second Python file."""
import sys
from config import publishconf_function
sys.path.append(".")
publishconf_function()
print(dir())
main_function
和publishconf_function
中的变量不会在文件之间共享:
$ python main.py
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'main_function', 'signal', 'sys']
将循环包装为以下示例:
def kirafunction():
"""Docstring."""
for setting_file in SETTINGS_FILES:
VARIABLES = yaml.safe_load(open(setting_file))
locals().update(VARIABLES)
kirafunction()
答案 0 :(得分:1)
我会避免对locals
返回的内容进行任何更新,因为文档明确指出:
注意 该字典的内容不得修改;更改可能不会影响解释器使用的局部变量和自由变量的值。
globals函数是仅包含模块属性的字典,并且globals
返回的映射确实是可写的。
因此,如果它存在于一个Python源代码中:
def kirafunction(map,settings):
# [NOTE] Another value in list
for setting_file in settings:
VARIABLES = yaml.load(open(setting_file))
map.update(VARIABLES)
导入以上函数后,可以从任何其他Python来源中使用它:
kirafunction(globals(), settings)
并将变量导入到调用模块的全局字典中。而且将是高度非Python的...
稍微有点Python化的方式是,专用于一个Python模块来保存加载yaml文件的代码和新变量:
loader.py:
import ruamel.yaml as yaml
SETTINGS_FILES = ["kira.yaml", "kristina.yaml"]
for setting_file in SETTINGS_FILES:
VARIABLES = yaml.safe_load(open(setting_file))
# [INFO] Convert Python dictionary to variables:
# https://stackoverflow.com/a/36059129/5951529
globals().update(VARIABLES)
然后在您可以使用的任何其他Python模块中使用
:...
import loader # assuming that it is in sys.path...
...
print(loader.DECISION)
print(dir(loader))
但这仍然不常见,需要评论以解释其理由。
阅读您评论中的Pelican配置示例后,我假设您需要的是一种在不同脚本中导入yaml文件中声明的一堆变量的方法。在那种情况下,我会将加载变量的代码放在一个模块中,并在其他模块中更新globals()
字典:
loader.py:
import ruamel.yaml as yaml
MAIN_CONFIG = ["kira.yaml", "kristina.yaml"]
PUBLISHCONF_CONFIG = ["kira.yaml", "katya.yaml"]
def kirafunction(pelicanplugins):
"""Function for both Python files."""
variables = {}
for setting_file in pelicanplugins:
# [INFO] Convert Python dictionary to variables:
# https://stackoverflow.com/a/36059129/5951529
variables.update(yaml.safe_load(open(setting_file)))
return variables
然后例如在publishconf.py
中,您将使用:
from loader import kirafunction, PUBLISHCONF_CONFIG as pelican_config
# other Python code...
# import variables from the yaml files defined in PUBLISHCONF_CONFIG
# because Pelican expects them as plain Python module variables
globals().update(kirafunction(pelican_config))
再次,在此用例中更新globals()
可能是适当的,但通常对此不予理,,因此发表评论。