Почему вызывающая функция в python содержит переменную, равную значению?

Я начал изучать python, и я хотел бы спросить вас о чем-то, что я считал небольшой магией на этом языке.

Я хотел бы отметить, что перед изучением python я работал с PHP, и там я этого не заметил.

Что происходит? Я заметил, что некоторые конструкторы или методы вызова в Python находятся в этой форме.

object.call(variable1 = value1, variable2 = value2)

Например, в FLask:

app.run(debug=True, threaded=True)

Есть ли причина для этого соглашения? Или существует какая-то семантическая причина, исходящая из языковых основ? Я не видел что-то подобное в PHP так часто, как в Python, и потому, что я действительно удивлен. Мне действительно любопытно, есть ли какая-то магия или это только соглашение, чтобы легче читать код.

Ответ 1

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

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

Рассмотрим это:

app.run(True, False)

Вы знаете, что означают эти два аргумента? Даже если вы можете догадаться, что единственными двумя разумными аргументами являются потоки и отладки флагов, как вы можете догадаться, какой из них на первом месте? Единственный способ, которым вы можете это сделать, - выяснить, какой тип app есть, и проверить docstring или определение метода app.run.

Но здесь:

app.run(debug=True, threaded=False)

Очевидно, что это значит.


Стоит прочитать FAQ В чем разница между аргументами и параметрами? и другими разделами учебника рядом с приведенным выше. Затем вы можете прочитать ссылку на определения функций для получения полной информации о параметрах и Calls для получения полной информации о аргументы и, наконец, документацию модуля inspect по видам параметров.

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

Ответ 2

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

def pmt(principal, interest, term):
    return **something**;

Когда кто-то пытается рассчитать амортизацию покупки своего дома, он может быть вызван таким образом:

payment = pmt(100000, 4.2, 360)

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

payment = pmt(360, 4.2, 100000)

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

payment = pmt(principal=100000, interest=4.2, term=360)

Кроме того, параметры ключевых слов позволяют изменять порядок параметров на сайте вызова, и все работает правильно:

# Equivalent to previous example
payment = pmt(term=360, interest=4.2, principal=100000)

Подробнее см. http://docs.python.org/2/tutorial/controlflow.html#keyword-arguments.

Ответ 3

Это аргументы, передаваемые по ключевым словам. Семантическая разница между аргументами ключевого слова и позиционными аргументами.

Они часто используются как "параметры" и предоставляют гораздо более читаемый синтаксис для этого обстоятельства. Подумайте об этом:

>>> sorted([2,-1,3], key=lambda x: x**2, reverse=True)
[3, 2, -1]

Против (python2):

>>> sorted([2,-1,3], None, lambda x: x**2, True)
[3, 2, -1]

В этом втором примере вы можете рассказать, что означает значение None или True?

Обратите внимание, что только в аргументах ключевого слова, то есть аргументы, которые вы можете указать только с помощью этого синтаксиса, были введены в python3. В python2 любой аргумент может быть задан положением (кроме случаев, когда используется **kwargs, но это другая проблема).

Ответ 4

Нет "волшебства".

Функция может принимать:

  • Позиционные аргументы (args)
  • Аргументы с ключевыми словами (kwargs)

Всегда этот порядок.

Попробуйте следующее:

def foo(*args, **kwargs):
    print args
    print kwargs

foo(1,2,3,4,a=8,b=12)

Вывод:

(1, 2, 3, 4)
{'a': 8, 'b': 12}

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

Ответ 5

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

Пример:

def foo(i1, i2=1, i3=3, i4=5):
   # does something


foo(1,2,3,4)

foo(1,2,i4=3)

foo(1,i2=3)

foo(0,i3=1,i2=3,i4=5)