2014-01-10 2 views
6

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

Например, эта функция по существу делает печать каждого местоположения строки в файле.

def scan(fpin,base,string,pNo,print_to_file,dumpfile_path,quiet): 

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

+3

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

ответ

6

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

Учитывать встроенную функцию sorted. Он принимает до четырех аргументов. Является ли параметр reverse до или после cmp? Что я должен передать в качестве key, если я хочу, чтобы по умолчанию? Ответ: Черт, если я помню. Я звоню sorted(A, reverse=True), и он делает то, что я ожидаю.

Кстати, если у меня был тонна «конфигурация» -Style аргументов, которые я переходящими в каждый вызов для сканирования, и только изменяя (скажем, fpin и string) каждый раз, я мог бы быть склонен поставить все другие argumentsinto словарь, а затем передать его функции с синтаксисом **kwargs. Это немного более продвинуто. Подробнее см. В руководстве. (Обратите внимание, что это НЕ то же самое, что объявить эту функцию как принятие **kwargs. Определение функции одинаков, единственное отличие в том, что вызовы к ней выглядят.)

1

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

... Однако, если вы обнаружите, что делаете что-то подобное, хотя:

func('somestring', a=A, b=B, c=C) 
func('something else', a=A, b=B) 
func('something third', a=A, c=C, d=D) 

и т.д., где A, B, C действительно конфигураций для множества различных вещей, то вы должны начать смотреть в класс. Класс делает много вещей, но он также создает контекст. Вместо этого, вы можете сделать что-то вроде:

cf = myclass(a=A, b=B, c=C, d=D) 
cf.func('somestring') 
cf.func('something else') 
cf.func('something third') 

и т.д.

Смежные вопросы