Я пишу еще один «велосипед» для чтения файлов .ini, чтобы получить опыт работы с продвинутыми Python и ООП. Также я нахожу стиль доступа Python для configparser по умолчанию немного неприятным для глаз, то есть: something = config['section']['parameter']
вместо большего количества очарования something = config.section.parameter
.
Я закончил с этим дизайном:
ConfigStorage
объект для хранения пар параметр / значение в качестве словаря;
Config
объект для управления данными в объекте хранения.
__getattribute__
в Config
объект переопределен, поэтому я могу получить доступ к значениям в ConfigStorage
словаре по имени атрибута Config
объекта ( цель! ).
Система работает нормально, когда существует только один экземпляр объекта Config
. Когда я попытался работать с несколькими конфигами (и, следовательно, создать новые Config
объекты для управления ими), я понял, что ConfigStorage
- это один для всех .
Я пытался создать новый экземпляр ConfigStorage
для каждого Config
объекта, но Python достигает максимальной глубины рекурсии в этом коде ( почему? ):
class _ConfigStorage(object):
def __init__(self):
self.config = dict()
class Config(object):
def __getattribute__(self, name):
if name in self.c.config:
return self.c.config[name]
else:
raise AttributeError("No parameter named [%s]" % name)
def __init__(self, file):
self.c = _ConfigStorage()
with open(file, 'r') as f:
for config_line in f:
key = # getting key from line
value = # getting value
self.c.config[key] = value
Наконец, мой код заработал, но я нахожу это решение очень грубым и испорченным черной магией. Я разделяю данные в объекте хранения, добавляя к ключу словаря строковое представление Config
ID объекта. Объект ConfigStorage
все еще один.
Также необходим метод __del__
, так как GC не знает о ненужных данных в хранилище, и я должен удалить их вручную. Это отстой.
class _ConfigStorage(object):
config = dict()
class Config(object):
def __getattribute__(self, name):
key = str(id(self)) + name
if key in _ConfigStorage.config:
return _ConfigStorage.config[key]
else:
raise AttributeError("No parameter named [%s]" % name)
def __init__(self, file):
with open(file, 'r') as f:
for config_line in f:
key = str(id(self) + # getting key from line
value = # getting value
_ConfigStorage.config[key] = value
def __del__(self):
instance_id = str(id(self))
keys_to_delete = []
for key in _ConfigStorage.config:
if instance_id in key:
keys_to_delete.append(key)
for key_to_delete in keys_to_delete:
del _ConfigStorage.config[key_to_delete]
Как улучшить дизайн, получив доступ к данным словаря по атрибуту объекта?