2016-02-08 53 views
0

我想創建一個函數,它可以帶有1或2個參數。 目前,我有一個函數,通過CMD到底需要2個參數:傳遞函數中的可選參數 - 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嗨Christoper,如果我改變函數只接受一個參數,那麼它忽略了我通過CMD寫的東西,因此不會讓我傳遞第二個參數。 –

+0

如果你繼續傳遞它兩個參數,那麼肯定。但你爲什麼? –

回答

3

這在FineManual(TM)解釋說:https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions

注意,在Python中,表達式定義當執行def語句時(這是首次導入頂級函數時),可選參數的缺省值將被評估一次,這會導致意外行爲(參見"Least Astonishment" and the Mutable Default Argument)。

此外,「默認值」必須是表達式,而不是語句,因此您不能在此處執行任何錯誤處理。 WRT /你的情況下,試圖使用sys.argv[2]作爲默認值,它是錯的,至少有兩個原因:

  1. 因爲你已經注意到了,它打破如果len(sys.argv) < 3
  2. 它使你的函數依賴sys.argv,所以你你的函數應該一無所知這裏的參數 - 在不同的上下文

這裏正確的解決辦法是處理中的「切入點」代碼的所有用戶輸入(sys.argv或其他)(該__main__部分)不能重複使用值來自(sys.argv,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]',因爲如果沒有參數傳遞,它也會破壞代碼。那麼我該如何檢查實際通過的arg? –

+0

在'foo'中使用'def foo(* args)'時,'args'將會是'tuple'。首先要做的第一件事就是檢查它的長度,如果沒有參數實際通過,採取適當的行動。還要注意標準庫中有幾個命令行參數解析器... –

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

像這樣?有點代碼對不起: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. 

這就是如何通過可選參數,而不是由一個變量,其在初始化存儲器中的變量定義的默認值。