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

Python: избегать предупреждений pylint о слишком многих аргументах

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

x = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9

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

def mysum(x1, x2, x3, x4, x5, x6, x7, x8, x9):
    x = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9
    return x

Проблема заключается в том, что pylint вызовет предупреждение о слишком большом количестве аргументов. Я мог бы избежать предупреждения, сделав что-то вроде:

def mysum(d):
    x1 = d['x1']
    x2 = d['x2']
    ...
    x9 = d['x9']
    x = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9
    return x

def mybigfunction():
    ...
    d = {}
    d['x1'] = x1
    ...
    d['x9'] = x9
    x = mysum(d)

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

Есть ли лучший способ сделать это?

4b9b3361

Ответ 1

Во-первых, один из Perlis epigrams:

"Если у вас есть процедура с 10 параметры, вы, вероятно, пропустили некоторые."

Некоторые из 10 аргументов предположительно связаны между собой. Группируйте их в объект и передайте это вместо.

Приведите пример вверх, потому что в ответе на него недостаточно информации:

class PersonInfo(object):
  def __init__(self, name, age, iq):
    self.name = name
    self.age = age
    self.iq = iq

Затем ваша 10-функция аргумента:

def f(x1, x2, name, x3, iq, x4, age, x5, x6, x7):
  ...

становится:

def f(personinfo, x1, x2, x3, x4, x5, x6, x7):
  ...

и вызывающий абонент изменит на:

personinfo = PersonInfo(name, age, iq)
result = f(personinfo, x1, x2, x3, x4, x5, x6, x7)

Ответ 2

Вам нужен лучший способ передать аргументы или просто остановить pylint от трудностей? Если последнее, я, кажется, вспоминаю, что вы можете остановить ворчание, добавив pylint -controlling комментарии в свой код в соответствии с строками:

#pylint: disable-msg=R0913

или

#pylint: disable-msg=too-many-arguments

помня о том, чтобы вернуть их как можно скорее.

По-моему, нет ничего неправильного в передаче большого количества аргументов и решений, защищающих их включение в какой-либо контейнерный аргумент, на самом деле не решает никаких проблем, кроме как остановить pylint от nagging you: -).

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

Ответ 3

Вы можете легко изменить максимально допустимое количество аргументов в pylint. Просто откройте файл pylintrc (сгенерируйте его, если у вас его еще нет) и измените:

макс-арг = 5

чтобы:

max-args = 6 # или любое подходящее вам значение

Из руководства Пилинта

Указание всех параметров, подходящих для ваших настроек и стандартов кодирования, может быть утомительным, поэтому можно использовать файл rc для указания значений по умолчанию. Pylint ищет /etc/pylintrc и ~/.pylintrc. Опция --generate-rcfile создаст закомментированный файл конфигурации в соответствии с текущей конфигурацией стандартного вывода и выхода. Вы можете поставить другие опции перед этим, чтобы использовать их в конфигурации, или начать со значений по умолчанию и вручную настроить конфигурацию.

Ответ 5

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

Ответ 6

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

EDIT: если это временная мера, отключите предупреждение для конкретной функции, используя комментарий, как описано здесь: http://lists.logilab.org/pipermail/python-projects/2006-April/000664.html

Позже вы можете grep для всех отключенных предупреждений.

Ответ 7

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

Так что я бы лучше сделал:

#pylint: disable-msg=too-many-arguments

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

Так лучше делать

#pylint: disable-msg=too-many-arguments
code_which_would_trigger_the_msg
#pylint: enable-msg=too-many-arguments    

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

Ответ 8

У Python есть хорошие инструменты для функционального программирования, которые, вероятно, будут хорошо соответствовать вашим потребностям. Проверьте лямбда-функции и map. Кроме того, вы используете dicts, когда кажется, что вам будет гораздо лучше подавать списки. Для простого примера, который вы предоставили, попробуйте эту идиому. Обратите внимание, что карта будет лучше и быстрее, но может не соответствовать вашим потребностям:

def mysum(d):
   s = 0  
   for x in d:
        s += x
   return s

def mybigfunction():
   d = (x1, x2, x3, x4, x5, x6, x7, x8, x9)
   return mysum(d)

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

Ответ 9

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