Принудительное именование параметров в Python

В Python у Вас может быть функциональное определение:

def info(object, spacing=10, collapse=1)

который можно было назвать любым из следующих способов:

info(odbchelper)                    
info(odbchelper, 12)                
info(odbchelper, collapse=0)        
info(spacing=15, object=odbchelper)

благодаря разрешению Python аргументов любого-порядка, пока их называют.

Проблема, которую мы имеем, состоит в том, когда некоторые наши большие функции растут, люди могли бы добавлять параметры между spacing и collapse, подразумевать, что неправильные значения могут идти в параметры, которые не называют. Кроме того, иногда это не всегда ясно относительно какой потребности войти. Мы после способа вынудить людей назвать определенные параметры - не только стандарт кодирования, но и идеально флаг или pydev плагин?

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

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

94
задан Mark Mayo 3 June 2017 в 02:03
поделиться

6 ответов

Обновление:

Я понял, что использование ** kwargs не решит проблему. Если ваши программисты изменяют аргументы функции по своему усмотрению, можно, например, изменить функцию на эту:

def info(foo, **kwargs):

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

Это действительно сводится к тому, что говорит Брайан.


(...) люди могут добавлять параметры между интервалом и collapse (...)

В общем, при изменении функций новые аргументы всегда должны идти в конец. В противном случае это нарушит код. Должно быть очевидно.
Если кто-то изменит функцию так, что код сломается, это изменение должно быть отклонено.
(Как говорит Брайан, это похоже на контракт)

(...) иногда не всегда ясно, что нужно сделать.

Глядя на подпись функции (например, def info (объект, интервал = 10, коллапс = 1) ) следует сразу увидеть, что каждый аргумент, имеющий , а не значение по умолчанию, является обязательным.
То, для чего аргумент, должно быть указано в строке документации.


Старый ответ (сохранен для полноты) :

Вероятно, это не лучшее решение:

Вы можете определять функции следующим образом:

def info(**kwargs):
    ''' Some docstring here describing possible and mandatory arguments. '''
    spacing = kwargs.get('spacing', 15)
    obj = kwargs.get('object', None)
    if not obj:
       raise ValueError('object is needed')

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

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

2
ответ дан 24 November 2019 в 06:02
поделиться

Вы можете использовать оператор ** :

def info(**kwargs):

таким образом люди будут вынуждены использовать именованные параметры.

0
ответ дан 24 November 2019 в 06:02
поделиться

Вы можете объявить свои функции как принимающие только **args. Это разрешит аргументы с ключевыми словами, но вам придется проделать дополнительную работу, чтобы убедиться, что передаются только правильные имена.

def foo(**args):
   print args

foo(1,2) # Raises TypeError: foo() takes exactly 0 arguments (2 given)
foo(hello = 1, goodbye = 2) # Works fine.
1
ответ дан 24 November 2019 в 06:02
поделиться
def cheeseshop(kind, *arguments, **keywords):

в python если вы используете *args, это означает, что вы можете передать n-ное количество аргументов для этого параметра - которые будут приходить списком внутри функции для доступа

и если вы используете **kw, это означает его ключевые аргументы, которые могут быть доступны как dict - вы можете передать n-ное количество kw args, и если вы хотите ограничить, что пользователь должен ввести последовательность и аргументы по порядку, то не используйте * и ** - (это питонический способ обеспечить общие решения для больших архитектур. ...)

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

def info(object, spacing, collapse)
  spacing = spacing or 10
  collapse = collapse or 1
0
ответ дан 24 November 2019 в 06:02
поделиться

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

Если вы все еще хотите это сделать, используйте декоратор функции и функцию inspect.getargspec . Это будет использоваться примерно так:

@require_named_args
def info(object, spacing=10, collapse=1):
    ....

Реализация require_ named_args оставлена ​​в качестве упражнения для читателя.

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

0
ответ дан 24 November 2019 в 06:02
поделиться

Я не понимаю, почему программист вообще добавляет параметр между двумя другими.

Если вы хотите, чтобы параметры функции использовались с именами (например, info (spacing = 15, object = odbchelper) ), то не имеет значения, в каком порядке они определены, поэтому вы можете ну поставь новые параметры в конец.

Если вы действительно хотите, чтобы порядок имел значение, не ждите, что что-то сработает, если вы его измените!

-2
ответ дан 24 November 2019 в 06:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: