Dalam artikel sebelumnya, kami berjaya mencipta kelas data sifat simulasi untuk mengurus nilai konfigurasi untuk aplikasi. Walau bagaimanapun, ia pada asasnya hanya templat yang perlu kami laksanakan semula untuk setiap penggunaan. Dalam versi 2, kerja saya, saya berjaya melaksanakan kelas boleh guna semula.
Rajah kelas berikut menunjukkan kelas asas boleh guna semula dan struktur data yang diperlukan untuk pembangun menggunakan fungsi ini.
Pembangun memulakan proses dengan mensubkelaskan Sifat Konfigurasi seperti berikut.
BASE_FILE_NAME: str = 'config.ini' MODULE_NAME: str = 'version2properties' class ConfigurationPropertiesVersion2(ConfigurationProperties, metaclass=SingletonV3): def __init__(self): self.logger: Logger = getLogger(LOGGER_NAME) super().__init__(baseFileName=BASE_FILE_NAME, moduleName=MODULE_NAME, sections=CONFIGURATION_SECTIONS) self._configParser.optionxform = self._toStr # type: ignore self._loadConfiguration()
Panggilan kepada super mencipta laluan yang layak sepenuhnya ke fail konfigurasi. Kod ini mengikuti subset Spesifikasi Direktori Pangkalan XDG. Kod mula-mula mencuba XDG_CONFIG_HOME, kemudian HOME, dan akhirnya menggunakan direktori semasa jika kedua-duanya gagal. Dalam baris 13, pembangun memanggil kaedah yang dilindungi untuk menyediakan penghurai konfigurasi. Selain itu, panggilan itu akan
Keupayaan sebelumnya menghasilkan banyak fail konfigurasi kod dan bootstraps yang boleh digunakan semula. Selain itu, kami menjadikan kelas sebagai Singleton untuk mengurangkan kos penciptaan sambil kami membuat instantiat merentasi pangkalan kod aplikasi kami.
Perhatikan bahagian parameter dalam panggilan super. Takrif bahagian ini kelihatan seperti ini:
from codeallybasic.ConfigurationProperties import Sections CONFIGURATION_SECTIONS: Sections = Sections( { SectionName('General'): SECTION_GENERAL, SectionName('Database'): SECTION_DATABASE, } )
Di atas ialah kamus yang kuncinya ialah nama bahagian dan nilainya ialah bahagian.
Bahagian hanyalah senarai entri ConfigurationNameValue. ConfigurationNameValue ialah kelas data dengan 2 nilai, PropertyName dan nilai lalainya. Berikut ialah bahagian kami.
from codeallybasic.ConfigurationProperties import Section from codeallybasic.ConfigurationProperties import ConfigurationNameValue from codeallybasic.ConfigurationProperties import PropertyName SECTION_GENERAL: Section = Section( [ ConfigurationNameValue(name=PropertyName('debug'), defaultValue='False'), ConfigurationNameValue(name=PropertyName('logLevel'), defaultValue='Info'), ConfigurationNameValue(name=PropertyName('phoneyEnumByValue'), defaultValue=DEFAULT_PHONEY_ENUM_BY_VALUE.value), ConfigurationNameValue(name=PropertyName('impostorEnumByName'), defaultValue=DEFAULT_IMPOSTOR_ENUM_BY_NAME.name), ] ) SECTION_DATABASE: Section = Section( [ ConfigurationNameValue(name=PropertyName('dbName'), defaultValue='example_db'), ConfigurationNameValue(name=PropertyName('dbHost'), defaultValue='localhost'), ConfigurationNameValue(name=PropertyName('dbPort'), defaultValue='5432'), ] )
Perhatikan bahawa saya telah menetapkan dua sifat penghitungan baharu. Satu yang kami ingin kekalkan ialah nilai dan satu lagi namanya.
Di sini terdapat takrifan penghitungan.
class PhoneyEnumByValue(Enum): TheWanderer = 'The Wanderer' Mentiroso = 'Mentiroso' FakeBrenda = 'Faker Extraordinaire' NotSet = 'Not Set' @classmethod def deSerialize(cls, value: str) -> 'PhoneyEnumByValue': @classmethod def deSerialize(cls, value: str) -> 'PhoneyEnumByValue': match value: case PhoneyEnumByValue.TheWanderer.value: phoneyEnum: PhoneyEnumByValue = PhoneyEnumByValue.TheWanderer case PhoneyEnumByValue.Mentiroso.value: phoneyEnum = PhoneyEnumByValue.Mentiroso case PhoneyEnumByValue.FakeBrenda.value: phoneyEnum = PhoneyEnumByValue.FakeBrenda case _: raise Exception('Unknown PhoneyEnumByValue') return phoneyEnum class ImpostorEnumByName(Enum): Low = 0.1 Medium = 0.5 High = 1.0 NotSet = -1.0
Kita akan melihat bagaimana ini mempengaruhi takrifan harta dalam kelas pembangun
Sifat rentetan ditakrifkan seperti berikut.
BASE_FILE_NAME: str = 'config.ini' MODULE_NAME: str = 'version2properties' class ConfigurationPropertiesVersion2(ConfigurationProperties, metaclass=SingletonV3): def __init__(self): self.logger: Logger = getLogger(LOGGER_NAME) super().__init__(baseFileName=BASE_FILE_NAME, moduleName=MODULE_NAME, sections=CONFIGURATION_SECTIONS) self._configParser.optionxform = self._toStr # type: ignore self._loadConfiguration()
Apa yang telah kami singkirkan ialah plat dandang untuk mengakses configParser untuk mendapatkan dan menetapkan nilai. Apa yang kami tambahkan ialah penghias configurationGetter dan configurationSetter. Saya tidak akan membincangkan butiran pelaksanaan penghias dan meninggalkan ini sebagai latihan untuk pembaca. Penghias ini menjaga interaksi dengan penghurai konfigurasi untuk mendapatkan dan menetapkan nilai. Semasa menetapkan nilai, penghias configurationSetter melakukan tulis-tembus.
Pembangun mentakrifkan sifat integer seperti berikut.
from codeallybasic.ConfigurationProperties import Sections CONFIGURATION_SECTIONS: Sections = Sections( { SectionName('General'): SECTION_GENERAL, SectionName('Database'): SECTION_DATABASE, } )
Perhatikan bahawa penghias configurationGetter mempunyai parameter pilihan. Ia ialah fungsi yang mengambil nilai sifat rentetan dan menukarnya kepada nilai ditaip yang sesuai sebelum kembali ke sifat pemanggil. Ini boleh digunakan pada sifat terapung.
Sifat penghitungan di mana kita ingin mengekalkan nama penghitungan ditakrifkan seperti berikut:
from codeallybasic.ConfigurationProperties import Section from codeallybasic.ConfigurationProperties import ConfigurationNameValue from codeallybasic.ConfigurationProperties import PropertyName SECTION_GENERAL: Section = Section( [ ConfigurationNameValue(name=PropertyName('debug'), defaultValue='False'), ConfigurationNameValue(name=PropertyName('logLevel'), defaultValue='Info'), ConfigurationNameValue(name=PropertyName('phoneyEnumByValue'), defaultValue=DEFAULT_PHONEY_ENUM_BY_VALUE.value), ConfigurationNameValue(name=PropertyName('impostorEnumByName'), defaultValue=DEFAULT_IMPOSTOR_ENUM_BY_NAME.name), ] ) SECTION_DATABASE: Section = Section( [ ConfigurationNameValue(name=PropertyName('dbName'), defaultValue='example_db'), ConfigurationNameValue(name=PropertyName('dbHost'), defaultValue='localhost'), ConfigurationNameValue(name=PropertyName('dbPort'), defaultValue='5432'), ] )
Selain menggunakan penghias yang sesuai ambil perhatian bahawa untuk mengekalkan nama penghitungan gunakan parameter enumUseName dan tetapkannya kepada Benar.
Berikut ialah sifat penghitungan yang mana pembangun ingin mengekalkan nilainya. Perhatikan bahawa penghias setter menunjukkan bahawa ia adalah penghitungan. Selain itu, maklum bahawa pembangun mesti menyediakan kaedah penyahserikatan yang boleh menukar nilai kepada nilai penghitungan tertentu.
class PhoneyEnumByValue(Enum): TheWanderer = 'The Wanderer' Mentiroso = 'Mentiroso' FakeBrenda = 'Faker Extraordinaire' NotSet = 'Not Set' @classmethod def deSerialize(cls, value: str) -> 'PhoneyEnumByValue': @classmethod def deSerialize(cls, value: str) -> 'PhoneyEnumByValue': match value: case PhoneyEnumByValue.TheWanderer.value: phoneyEnum: PhoneyEnumByValue = PhoneyEnumByValue.TheWanderer case PhoneyEnumByValue.Mentiroso.value: phoneyEnum = PhoneyEnumByValue.Mentiroso case PhoneyEnumByValue.FakeBrenda.value: phoneyEnum = PhoneyEnumByValue.FakeBrenda case _: raise Exception('Unknown PhoneyEnumByValue') return phoneyEnum class ImpostorEnumByName(Enum): Low = 0.1 Medium = 0.5 High = 1.0 NotSet = -1.0
Mengakses dan mengubah suai sifat adalah sama seperti dalam versi 1.
@property @configurationGetter(sectionName='General') def debug(self) -> str: return '' # never executed @debug.setter @configurationSetter(sectionName='General') def debug(self, newValue: str): pass
Coretan di atas menghasilkan output berikut.
@property @configurationGetter(sectionName='Database', deserializeFunction=int) def dbPort(self) -> int: return -1 @dbPort.setter @configurationSetter(sectionName='Database',) def dbPort(self, newValue: int): pass
Kod sumber untuk artikel ini ada di sini. Lihat kelas sokongan SingletonV3. Lihat pelaksanaan ConfigurationProperties
Hasil pelaksanaan membuatkan saya berpuas hati sebagai pengguna kod tersebut. Saya dapat mendapatkan dan menetapkan sifat yang ditaip. Ia tidak mengeluarkan kod sebanyak yang saya harapkan pada mulanya. Walau bagaimanapun, ia memberikan saya kod yang boleh diguna semula. Walau bagaimanapun, ia menggesa saya untuk menulis Templat Langsung dalam PyCharm untuk membolehkan saya menjana sifat individu.
Siaran seterusnya saya melaksanakan apa yang saya panggil sifat dinamik. Ia mengalih keluar sepenuhnya semua kod plat dandang dan masih mengekalkan kelebihan yang disebutkan di atas.
Atas ialah kandungan terperinci Ke Arah Fail Konfigurasi Python yang Mudah Versi 2. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!