2016-02-08 2 views
0

Я хотел бы создать функцию, которая может принимать 1 или 2 аргумента. В настоящее время у меня есть функция, которая принимает ровно два аргумента через CMD:Передача необязательного аргумента в функции - python

def test(self,countName,optionalArg): 
     if countName == "lowest": 
      #something 
     if optionalArg == "furthest: 
      #something 
     else: 
      #something else 

if __name__ == '__main__': 
     countName = sys.argv[1] 
     optionalArg = sys.argv[2] 

     temp = len(sys.argv) 
     for i in xrange(1,temp): 

      sys.argv.pop() 

Я бы тогда запустить:

питон filename.py низкий дальше

Используя это означает, что Попутно второй аргумент является обязательным. Если я попытаюсь запустить мой скрипт, просто передав один аргумент, он встретит ошибку (как и ожидалось). Мой вопрос: как создать необязательный аргумент, который может быть передан или нет, в зависимости от ситуации?

Например:

питона filename.py низкий

В этой ситуации, я ожидаю, что программа для выполнения «#something еще» сценарий, как и не было принято ничего, и это отличается чем «самый дальний».

Пожалуйста, не пишите код для меня, я здесь, чтобы узнать :)

+0

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

+0

@ ChristoferOhlsson Привет Кристопер, если я изменю функцию, чтобы принять только один аргумент, тогда он игнорирует то, что я пишу через CMD, тем самым не позволяя мне передать второй аргумент. –

+0

Если вы продолжаете передавать два аргумента, то уверены. Но почему бы вам? –

ответ

3

Это объясняется в FineManual (тм): https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions

Обратите внимание, что в Python, выражение Определяя Значение по умолчанию для необязательного аргумента равно eval'd ony один раз, когда выполняется оператор def (который сначала импортируется для функции верхнего уровня), что может привести к неожиданному поведению (cf "Least Astonishment" and the Mutable Default Argument).

Кроме того, «значение по умолчанию» должно быть выражением , а не инструкцией, поэтому здесь вы не можете обрабатывать ошибки. WRT/ваш случай с попыткой использовать sys.argv[2] в качестве значения по умолчанию, это не так, по крайней мере по двум причинам:

  1. , как вы уже заметили, он ломает, если len(sys.argv) < 3
  2. это ваша функция зависит от sys.argv, так что вы не может использовать его в другом контексте

Правильным решением здесь обрабатывать весь пользовательский ввод (sys.argv или любой другой) в коде «точка входа» (раздел __main__) - ваша функция не должна ничего знать о том, где аргументы значения получены из (), HTTP-запрос, текстовый файл или что-то еще).

Для того, чтобы сделать длинный рассказ коротким: используйте либо твердое значение (если оно имеет смысл), либо значение «дозорного» (None - хороший кандидат) в качестве значения по умолчанию для вашего необязательного аргумента, а также все пользовательские входы разбор в разделе __main__ (или даже лучше в main() функции, вызываемой из секции __main__, так что вы не загрязнять пространство имен модуля с несущественными переменными):

def func(arg, optarg=None): 
    #code here 


def main(*args): 
    #parse args 
    #call func with the right args 

if __name__ == "__main__": 
    import sys 
    main(*sys.argv) 
+0

Привет, спасибо вам за помощь. Я прочитал его и не мог понять, как решить проблему, используя это. Я обновил свой вопрос, был бы признателен, если бы вы его просмотрели. Я полагаю, что моя проблема связана с «optionalArg = sys.argv [2]», поскольку она всегда ожидает там утверждения.не передавая ничего через CMD, появляется ошибка «индекс индекса вне диапазона». –

+0

Мне очень жаль, что мне потребовалось столько времени, чтобы ответить, личные проблемы. Большое вам спасибо, это очень помогло мне! Мне удалось преобразовать мой код и использовать (* args) так, как это было упомянуто. Для меня все еще непонятно, и вот как я могу проверить переданные аргументы. Я не могу использовать 'if args [1]', так как он также нарушает код, если аргументы не были переданы. Тогда как я должен проверить, какой аргумент фактически был передан? –

+0

При использовании 'def foo (* args)', в 'foo',' args' будет 'tuple'. Самое первое, что нужно сделать, это, конечно, проверить его длину и предпринять соответствующие действия, если никакие аргументы не были переданы. Также обратите внимание, что есть пара аргументов парсеров аргументов в стандартном lib ... –

1

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

0

очень, очень некрасиво способ заключается в использовании исключений для проверки, если параметр определяется:

import sys 

if __name__ == '__main__': 
    arg = sys.argv[1] 

    try: 
     optionalArg = sys.argv[2] 
    except IndexError: 
     optionalArg = "" 
    else: 
     print "sure, it was defined." 

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

0

Что-то вроде этого? kinda code sorry: D

def function(value, opt = ""): 
    print("Value: " + value) 
    if not opt == "": 
    print("Optional: " + opt) 
0

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

0

Вариант:

def somefunc(*args, **kwargs): 
    if 'optional_arg' in kwargs: 
     print kwargs['optional_arg'] 
0

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

Вот пример для *args:

def test(count_name, *args): 

    if count_name == "lowest":  
     print('count_name received.') 

    if args and args[-1] == "furthest":  
     print('2nd arg received.')  

    else:  
     print('No second arg given.')  

    return None 


if __name__ == '__main__': 
    count_name = 'lowest' 
    optional_arg = 'furthest' 

    print('Test 1:') 
    test(count_name, optional_arg) 
    # Displays: 
    # Test 1: 
    # count_name received. 
    # 2nd arg received. 

    print('\n\nTest 2:') 
    test(count_name) 
    # Test 2: 
    # count_name received. 
    # No second arg given. 

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

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