Определить функции со слишком большим количеством аргументов для соблюдения стандарта PEP8
Я определил функцию с длинным списком аргументов. Общие символы в определении выше 80 и не сохраняются PEP8.
def my_function(argument_one, argument_two, argument_three, argument_four, argument_five):
Что может быть лучшим способом избежать горизонтальной прокрутки.
Ответы
Ответ 1
Пример приведен в PEP 8:
class Rectangle(Blob):
def __init__(self, width, height,
color='black', emphasis=None, highlight=0):
Итак, это официальный ответ. Лично я ненавижу этот подход, в котором строки продолжения имеют ведущие пробелы, которые не соответствуют какому-либо реальному уровню отступа. Мой подход:
class Rectangle(Blob):
def __init__(
self, width, height,
color='black', emphasis=None, highlight=0
):
., или просто пусть строка будет содержать более 80 символов.
Ответ 2
Для кода Python, который использует аннотации типов, я предлагаю следующее:
def some_func(
foo: str,
bar: str = 'default_string',
qux: Optional[str] = None,
qui: Optional[int] = None,
) -> List[str]:
"""
This is an example function.
"""
print(foo)
...
Если вы используете yapf, вы можете использовать эти параметры в .style.yapf
:
[style]
dedent_closing_brackets = true
split_arguments_when_comma_terminated = true
Ответ 3
def my_function(argument_one, argument_two, argument_three,
argument_four, argument_five):
Ответ 4
Лично я также использовал для решения того же решения, что и второй стиль @BrenBarn. Мне нравится, как правильно представлять отступы параметров функции и ее реализацию, хотя это "несчастливое лицо" несколько необычно для некоторых других людей.
В настоящее время PEP8 специально дает пример для такого случая, поэтому, возможно, основное направление будет адаптировать этот стиль:
# More indentation included to distinguish this from the rest.
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
Ответ 5
Мне лично нравится выстраивать параметры по одному в строке, начиная с открытых круглых скобок и сохраняя этот отступ. flake8
тоже кажется счастливым.
def guess_device_type(device_name: str,
username: str=app.config['KEY_TACACS_USER'],
password: str=app.config['KEY_TACACS_PASS'],
command: str='show version') -> str:
"""Get a device_type string for netmiko"""
Ответ 6
Я нахожу себя таким образом довольно интересным:
def my_function(
argument_one, argument_two, argument_three,
argument_four, argument_five
):
...
это позволяет сворачиванию кода довольно легко выявлять сигнатуры функций, например, рассмотрим следующий фрагмент кода:
def my_function(
argument_one, argument_two, argument_three,
argument_four, argument_five
):
s1 = 1
s2 = 2
if s1 + s2:
s3 = 3
def my_other_function(argument_one, argument_two, argument_three):
s1 = 1
s2 = 2
if s1 + s2:
s3 = 3
Этот способ позволяет свернуть весь файл и увидеть сразу все функции/подписи, то есть:
![enter image description here]()
Ответ 7
Что я бы порекомендовал
Несмотря на то, что это делает функцию более многословной, для более чем одного аргумента я думаю, что это лучше (пример ниже взят из Python
):
def my_function(
argument_one,
argument_two,
argument_three,
argument_four,
argument_five,
):
...
Почему?
- Наличие каждого аргумента в одной строке упрощает использование
git diff
, поскольку изменение одной переменной покажет только это изменение. Если у вас есть более одного аргумента в каждой строке, визуально это будет раздражать позже.
- Обратите внимание, что запятая в последнем аргументе облегчает добавление или удаление аргумента позже, а также соответствует Конвенции PEP 8 "Запятая в запятых", а в дальнейшем дает лучший
git diff
.
- Одна из причин, почему мне действительно не нравится парадигма "выровнять аргументы с открывающими скобками", заключается в том, что она не дает легко поддерживаемого кода.
- Кевлин Хенни объясняет, что это плохая практика в своей лекции ITT 2016 - Семь неэффективных навыков программирования для многих программистов.
- Основная причина плохой практики заключается в том, что если вы измените имя функции (или оно слишком длинное), вам придется заново редактировать интервал в строках всех аргументов, что совсем не так. масштабируемо, хотя может быть (иногда) (субъективно) красивее.
- Другая причина, тесно связанная с приведенной выше, связана с метапрограммированием. Если кодовая база станет слишком большой, вам в конечном итоге понадобится программировать изменения, что будет адом, если интервал между аргументами будет разным для каждой функции.
- Большинство редакторов, когда открыты скобки и вы нажмете enter, откроют новую строку с вкладкой и перенесут закрывающую скобку в нижнюю строку без метки. Таким образом, форматирование кода таким способом очень быстро и отчасти стандартизировано. Например, это форматирование очень распространено в
JavaScript
.
- Наконец, если вы считаете, что каждый аргумент слишком громоздок, потому что ваша функция может иметь много аргументов, я бы сказал, что вы компрометируете простое форматирование кода из-за редких исключений.
- Не принимайте законы исключениями.
- Если у вашей функции много аргументов, вы, вероятно, делаете что-то не так. Разбейте его на несколько (под) функций и классов.