目前,我有一个Python文件,其中包含多个类,每个类在其构造函数中都接受5-10个参数。
每次我想更改这些参数的默认值时,我都需要遍历整个文件来查找那些构造函数,并手动修改它们,这并不太复杂,但有时会有点混乱。
我想知道是否有任何方法为它编写一个人类可读的配置文件,以便我可以直接修改这个配置文件中的一些条目来更改相应的默认参数?我该怎么做?
谢谢!
发布于 2015-11-29 19:24:20
您可以以任何格式编写配置文件。
Python提供了对JSON、XML和类似于传统分段配置文件(configparser)的格式的支持。所有这些格式都支持嵌套结构(最后一种方式稍微不太有用)。
许多Python项目选择的另一个选项是在Python本身中编写配置文件。实际上,Python字典看起来几乎像JSON,所以即使是对不太熟悉Python的人来说,它也应该很容易读和写。然后可以加载该文件并对其进行动态评估,这意味着您还可以使用诸如检索环境变量、递归加载其他文件或使用方便的函数(如os.path.whatever )等高级工具。如果您不希望执行这种“不受信任”的代码,请查看ast.literal_eval。
无论您选择什么格式,您都应该编写一个小的config模块,它提供一个函数来检索给定一个键的配置值。键可以是一个类似于module.submodule.class.parameter的字符串,它被函数分解成几个部分,用于在配置文件的层次结构中查找条目。最好将配置加载到内存中的数据结构中,然后处理来自该结构的所有请求。您可以在第一次调用函数时延迟加载。
发布于 2015-11-29 19:16:24
我的建议应该被看作是一种意见,而不是知识(这让我怀疑这个职位对此有多适合)。
如果您已经有了一个应用程序,最简单的也是我最喜欢的方法是以KEY=VALUE格式以纯文本形式存储配置文件。在我看来,这是最简单和最干净的方法。纯文本在任何地方都是可以理解的(而不是一些qwerky格式),而且KEY=VALUE非常容易单独阅读和理解。
举个例子:
port=443
host=localhost
proxy=127.0.0.1您可以使用特定的名称(.NAME格式将其隐藏在特定的操作系统上)将其存储在当前的工作目录中。
在这一点上,解析内容是相当直接的,这取决于应用程序的结构。
with open('filename') as config_file:
config_entries = config_file.readlines()
for line in config_entries:
pair = line.split('=')
key = pair[0]
val = pair[1]从本质上说,大多数元数据都是与代码的其余部分脱耦合的,这使得将来的维护和更新非常容易。
当然,这是一种简单的方法,您可以选择(如@Mark所建议的)使用结构解析器,但我认为它增加了一个额外的复杂性层,在大多数情况下可以很容易地避免。
(1)未进行代码测试。
发布于 2021-11-04 13:59:17
关于用Python编写配置类的最佳方法,已经有了很多讨论。我更喜欢使用基于classutilities包(pip install classutilities)的类,参见https://pypi.org/project/classutilities/的文档。
这个包迫使您遵循PEP8 (常量类变量的大写名称,没有类实例和方法等)。并强制该类作为“静态”类(在Java/C#已知的逻辑中)。
本地和生产堆栈的配置示例:
# File base_config.py
from classutilities import ConfigClassMixin, classproperty
class ConfigBase(ConfigClassMixin):
"""Base configuration options for all stacks"""
PGSQL_HOST: str
PGSQL_USER: str
PGSQL_PASS: str
PGSQL_PORT: int
PGSQL_DATABASE: str
CORS_ORIGINS: list[str]
@classproperty
def DB_CONNECTION(cls):
"""Create database connection."""
return ...本地配置文件可以如下所示:
# File config_local.py
from .config_base import ConfigBase
class ConfigLocal(ConfigBase):
"""Local stack configuration"""
PGSQL_HOST: str = "database"
PGSQL_USER: str = "whoever"
PGSQL_PASS: str = "..."
PGSQL_PORT: int = 5432
PGSQL_DATABASE: str = "whatever"
CORS_ORIGINS: list[str] = ["*"]生产堆栈可能会使用环境变量初始化大多数变量(但在技术上是相同的)。
然后,您可以根据__init__.py文件中的环境变量(定义您想要的堆栈)轻松地选择堆栈配置(考虑到整个配置构造都在一个配置子包中)。例如:
# File __init__.py
import os
from .config_base import ConfigBase
from .config_local import ConfigLocal
from .config_production import ConfigProduction
# Get the stack definition
stack: str = os.getenv("ENVIRONMENT", "local")
# Select correct configuration
CONFIG: type[ConfigBase] = ConfigLocal
if stack == "local":
CONFIG: type[ConfigBase] = ConfigLocal
elif stack == "production":
CONFIG: type[ConfigBase] = ConfigProduction
# other options here (typically 'production')
else:
raise RuntimeError("Wrong stack name")然后,可以通过从子包导入变量CONFIG来使用您的配置。例如:
from whatever.config import CONFIG
# ...
# To access configuration variables/properties:
CONFIG.DB_CONNECTION.query(...)我认为这是处理配置问题的最干净的方法。
https://stackoverflow.com/questions/33986750
复制相似问题