Rumah >pembangunan bahagian belakang >Tutorial Python >Ke Arah Fail Konfigurasi Python yang Mudah Versi 3

Ke Arah Fail Konfigurasi Python yang Mudah Versi 3

Barbara Streisand
Barbara Streisandasal
2024-12-20 14:26:16349semak imbas

pengenalan

Ini adalah artikel terakhir dalam siri ini. Pelaksanaan ini bertujuan untuk memperbaiki kelemahan utama kod plat dandang yang saya terangkan dalam artikel sebelumnya. Saya memanggil pelaksanaan ini kelas sifat dinamik.

Perwakilan Kelas

Rajah kelas berikut menunjukkan kelas boleh guna semula DynamicConfiguration dan struktur data sokongan yang diperlukan untuk pembangun menggunakan fungsi ini. Ia masih menyediakan semua fungsi asas versi 2 termasuk pengikat but auto, penciptaan bahagian yang hilang dan nilai utama.

Towards Effortless Python Configuration Files Version 3

Penerangan Kod Pembangun

Saya akan membentangkan kod sumber penuh untuk aplikasi yang ingin menggunakan kelas ini. Saya menggunakan sifat-sifat terdahulu yang telah kita bincangkan dalam 3 artikel sebelum ini.

from codeallybasic.DynamicConfiguration import DynamicConfiguration
from codeallybasic.DynamicConfiguration import KeyName
from codeallybasic.DynamicConfiguration import SectionName
from codeallybasic.DynamicConfiguration import Sections
from codeallybasic.DynamicConfiguration import ValueDescription
from codeallybasic.DynamicConfiguration import ValueDescriptions
from codeallybasic.SecureConversions import SecureConversions

from codeallybasic.SingletonV3 import SingletonV3

from ByteSizedPython.ImpostorEnumByName import ImpostorEnumByName
from ByteSizedPython.PhoneyEnumByValue import PhoneyEnumByValue

LOGGER_NAME:       str = 'Tutorial'
BASE_FILE_NAME: str = 'config.ini'
MODULE_NAME:       str = 'version3properties'

DEFAULT_PHONEY_ENUM_BY_VALUE:  PhoneyEnumByValue  = PhoneyEnumByValue.FakeBrenda
DEFAULT_IMPOSTOR_ENUM_BY_NAME: ImpostorEnumByName = ImpostorEnumByName.High

GENERAL_PROPERTIES: ValueDescriptions = ValueDescriptions(
    {
        KeyName('debug'):    ValueDescription(defaultValue='False', deserializer=SecureConversions.secureBoolean),
        KeyName('logLevel'): ValueDescription(defaultValue='Info'),
        KeyName('phoneyEnumByValue'):  ValueDescription(defaultValue=DEFAULT_PHONEY_ENUM_BY_VALUE.value,  enumUseValue=True),
        KeyName('impostorEnumByName'): ValueDescription(defaultValue=DEFAULT_IMPOSTOR_ENUM_BY_NAME.name,  enumUseName=True),
    }
)

DATABASE_PROPERTIES: ValueDescriptions = ValueDescriptions(
    {
        KeyName('dbName'): ValueDescription(defaultValue='dbName'),
        KeyName('dbHost'): ValueDescription(defaultValue='localhost'),
        KeyName('dbPort'): ValueDescription(defaultValue='5342', deserializer=SecureConversions.secureInteger),
    }
)

CONFIGURATION_SECTIONS: Sections = Sections(
    {
        SectionName('General'):  GENERAL_PROPERTIES,
        SectionName('Database'): DATABASE_PROPERTIES,
    }
)

class ConfigurationPropertiesVersion3(DynamicConfiguration, metaclass=SingletonV3):
    def __init__(self):

        self._logger: Logger = getLogger(LOGGER_NAME)

        super().__init__(baseFileName=BASE_FILE_NAME, moduleName=MODULE_NAME, sections=CONFIGURATION_SECTIONS)

Baris 45-50 ialah kod yang perlu anda tulis. Pada asasnya, anda hanya memastikan bahawa anda lulus nama fail, nama modul dan bahagian konfigurasi. Jenis Bahagian ini berasal daripada modul DynamicConfiguration.

Baris 21-28 dan 30-36 ialah kamus ValueDescriptions. KeyName ialah harta dan menunjuk ke ValueDescription. Perhatikan bahawa penunjuk tentang cara untuk mengekalkan penghitungan dialihkan daripada penghias pelaksanaan sebelumnya kepada atribut boolean dalam ValueDescription.

Penerangan Kod Pelaksanaan

Jika anda melihat dengan teliti pada rajah kelas untuk DynamicConfiguration anda akan melihat bahawa ia melaksanakan dua kaedah sihir Python. Mereka ialah kaedah __getattr__(diri, nama)__ dan __setattr__(diri, nama, nilai)__.

  • __getattr__(diri, nama)__ Membenarkan pembangun mentakrifkan tingkah laku apabila pengguna kelas cuba mengakses atribut yang tidak wujud.
  • __setattr__(diri, nama, nilai)__ Membenarkan pembangun mentakrifkan gelagat untuk tugasan kepada atribut.

Berikut ialah kod untuk __getattr__. Ini kelihatan sangat mirip dengan penghias yang kami gunakan dalam versi 2. Kerja utama berlaku pada panggilan pada talian 14 kepada kaedah yang dilindungi _lookupKey(). Ia mengembalikan huraian penuh atribut supaya kita boleh mensimulasikan pengambilan semula atribut.

    def __getattr__(self, attrName: str) -> Any:
        """
        Does the work of retrieving the named attribute from the configuration parser

        Args:
            attrName:

        Returns:  The correctly typed value
        """

        self._logger.info(f'{attrName}')

        configParser: ConfigParser     = self._configParser
        result:       LookupResult     = self._lookupKey(searchKeyName=KeyName(attrName))
        valueDescription: ValueDescription = result.keyDescription

        valueStr: str = configParser.get(result.sectionName, attrName)

        if valueDescription.deserializer is not None:
            value: Any = valueDescription.deserializer(valueStr)
        else:
            value = valueStr

        return value

Berikut ialah pelaksanaan__setattr__(). Perhatikan sokongan untuk penghitungan dalam baris 22-27 dan ciri tulis lalu dalam baris 30.

    def __setattr__(self, key: str, value: Any):
        """
        Do the work of writing this back to the configuration/settings/preferences file
        Ignores protected and private variables uses by this class

        Does a "write through" to the backing configuration file (.ini)

        Args:
            key:    The property name
            value:  Its new value
        """

        if key.startswith(PROTECTED_PROPERTY_INDICATOR) or key.startswith(PRIVATE_PROPERTY_INDICATOR):
            super(DynamicConfiguration, self).__setattr__(key, value)
        else:
            self._logger.debug(f'Writing `{key}` with `{value}` to configuration file')

            configParser: ConfigParser  = self._configParser
            result:       LookupResult  = self._lookupKey(searchKeyName=KeyName(key))
            valueDescription: ValueDescription = result.keyDescription

            if valueDescription.enumUseValue is True:
                valueStr: str = value.value
                configParser.set(result.sectionName, key, valueStr)
            elif valueDescription.enumUseName is True:
                configParser.set(result.sectionName, key, value.name)
            else:
                configParser.set(result.sectionName, key, str(value))

            self.saveConfiguration()

Mengakses dan Mengubahsuai Sifat

Mengakses dan mengubah suai sifat adalah sama seperti dalam versi 2.

    basicConfig(level=INFO)

    config: ConfigurationPropertiesVersion2 = ConfigurationPropertiesVersion2()

    logger: Logger = getLogger(LOGGER_NAME)

    logger.info(f'{config.debug=}')
    logger.info(f'{config.logLevel=}')
    logger.info(f'{config.phoneyEnumByValue=}')
    logger.info(f'{config.impostorEnumByName=}')
    logger.info('Database Properties Follow')
    logger.info(f'{config.dbName=}')
    logger.info(f'{config.dbHost=}')
    logger.info(f'{config.dbPort=}')
    logger.info('Mutate Enumeration Properties')
    config.phoneyEnumByValue = PhoneyEnumByValue.TheWanderer
    logger.info(f'{config.phoneyEnumByValue=}')
    config.impostorEnumByName = ImpostorEnumByName.Low
    logger.info(f'{config.impostorEnumByName=}')

Coretan di atas menghasilkan output berikut.

INFO:Tutorial:config.debug='False'
INFO:Tutorial:config.logLevel='Info'
INFO:Tutorial:config.phoneyEnumByValue=<PhoneyEnumByValue.FakeBrenda: 'Faker Extraordinaire'>
INFO:Tutorial:config.impostorEnumByName='High'
INFO:Tutorial:Database Properties Follow
INFO:Tutorial:config.dbName='example_db'
INFO:Tutorial:config.dbHost='localhost'
INFO:Tutorial:config.dbPort=5432
INFO:Tutorial:Mutate Enumeration Properties
INFO:Tutorial:config.phoneyEnumByValue=<PhoneyEnumByValue.TheWanderer: 'The Wanderer'>
INFO:Tutorial:config.impostorEnumByName='Low'

Kesimpulan

Kod sumber untuk artikel ini ada di sini. Lihat kelas sokongan SingletonV3. Lihat pelaksanaan

Kelebihan

  • Taip mudah akses selamat kepada sifat aplikasi
  • Kelas induk boleh guna semula untuk pelaksanaan yang berbeza
  • Kod dipacu struktur data untuk menambah bahagian baharu dan kekunci konfigurasi
  • Tiada kod plat dandang untuk hartanah

Keburukan

  • Memandangkan tiada sifat sebenar yang dilaksanakan, kami tidak mendapat sokongan IDE untuknya
  • Selain itu, disebabkan kaedah carian untuk kunci, kunci yang berbeza dalam bahagian yang berbeza tidak boleh mempunyai nama yang sama

Atas ialah kandungan terperinci Ke Arah Fail Konfigurasi Python yang Mudah Versi 3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn