Python 使用不同的配置文件-应通过命令行参数作出决定

Python 使用不同的配置文件-应通过命令行参数作出决定,python,configuration,arguments,Python,Configuration,Arguments,我有一个脚本,它使用一个名为config.py的配置文件。实际上这是一个配置模块。总之:配置模块包含很多参数、字典和字典列表等等 在今天的脚本中,它是这样使用的 import config def main(): myParameter = config.myParameter 现在,我有了这个脚本的另一个应用程序场景,它使用了一个相关的配置('config_advanced.py',但是参数和字典有不同的值 现在,我的目标是选择所用配置模块的名称作为传递的命令行参数: myScr

我有一个脚本,它使用一个名为config.py的配置文件。实际上这是一个配置模块。总之:配置模块包含很多参数、字典和字典列表等等

在今天的脚本中,它是这样使用的

import config

def main(): 
    myParameter = config.myParameter
现在,我有了这个脚本的另一个应用程序场景,它使用了一个相关的配置('config_advanced.py',但是参数和字典有不同的值

现在,我的目标是选择所用配置模块的名称作为传递的命令行参数:

myScript.py -configuration config_advanced.py
由于配置模块与主脚本位于同一文件夹中,我想我必须首先将传递的配置文件重命名为'config.py'。然后我可以执行
import-config
。否则,如果我使用'import-config\u-advanced',我将无法使用像这样的调用

config.myParameter
在主脚本中

另一种可能是,将配置模块放在子文件夹中,并保留名称config.py。然后,传递的命令行参数必须包含子文件夹

无论哪种方式,我都无法在主文件的顶部执行导入,因为我必须首先进行参数解析。这在技术上不是问题,但有人说这至少是一个糟糕的做法

你觉得怎么样? 不费吹灰之力就能达到目的的更好方法是什么? 非常感谢


编辑:
一个有效的解决办法是:

import sys fullpath = "d:\\python\\scripts\\projectA\\configurationFiles\\" 
sys.path.append(fullpath) 
config = __import__('config_advanced')

如果没有syspath,它将无法工作,因此以下尝试将无法工作:

config = __import__('d:\\python\\scripts\\projectA\\configurationFiles\\config_advanced')
config = __import__('d:\\python\\scripts\\projectA\\configurationFiles\\config_advanced.py')

另一种可能性与您在问题中的建议类似,但不需要您将内容隐藏在子文件夹中,即将config_advanced.py和config_plain.py放在与主脚本相同的文件夹中,然后动态地将config.py设置为指向要使用的实际配置文件的链接

然而,马蒂诺的建议要简单得多

OTOH,georg提出了一个非常有效的观点,特别是如果这个脚本不仅仅是供您个人使用的话。虽然将Python本身用于配置数据是灵活和强大的,但它可能有点太强大了。配置数据应该是数据,而不是实时可执行代码。如果您在修改配置数据时犯了一个小错误,可能会导致voc,如果它在一个可执行文件中。如果一个恶意用户访问它,他们可能造成的损害是没有限制的

如果一个普通的旧数据文件中的坏数据做了一些你的配置解析代码没有怀疑到的奇怪的事情,那么它在最坏的情况下会导致ValueError。但是一个实时Python文件中的坏数据可能会抛出各种各样的严重错误。或者更糟糕的是,它可能会在完全沉默的情况下做坏事


为了回应您的评论,这里有一些代码来说明第一点:

#! /usr/bin/env python

import os

config_file = "config.py"

def link_config(mode):
    if os.path.exists(config_file):
        os.remove(config_file)

    config_name = "config_%s.py" % mode
    os.symlink(config_name, config_file)

#.... parse command line to determine config_mode string, then do
link_config(config_mode)

#Now import the newly-linked config file
import config
如果config_mode==“plain”,上述代码将导致将config_plain.py作为“config”导入

如果config_mode==“advanced”,则会导致将config_advanced.py作为“config”导入

但正如我之前所说的,martineau的方法要简单得多。而IIRC,
os.symlink
可能无法在非unix系统上工作


至于你的第二点,看看它必须是python吗?Json/yaml/ini会更容易(也更安全)使用。您可以使用内置函数按名称导入模块,并将结果命名为
config
。非常感谢。成功了!我必须先附加配置文件的路径。或者还有其他方法吗?这是我的解决方案:
import sys
fullpath=“d:\\python\\scripts\\a\\configurationFiles\\”
sys.path.append(fullpath)
config=\uuuu import\uuuu('config\u advanced')
很抱歉格式不正确。根据帮助,两个空格应该添加换行符:“用两个空格结束一行以添加换行符”.但我猜,我在这里做错了一些事情。很难阅读注释中的代码,也不可能正确缩进,因此请将其编辑到您的问题中。注释中的代码应限制为微小的片段。1.我不理解第一点;)-您的意思是,我应该先将文件写入config.py,因此config.py包含类似“import config_plain”的内容,然后是import config?2。配置应该只包含数据:对我来说似乎有效:)我不确定如何处理字典列表,我想,使用python模块作为配置将是最简单的方法。我以前从未使用过json,但它似乎与普通python字典非常相似。无论如何:在确认中只使用数据意味着我需要一些解析。所以我想我应该使用配置解析器模块?但是,如何使用配置解析器读取带有列表的json格式的字典列表呢?有什么例子吗?非常感谢你的澄清。我以前从未见过os.symlink。但我理解你的观点,那可能行不通。所以我实施了马蒂诺的方法。我希望我做得对:)