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

Форматирование строк и именованных аргументов в Python

Случай 1:

"{arg1} {arg2}".format (10, 20)

Он даст KeyError: 'arg1', потому что я не передал именованные аргументы.

Случай 2:

"{arg1} {arg2}".format(arg1 = 10, arg2 = 20)

Теперь он будет работать правильно, потому что я передал именованные аргументы. И он печатает '10 20'

Случай 3:

И, если я ошибаюсь, он покажет KeyError: 'arg1'

 "{arg1} {arg2}".format(wrong = 10, arg2 = 20)

Но,

Случай 4:

Если я передаю именованные аргументы в неправильном порядке

"{arg1} {arg2}".format(arg2 = 10, arg1 = 20)

Он работает...

и он печатает '20 10'

Мой вопрос в том, почему он работает и что использует именованные аргументы в этом случае.

4b9b3361

Ответ 1

Именованные поля замены (части {...} в строке соответствуют аргументам ключевого слова методу .format(), а не позиционным аргументам.

Аргументы ключевого слова как ключи в словаре; порядок не имеет значения, поскольку они сопоставляются с именем.

Если вы хотите совместить с позиционными аргументами, используйте числа:

"{0} {1}".format(10, 20)

В Python 2.7 и выше вы можете опустить числа; поля замены {} затем автоматически нумеруются в порядке появления в строке форматирования:

"{} {}".format(10, 20) 

Строка форматирования может совпадать как с аргументами positional, так и с ключевыми словами и может использовать аргументы несколько раз:

"{1} {ham} {0} {foo} {1}".format(10, 20, foo='bar', ham='spam')

Цитата из спецификации строки :

Само имя поля начинается с arg_name, которое либо число, либо ключевое слово. Если это число, это относится к позиционному аргументу, и если это ключевое слово, оно ссылается на именованный аргумент ключевого слова.

Акцент на мой.

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

Вы также можете использовать синтаксис вызова **keywords для применения существующего словаря к формату, что упрощает превращение CSV файла в форматированный вывод:

import csv

fields = ('category', 'code', 'price', 'description', 'link', 'picture', 'plans')
table_row = '''\
    <tr>
      <td><img src="{picture}"></td>
      <td><a href="{link}">{description}</a> ({price:.2f})</td>
   </tr>
'''

with open(filename, 'rb') as infile:
    reader = csv.DictReader(infile, fieldnames=fields, delimiter='\t')
    for row in reader:
        row['price'] = float(row['price'])  # needed to make `.2f` formatting work
        print table_row.format(**row)

Здесь picture, link, description и price - все ключи в словаре row, и гораздо проще увидеть, что происходит, когда я применяю row к строке форматирования.