Возможно ли сократить эту функцию?
Всем привет. Я хочу чтобы переменные в этой функции сразу передавались в функцию render_template()
а не заново вручную переписывать каждое значение. Я понимаю что все можно напрямую записать в render_template
, но есть ли другой способ?
def info():
lvl = wynnpars.lvl
precent = wynnpars.precent
warcount = wynnpars.warcount
totalm = wynnpars.totalm
owner = wynnpars.owner
o_owner = wynnpars.o_owner
chief = wynnpars.chief
o_chief = wynnpars.o_chief
strategist = wynnpars.strategist
o_strategist = wynnpars.o_strategist
recruits = wynnpars.recruirt
o_recruits = wynnpars.o_recruit
return render_template('info.html',
lvl = lvl,
precent = precent,
warcount = warcount,
owner = owner,
recruits = recruits,
totalm = totalm,
chief = chief,
strategist = strategist,
strat = range(len(strategist)),
rec = range(len(recruits)),
o_owner = o_owner,
o_chief = o_chief,
o_str = o_strategist,
o_rec = o_recruits
)
Ответы (1 шт):
Не совсем понятно, что за объект wynnparse (Какой у него тип)
Но скорее всего вам поможет вот такой способ:
def info():
return render_template('info.html', **vars(wynnpars)) # Или wynnpars.__dict__
Что здесь происходит?
В большинстве случаев вы можете получить доступ ко всем элементам объекта python, используя obj.__dict__
или vars(obj)
(За исключением следущих случаев):
- Slot based class (Класс, переопределяющий
__slots__
(см. Ориг. Документацию или Неплохой ответ на stackoverlflow) - Dataclass (классы с декоратором
@dataclass
не имеют__dict__
) - Классов из друг их языков (например C-based классы, написанные на чистом С)
- Именованные картежи (объекты
collections.namedtuple
так же не имеют__dict__
)
__dict__
- по сути обычный питоновский словарь (dict
), который хранит все данные объекта в виде пар ключ значение (как и все словари) например:
class Example:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
self.text = 'Hello world'
object_example = Example(1, 3, 5)
print(vars(object_example))
print(object_example.__dict__)
Оба print
'a выведут одинаковый результат, словарь, с переменными и их значениями:
И так, vars(obj)
(так же как и obj.__dict__
) Позволяют из объекта получить словарь со списокм его переменных.
Далее все что нам остается это полученный словарь значений передать в функцию. Используя **dict
синтаксис мы можем передать словарь в функцию, как если бы каждый из ключей мы подставляли напрямую (См. операторы распаковки Python:
class Example:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
self.text = 'Hello world'
def some_func(c, b, a, text):
print(f'получены значения: \n{a = }\n{b = }\n{c = }\n{text = }')
obj = Example(5, 6, 7)
print('VARS Результат: \n')
some_func(**vars(obj))
print('\nОбычный результат: \n')
some_func(
a=obj.a,
b=obj.b,
c=obj.c,
text=obj.text
)
Код выше показывает 2 способа предачи значений объекта в функцию, как у вас, и через vars()
и оператор **
Рузультаты будут идентичны:
Таким образом, вы можете передавать каждое из значений через **vars, и сократить код.
ВАЖНО! Обратите внимание, ключи, под которыми передаются переменные, будут соответствовать названию переменных в объекте. Таким образом, использование
lvl = wynnpars.lvl
precent = wynnpars.precent
warcount = wynnpars.warcount
owner = wynnpars.owner
recruits = wynnpars.recruits
Не вызовет, проблем, но в местах, где название ключа в шаблоне не соотвтствует переменной в wynnpars, например:
o_str = wynnpars.o_strategist
o_rec = wynnpars.o_recruit
Приведет к тому, что при использовании **wynnpars.__dict__
в вашем шаблоне переменной с названием o_rec
не будет, но будет o_recruit
. В таком случае вам нужно будет изменить шаблон, либо скомбинировать 2 варианта.
Комбинации:
В вашем примере часть названий переменных в шаблоне, соответствуют переменным в wynnpars, а часть - нет. К тому же, часть из них, вообще вычисляет по ходу, и не присутствует в оригинальном wynnpars, например
strat = range(len(strategist))
В таком случае, такие переменные вы можете передавать совместно, примерно так:
def info():
return render_template('info.html',
**vars(wynnpars),
strat=range(len(wynnpars.strategist)),
rec=range(len(wynnpars.recruirt)),
o_str=wynnpars.o_strategist,
o_rec=wynnpars.o_recruit
)
Здесь те переменные, названия которых совпадают с полями wynnpars, опускаются, потому что они передадутся автоматически, вместе с **vars(wynnpars)
.
Поля, которые вычисляются по ходу, передаются следом, как обычно, и вычисляются из других полей переменной wynnpars
.
Ну и в конце передаются те переменные, названия которых не совпадают с названиями переменных в оригинальном объекте wynnpars
. Благодаря этому, вам не придется изменять в шаблоне все использования переменной o_rec
на o_recruit
P.S. Еще одно отступление
vars(obj)
- по сути просто один из способов получить значение в obj.__dict__
.
Большинство источников предлагает vars(obj)
как более предпочтительный для использования вариант, считая его более читаемым.
Лично для меня obj.__dict__
всегда был понятнее, поэтому предлагаю вам самостоятельно выбрать, какой из вариантов ВАМ нравится больше.