Python中的应用程序配置文件

时间:2018-10-19 17:05:08

标签: python class

我正在设计一个多租户工作负载自动化软件(可自动运行Jobs的软件)。为此,我正在创建一个默认的Job配置类。默认情况下,此类中指定的配置将应用于所有类型的作业。

租户(乔布斯的所有者)可以选择针对其特定类别的乔布斯覆盖这些默认配置。

例如:

# Default configurations for all types of Jobs
class DefaultConfigurations:

    def __init__(self, job_defintion):
        self.job_state_database = DEFAULT_DB
        self.job_definition_repository_type = DEFAULT_REPO
        .... 
        # there will be 100's of configurations like this. 

现在,如果某些租户想要为其特定类型的作业覆盖默认的应用程序配置,则他们可以继承DefaultConfiguration类并覆盖其想要覆盖的配置。

例如:

# These overridden configurations will be applied to all the HiveJobs.
class HiveJobs(DefaultConfigurations):

     def __init__(self, job_definition):
        self.job_state_database = "sql"
        self.job_definition_repository_type = "svn"

# These overridden configurations will be applied to all the SparkJobs.
class SparkJobs(DefaultConfigurations):

     def __init__(self, job_definition):
        self.job_state_database = "MongoDb"   
        if (job_definition.technology == "Old")
            self.job_state_database = "sql"  

对于所有其他类型的作业,将使用默认配置。

单个作业也有其定义(以XML形式提及)。在单个作业定义XML文件中,还指定了作业类。例如,Hive Job将在其定义中将其类指定为“ hive”。

其中一个配置单元作业的job_definition文件示例:

<job_definition>

    name hello_world_from_hive
    class hive
    command echo "hello world from Hive"

    cron_schedule 5 4 * * * 

</job_defintion>

在运行时,Job Executor将检查其定义文件中指定的Job类,并相应地选择配置类(例如,上例中的DefaultConfigurations,HiveJobs或SparkJobs)。

作业执行程序将从XML文件构造一个job_definition对象,并将该Job定义对象传递给相应的配置类,以获取执行此作业所需的最终配置。这是必需的,因此也可以基于某些运行时参数来添加/删除某些配置。请注意,首选项将优先于各个作业定义文件中覆盖的配置。

我不确定以上方法是否是用Python编写此类配置文件的最佳方法。

5 个答案:

答案 0 :(得分:4)

只需参数化__init__即可根据需要设置属性值。

class Configuration:
    def __init__(self, db, repo_type):
        self.job_state_database = db
        self.job_definition_repository_type = repo_type

d = Configuration(DEFAULT_DB, DEFAULT_REPO)
hj = Configuration("sql", "svn")

如果您不希望用户手动传递数据库和存储库类型,请定义用于包装它们的类方法。

class Configuration:
    def __init__(self, db, repo_type):
        self.job_state_database = db
        self.job_definition_repository_type = repo_type

    @classmethod
    def default_configuration(cls):
        return cls(DEFAULT_DB, DEFAULT_REPO)

    @classmethod
    def hive_configuration(cls):
        return cls("sql", "svn")


d = Configuration.default_configuration()
hj = Configuration.hive_configuration()

在这两种情况下,我都没有看到定义定义不同类型以反映存储在属性中的信息的任何理由。...除非使用不同类型 以不再需要显式存储数据库和存储库类型信息的方式覆盖各种方法。 (我们正在进入设计 但是,无法仅根据问题中的信息来判断问题。

class Configuration:
    def do_something(self):
        """Do stuff using the default database/repo"""

class HiveJob(Configuration):
    def do_something(self):
        """Do stuff using sql/svn instead"""

答案 1 :(得分:2)

  

我不确定以上方法是否是用Python编写此类配置文件的最佳方法。

如果不需要将配置配置为XML,则Python与json具有很好的集成,因此您可以在配置中使用json来代替xml。例如:

{
  "name": "hello_world_from_hive",
  "class": "hive",
  "command": "echo 'hello world from Hive'",
  "cron_schedule": "5 4 * * *"
}

然后,读取配置文件将很简单:

import json

with open('job_definition.json', 'r') as file:
  job_definition = json.load(file)

现在,job_definition是一个python对象,您可以正常访问它,例如:

job_definition['name']

如果需要XML,我建议使用解析器(例如etree或lxml),然后将其转换为python对象。

答案 2 :(得分:0)

我相信在python中存储此类信息的最自然的方法是使用字典。

它们不仅存储(键,值)对,而且还可以彼此覆盖,从而减轻了用户的继承负担。

# Default configurations for all types of Jobs
DefaultConfigurations = {
    'job_state_database':DEFAULT_DB,
    'job_definition_repository_type':DEFAULT_REPO,
    # there will be 100's of configurations like this.
}

# Specific configurations
def HiveJobs(technology):
    job_state_database = "MongoDb"
    if (technology == "Old")
       job_state_database = "sql"
    return {**DefaultConfigurations,
            **{'job_state_database':job_state_database,}}.


my_config = {**HiveJobs("Old"), 
             **{'my_custom_param':my_custom_value}}

答案 3 :(得分:0)

我认为最常用的配置方式是Python世界中的py文件。在flask和Django中,默认情况下它们使用py文件作为配置文件。

用户可以在py文件 config.py 中定义其配置,如下所示:

JOB_STATUS_DATABASE = 'sql'
JOB_REPOSOTIRY_TYPE = 'svn'
  1. 易于读写
  2. 您只需要告诉租户这些配置字段即可,他们无需关心您的实施细节。
  3. 一个作业类别的一个配置文件,例如:蜂巢作业的config_hive.py。

您可以看看flask.config moduledjango.conf.global_settings example

Flask配置模块还支持来自普通类的构造配置,这与您的方法类似。我认为,从py文件构造配置更加简单和愚蠢。用户可能不想继承您的配置类,并在他们的代码中写上self.balabla = xxxBLABLA = xxx很清楚并且足够。


您还可以看看YAML,似乎许多系统都在YAML文件中定义了它们的配置,例如:Kubernetes job config,travis-ci config等。

答案 4 :(得分:-1)

您可以使用ConfigParser,它非常易于使用,例如:

var items = ["aaa", "bbb", "ccc", "ddd"]
var s = "aaa bb"
var f = s.split(" ").every(st => {
  return items.filter(item => {
    return item.includes(st)
  }).length !== 0;
})
console.log(f)