Формат строки python, вызывающий функцию
Есть ли способ форматировать с синтаксисом нового формата строку из вызова функции? например:
"my request url was {0.get_full_path()}".format(request)
поэтому он вызывает функцию get_full_path
внутри, а не как параметр в функции формата.
EDIT:
Вот еще один пример, который, скорее всего, покажет мое разочарование, вот что мне хотелось бы:
"{0.full_name()} {0.full_last_name()} and my nick name is {0.full_nick_name()}".format(user)
это то, чего я хочу избежать:
"{0} and {1} and my nick name is {2}".format(user.full_name(), user.full_last_name(), user.full_nick_name())
Ответы
Ответ 1
Python 3.6 добавляет литеральную строчную интерполяцию, которая написана с префиксом f
. См. PEP 0498 - Интерполяция буквенных строк.
Это позволяет писать
>>> x = 'hello'
>>> s = f'{x}'
>>> print(s)
hello
Следует отметить, что это не фактические строки, а представляют собой код, каждый раз оценивающий строку. В приведенном выше примере s
будет иметь тип str
со значением 'hello'
. Вы не можете передать f
-струю вокруг, так как она будет оцениваться с результатом str
перед использованием (в отличие от str.format
, но, как и любой другой модификатор строкового литерала, например r'hello'
, b'hello'
, '''hello'''
). (PEP 501 - интерполяция строк общего назначения (в настоящее время отложена) предлагает строковый литерал, который будет оценивать объект, который может принимать замены позже.)
Ответ 2
Не уверен, что вы можете изменить объект, но вы можете изменить или обернуть объект для создания свойств функций. Тогда они будут выглядеть как атрибуты, и вы можете сделать это как
class WrapperClass(originalRequest):
@property
def full_name(self):
return super(WrapperClass, self).full_name()
"{0.full_name} {0.full_last_name} and my nick name is {0.full_nick_name}".format(user)
который является законным.
Ответ 3
Python напрямую не поддерживает интерполяцию переменных. Это означает, что ему не хватает определенной функциональности (а именно, вызова функций в строках), которую поддерживают другие языки.
Так что здесь нечего сказать, кроме "нет", вы не можете этого сделать. Это просто не так, как работает синтаксис Python форматирования.
Лучшее у вас есть это:
"my request url was {0}".format(request.get_full_path())
Ответ 4
Как насчет этой очень странной вещи?
"my request url was %s and my post was %s"\
% (lambda r: (r.get_full_path(), r.POST))(request)
Пояснение:
- Классический способ форматирования
- Функция Lambda, которая принимает запрос и возвращает кортеж с тем, что вы хотите
- Вызвать lambda inline в качестве аргументов для вашей строки.
Я по-прежнему предпочитаю, как вы это делаете.
Если вы хотите читать, вы можете это сделать:
path, post = request.get_full_path(), request.POST
"my request url was {} and my post was {}".format(path, post)
Ответ 5
Таким образом, краткое изложение методов будет
(base) [1]~ $ cat r.py
# user is dict:
user = {'full_name': 'dict joe'}
print('{0[full_name]}'.format(user))
# user is obj:
class user:
@property
def full_name(self):
return 'attr joe'
print('{0.full_name}'.format(user()))
# Wrapper for arbitray values - as dict or by attr
class Getter:
def __init__(self, src):
self.src = src
def __getitem__(self, k):
return getattr(self.src, k, 'not found: %s' % k)
__getattr__ = __getitem__
print('{0[foo]} - {0.full_name}'.format(Getter(user())))
(base) [1]~ $ python r.py
dict joe
attr joe
not found: foo - attr joe