переменные в __setitem__ и __getitem__ class myName():
Хочу получить результат:
; передача значения в class myName()
myName['section_']['option_'] = 'value_'
; чтение значения из class myName()
myName['section_']['option_']
(словарь по факту не нужен, нужны имена section, option, и значение value, внутри класса,
далее все пойдет в ConfigParser)
Интуитивно понимаю как это должно работать, но почему-то не выходит.
Нашел пример, который работает со строками и записывает их в словарь, чуть поправил,
как мне вывести переменные уже в самом class myName()?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class myName:
def __init__(self):
self.dict_ = {}
def get(self):
return self.dict_
def __getitem__(self, *args):
if self.dict_.get(args[0]):
return self.dict_[args[0]]
else:
self.dict_[args[0]]={}
return self.dict_[args[0]]
def __setitem__(self, *args):
self.dict_[args[0]]=args[1]
return self.dict_[args[0]]
array = myName()
array['section_']['option_'] = 'value_'
print('...')
print(array['section_']['option_'])
print(array['section_'])
print(array.dict_)
print('...')
Интуитивно что-то такое:
class myName:
def __init__(self):
print('__init__')
def __getitem__(self, *arg):
print('__getitem__')
print(arg[0]) # выведет section_
print(arg[1]) # выведет option_
def __setitem__(self, *arg, val):
print('__setitem__')
print(arg[0]) # выведет section_
print(arg[1]) # выведет option_
print(val) # выведет value_
array = myName()
array['section_']['option_'] = 'value_'
print(array['section_']['option_'])
Вот так конечно реально вывести, но нужно как выше...
array['section_', 'option_'] = 'value_'
array['section_', 'option_']
Получится ли реализовать такой вариант?
class myName:
def __init__(self):
print('__init__')
self.section = None
self.option = None
self.value = None
def __iter__(self):
try:
self.iter += 1
except:
self.iter = 0
return self.iter
def __getitem__(self, *arg):
print('__getitem__')
try:
arg[0]
if self.__iter__ == 0: self.section = arg[0]
elif self.__iter__ == 1: self.option = arg[0]
self.__getitem__()
except:
self.iter = 0
if self.__iter__ == 0: print(self.section)
elif self.__iter__ == 1: print(self.section, self.option)
return self.value
объясните пожалуйста, как такое происходит:
class myName:
def __init__(self):
self.dict_ = {'sect1': {'opt1': 'val_1'}}
def __getitem__(self, *args):
print(args[0])
print(self.dict_[args[0]])
return self.dict_[args[0]]
array = myName()
print(array['sect1']['opt1'])
а на выводе:
sect1
{'opt1': 'val_1'}
val_1
почему при вызове self.dict_[args[0]] с помощью print результат один, а при помощи return другой?
Ответы (3 шт):
Так как dict является mutable структурой, то можно провернуть такое:
import json # Для красивого вывода
class MyDict(dict): # Наследуемся от dict
def __getitem__(self, item): # Переопределяем получение элемента через []
return self.setdefault(item, MyDict()) # Если значения по ключу нет,
# создаём ключ со значением=пустой MyDict()
# и возвращаем это значение
# иначе возвращается значение по ключу
if __name__ == '__main__':
cls = MyDict()
cls['section']['option'] = 'option_value'
cls['section']['tag'] = 'tag_value'
print(json.dumps(cls, indent=4, ensure_ascii=False))
print(cls['section']['option'])
Вывод:
{
"section": {
"option": "option_value",
"tag": "tag_value"
}
}
option_value
Если Вы хотите "упростить" работу с классом ConfigParser (автоматическое создание секций, если их нет), то можно сделать так:
from configparser import ConfigParser
class MyCfg(ConfigParser): # Создаём свой, "удобный" ConfigParser
def __getitem__(self, item): # Переопределяем получение секции через []
try:
return super(MyCfg, self).__getitem__(item) # Пытаемся вернуть из имеющихся
except KeyError: # Если секции нет
self.add_section(item) # Создаём её
return super(MyCfg, self).__getitem__(item) # И возвращаем
if __name__ == '__main__':
cfg = MyCfg()
cfg['section']['option'] = 'option_value'
cfg['section']['tag'] = 'tag_value'
cfg['another_section']['test'] = 'test_value'
with open('cfg.ini', 'w') as fp:
cfg.write(fp)
Вот что получилось в итоге:
from configparser import ConfigParser
class MyCfg(ConfigParser):
def __init__(self, file: str='cfg.ini'):
self.file = file
return super(MyCfg, self).__init__()
def __getitem__(self, item):
try:
return super(MyCfg, self).__getitem__(item)
except KeyError:
self.add_section(item)
return super(MyCfg, self).__getitem__(item)
def read(self):
return super(MyCfg, self).read(self.file)
def write(self):
with open(self.file, 'w') as fp:
return super(MyCfg, self).write(fp)
if __name__ == '__main__':
cfg = MyCfg('settings.ini')
cfg.read()
cfg['section']['option'] = 'option_value'
cfg['section']['tag'] = 'tag_value'
cfg['another_section']['test'] = 'test_value'
cfg.write()