Подтвердить что ты не робот

Формат строки 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())
4b9b3361

Ответ 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