Нет проблем с использованием «константы» в качестве значения по умолчанию. Как вы говорите, пока «константа» действительно постоянна, это не имеет значения. Единственное, вам нужно убедиться, что константа определена перед функцией, но обычно люди помещают все свои константы в начало файла, так что это не проблема.
Второй шаблон, который вы описываете, распространен, когда желаемое значение по умолчанию является изменяемым значением, таким как список. Вы часто видите такие вещи:
def foo(x=None):
if x is None:
x = []
вместо def foo(x=[])
. Вы можете найти много вопросов по этому поводу, но, по сути, это потому, что если вы не сделаете это таким образом, изменяемое значение по умолчанию будет сохраняться при нескольких вызовах функции, что обычно нежелательно.
Однако использование этого шаблона для изменяемой константы уровня модуля не решит эту проблему. Если у вас есть:
SOME_CONSTANT = []
def foo(x=None):
if x is None:
x = SOME_CONSTANT
. . . тогда вы все еще повторно используете одно и то же изменяемое значение для нескольких вызовов. (Конечно, определение изменяемого значения как «константы», вероятно, в любом случае не очень хорошая идея.) Вот почему я спрашивал в комментариях, видели ли вы, чтобы кто-то специально делал такие вещи с константами модуля.
Этот шаблон None-then-if также будет использоваться, если значение по умолчанию на уровне модуля на самом деле не является константой, а значением, предназначенным для изменения другим кодом. Если вы выполняете def foo(x=DEFAULT_TIMEOUT)
, значение x
по умолчанию равно тому, каким было DEFAULT_TIMEOUT
во время определения функции. Но если вы используете шаблон None-then-if, по умолчанию будет то, что DEFAULT_TIMEOUT
есть в момент вызова функции. Некоторые библиотеки определяют значения уровня модуля, которые не должны быть постоянными, а скорее являются значениями конфигурации, которые могут быть изменены в ходе выполнения. Это позволяет пользователям делать такие вещи, как установка DEFAULT_TIMEOUT = 20
для изменения времени ожидания по умолчанию для всех последующих вызовов, вместо того, чтобы каждый раз передавать timeout=20
. В этом случае вам понадобится проверка if внутри функции, чтобы убедиться, что каждый вызов использует «текущее» значение DEFAULT_TIMEOUT
.
person
BrenBarn
schedule
30.12.2017
[]
. С неизменяемыми типами, такими как числа, вы должны быть в порядке, используя их напрямую. - person Paul Panzer   schedule 30.12.20170
- person Stephen Rauch   schedule 30.12.2017