Использовать параметры формата и остаться со строкой, которую я могу снова отформатировать позже? - PullRequest
0 голосов
/ 05 декабря 2018

Я работал над проектом и столкнулся с интересной ситуацией.Я читаю некоторые данные из файла и использую их для форматирования / завершения такой строки.

#After I read the file I create an internal dictionary to use, so for brevity 
#I'll use an example of the retrieved data
film = {"name":"Gran Torino", "type":"Drama"}

movie = "{name} is a {genre} movie. The vote given by {person} is {stars}"
movie = movie.format(name=film["name"],genre=film["type"])

Это, очевидно, генерирует ошибку, такую:

Traceback (most recent call last):
File "movie.py", line 65, in <module>
    movie = movie.format(name=film["name"],genere=film["type"])
KeyError: 'person'

, потому что некоторые ключи отсутствуют.Недостающий будет получен от пользователя, когда он их введет.Я уже знаю, как избежать ошибки, например, отформатировать все после того, как я извлек другие данные из пользовательского ввода.
Однако мне интересно кое-что:

Есть ли способ Python , используя .format () / f-strings / string Template , для форматирования строки с некоторым начальным значением и сохранения некоторых пропущенных мест в последующем втором проходе?Другими словами, могу ли я вставить только определенное значение, а затем пропущенное?

Псевдокод того, чего я пытаюсь достичь

string = "{first} text {second} ... and so on {last}"
#apply one time format but only one some place-holders
result = string.format(first=value) #dosen't need to generate an error
print(result) # "value text {second} ... and so on {last}"

Как вы можете видеть, что я хочучтобы узнать, есть ли в языке способ выполнить эту процедуру со встроенными параметрами форматирования и без создания новой функции для этого.

Примечание:

Я уже пытался использоватьнекоторые другие параметры, такие как строка Template, но не смогли заставить его работать.Более того, я знаю, что можно сначала объединить данные, которые у меня есть, позже добавить строковую часть и отформатировать позже, как это:

first_part = film["name"] + " is a " + film["genre"] + " movie."
second_part = "The vote given by {person} is {stars}"
movie = first_part + second_part
#later when I have stars and person
movie.format(person=v1,stars=v2)

Это работает, но я бы хотел понять, могу ли я использовать два разаВместо этого используется метод format ().

1 Ответ

0 голосов
/ 05 декабря 2018

Вы можете написать функцию, которая создаст строку для вас.По умолчанию он будет использовать «unknown» в качестве строки, если информация отсутствует:

def str_constructor(name="unknown", genre="unknown", person="unknown", stars="unknown"):
    movie = "{} is a {} movie. The vote given by {} is {}".format(name, genre, person, stars)
    return movie

film = {"name":"Gran Torino", "type":"Drama"}
str_constructor(name=film["name"], type=film["type"])

Обновление:

Теперь, когда я полностью понимаю ваш желаемый результат, у меня есть другой вариант.Интуитивно понятный вариант этого будет:

string = "{name} is a {genre} movie. The vote given by {person} is {stars}"
film = {"name":"Gran Torino", "type":"Drama"}
print string.format(**film)

Но это вызовет ошибку, так как в вашем словаре форматирования отсутствуют переменные.

В этом ответе решение дается путем создания отдельного форматера.Попробуйте это:

from string import Formatter

class UnseenFormatter(Formatter):
    def get_value(self, key, args, kwds):
        if isinstance(key, str):
            try:
                return kwds[key]
            except KeyError:
                return key
        else:
            return Formatter.get_value(key, args, kwds)

string = "{name} is a {genre} movie. The vote given by {person} is {stars}"
film = {"name":"Gran Torino", "type":"Drama"}

fmt = UnseenFormatter()
print fmt.format(string, **film)

... и вы получите:

Gran Torino - жанровый фильм.Голос, отданный человеком, - звезды

Позже вы можете обновить свой словарь film, чтобы получить остальную часть вашего результата.

...