Какая структура данных подходит для хранения группы переменных - PullRequest
0 голосов
/ 20 июня 2020

Мне предоставлена ​​сторонняя функция mk_config, которая дает мне объекты в соответствии с (key, configs). Типичное использование: когда вам нужны некоторые из этих объектов, вы говорите

args = mk_config('args', **configs)
validator = mk_config('validator', **configs)
postproc = mk_config('postproc', **configs)

, а затем работаете с указанными объектами.

Поскольку мне не нравится видеть большие блоки шаблонов, я думаю, хорошо, может быть лучше следующее:

def mk_configs_tuple(keys, **configs):
    return [mk_config(k, **configs) for k in keys]

args, validator, postproc = mk_configs_tuple(
        ['args', 'validator', 'postproc'],
        **configs)

Но все же есть повторение имен клавиш, и если иметь дело с 20, это может выйти из-под контроля. Я мог бы ввести их в locals(), чтобы они были СУХИМИ, но большинство скажет, что это тоже dry, поэтому я думаю, что могу сделать это:

def mk_configs_dict(keys, **configs):
    return {k: mk_config(k, **configs) for k in keys}

m = mk_configs_dict(['args', 'validator', 'postproc'], **configs)
assert list(m) == ['args', 'validator', 'postproc']

Теперь словари работают быстро, но не всегда хорошо автопредлагает в среде IDE, и гораздо сложнее написать [''], чем . (как JSON). Итак, я думаю:

def mk_config_obj(keys, **configs):
    class ConfigObj: ...
    config_obj = ConfigObj()
    for key in keys:
        setattr(config_obj, key, mk_config(key, **configs))
    return config_obj

config_obj = mk_config_obj(['args', 'validator', 'postproc'], **configs)
assert {'args', 'validator', 'postproc'}.issubset(dir(config_obj))

Но потом я думаю, что если я не могу сделать это с тем, что python приходит естественно, я чего-то упускаю.

Ответы [ 4 ]

1 голос
/ 20 июня 2020

Может быть, именованный кортеж ?

from collections import namedtuple

def mk_config_obj(keys, **configs):
    return namedtuple('ConfigObj', keys)(*[mk_config(key, **configs) for key in keys])
0 голосов
/ 20 июня 2020

Лучший ответ, который у меня есть до сих пор:

from collections import namedtuple

def mk_config_nt(keys, **configs):
    ConfigNT = namedtuple('ConfigNT', field_names=keys)
    return ConfigNT(**{k: mk_config(k, **configs) for k in keys})

Почему мне это нравится?

Потому что я получаю свои ключи как атрибуты:

config_nt = mk_config_nt(['args', 'validator', 'postproc'], **configs)
assert {'args', 'validator', 'postproc'}.issubset(dir(config_nt))

который Я могу использовать автозаполнение / заполнение (хотя есть два дополнительных раздражающих имени метода: count и index).

Потому что у меня все еще есть выбор:

args, validator, postproc = mk_config_nt(['args', 'validator', 'postproc'], **configs)

И ... он на самом деле быстрее, чем dict. Время доступа к ключу / атрибуту (для группы из трех элементов):

custom object:   36.9 ns
dict:   32.4 ns
namedtuple:   30.7 ns
0 голосов
/ 20 июня 2020

Поприветствуйте Enums.

from enum import Enum

class MKConfigKey(Enum):
    args = 'args'
    validator = 'validator'
    postproc = 'post-roc'

config_map = {key: mk_config(key.value, **config) for key in MKConfigKey}
0 голосов
/ 20 июня 2020

Мне нравится иногда использовать список словарей


list_of_dictionaries = []

a = {}
s = {}
d = {}
f = {}

list_of_dictionaries.append(a)
list_of_dictionaries.append(s)
list_of_dictionaries.append(d)
list_of_dictionaries.append(f)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...