正如上一篇文章所述,简单化版本充满了可扩展性、可维护性和可扩展性等问题。
版本 Ø 的一个简单扩展是尝试将 Python 配置详细信息隐藏在属性类后面。 这是实现一个伪数据类,它公开一组属性,允许开发人员简单地执行属性 set 和 get 调用来检索和保留属性值。
从维护者的角度来看,此实现应该支持以下功能。
下面的 UML 类图描述了一个满足简介中要求的类。 ConfiguratonProperties 类通过受保护的方法 .createMissingSections 和 .createMissingKeys
满足要求 1 和 2以下代码显示了实现。 请注意,其他部分需要对此方法进行代码更新
SECTION_GENERAL: str = 'General' SECTION_DATABASE: str = 'Database' def _createMissingSections(self): """ Create missing sections. Add additional calls for each defined section """ self._createMissingSection(SECTION_GENERAL) self._createMissingSection(SECTION_DATABASE)
缺失部分代码如下。
def _createMissingSection(self, sectionName: str): """ Only gets created if it is missing Args: sectionName: The potential section to create """ hasSection: bool = self._configParser.has_section(sectionName) self.logger.info(f'hasSection: {hasSection} - {sectionName}') if hasSection is False: self._configParser.add_section(sectionName)
以下代码显示了实现。 再次注意,如果我们添加额外的部分,开发人员必须为新部分添加额外的循环。
GENERAL_PREFERENCES: Dict[str, str] = { 'debug': 'False', 'logLevel': 'Info' } DATABASE_PREFERENCES: Dict[str, str] = { 'dbName': 'example_db', 'dbHost': 'localhost', 'dbPort': '5432' } def _createMissingKeys(self): """ Create missing keys and their values. Add additional calls for each defined section. """ for keyName, keyValue in GENERAL_PREFERENCES.items(): self._createMissingKey(sectionName=SECTION_GENERAL, keyName=keyName, defaultValue=keyValue) for keyName, keyValue in DATABASE_PREFERENCES.items(): self._createMissingKey(sectionName=SECTION_DATABASE, keyName=keyName, defaultValue=keyValue)
缺失的关键代码如下。 请注意,任何丢失的密钥都会立即保留。
def _createMissingKey(self, sectionName: str, keyName: str, defaultValue: str): """ Only gets created if it is missing. The configuration file is updated immediately for each missing key and its value Args: sectionName: The section name where the key resides keyName: The key name defaultValue: Itsß value """ if self._configParser.has_option(sectionName, keyName) is False: self._configParser.set(sectionName, keyName, defaultValue) self._saveConfiguration()
要求 3 的示例实现如下。
请注意,通过设置属性并立即保留它,设置属性会写入到配置文件。 读取属性实际上是通读,因为我们如何立即写入设置属性。
@property def dbName(self) -> str: return self._configParser.get(SECTION_DATABASE, 'dbName') @dbName.setter def dbName(self, newValue: str): self._configParser.set(SECTION_DATABASE, 'dbName', newValue) self._saveConfiguration()
整数属性使用 .getint 方法来检索值。 设置属性时,开发人员必须手动将其转换为字符串。
@property def dbPort(self) -> int: return self._configParser.getint(SECTION_DATABASE, 'dbPort') @dbPort.setter def dbPort(self, newValue: int): self._configParser.set(SECTION_DATABASE, 'dbPort', str(newValue)) self._saveConfiguration()
布尔属性使用 .getboolean 方法来检索它们的值。 设置属性时,开发人员必须手动将其转换为字符串。
SECTION_GENERAL: str = 'General' SECTION_DATABASE: str = 'Database' def _createMissingSections(self): """ Create missing sections. Add additional calls for each defined section """ self._createMissingSection(SECTION_GENERAL) self._createMissingSection(SECTION_DATABASE)
我不会在本文中介绍枚举属性。 有两种方法可以通过名称或值来保存它们。 每种机制都需要稍微不同的方式将值反序列化回枚举类型。
以下代码片段演示了如何访问和修改属性。
def _createMissingSection(self, sectionName: str): """ Only gets created if it is missing Args: sectionName: The potential section to create """ hasSection: bool = self._configParser.has_section(sectionName) self.logger.info(f'hasSection: {hasSection} - {sectionName}') if hasSection is False: self._configParser.add_section(sectionName)
上面的代码片段产生以下输出
GENERAL_PREFERENCES: Dict[str, str] = { 'debug': 'False', 'logLevel': 'Info' } DATABASE_PREFERENCES: Dict[str, str] = { 'dbName': 'example_db', 'dbHost': 'localhost', 'dbPort': '5432' } def _createMissingKeys(self): """ Create missing keys and their values. Add additional calls for each defined section. """ for keyName, keyValue in GENERAL_PREFERENCES.items(): self._createMissingKey(sectionName=SECTION_GENERAL, keyName=keyName, defaultValue=keyValue) for keyName, keyValue in DATABASE_PREFERENCES.items(): self._createMissingKey(sectionName=SECTION_DATABASE, keyName=keyName, defaultValue=keyValue)
本文的源代码在这里。 支持类SingletonV3在这里
实现的结果最初让我作为代码的使用者感到满意。 我能够获取和设置类型属性。 然而,作为代码的维护者,每当我添加新的部分和新的属性时,我都必须手动更新代码数据结构和代码循环。 此外,我真正从中得到的只是一种在不同应用程序中需要新配置属性时使用的机制/模式。
请参阅我的下一篇文章,其中记录了替代实现,以解决我列出的缺点,同时保留优点。
以上是迈向轻松的 Python 配置文件版本 1的详细内容。更多信息请关注PHP中文网其他相关文章!