简体   繁体   English

在函数中传递可选参数-python

[英]Passing an optional argument in a function - python

I would like to create a function which can take either 1 or 2 arguments. 我想创建一个可以接受1个或2个参数的函数。 Currently, I have a function which takes exactly 2 arguments through CMD: 当前,我有一个函数,它通过CMD正好接受2个参数:

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()

I would then run: 然后,我将运行:

python filename.py lowest furthest python filename.py最低的

Using this means that passing the second arg is a must. 使用此方法意味着必须传递第二个arg。 If I try to run my script just by passing one arg, it encounters an error (as expected). 如果我尝试仅通过传递一个arg来运行脚本,则它将遇到错误(如预期的那样)。 My question is, how do you create an optional argument, which could either be passed or not, depending on the situation? 我的问题是,如何根据情况创建一个可选参数,该参数可以传递也可以不传递?

For example: 例如:

python filename.py lowest python filename.py最低

In this situation, I expect the program to perform the "#something else" script, as nothing was passed and it is different than "furthest". 在这种情况下,我希望程序执行“ #something else”脚本,因为未传递任何内容,并且与“ festest”不同。

Please do not write the code for me, I am here to learn :) 请不要为我写代码,我在这里学习:)

This is explained in the FineManual(tm): https://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions 在FineManual(tm)中对此进行了解释: https ://docs.python.org/2/tutorial/controlflow.html#more-on-defining-functions

Note that in Python, the expression defining the default value for an optional argument is eval'd ony once when the def statement is executed (which is at first import for a top-level function), which can lead to unexpected behaviours (cf "Least Astonishment" and the Mutable Default Argument ). 请注意,在Python中,定义def为可选参数的默认值的表达式在执行def语句时会被评估一次(首先是对顶层函数的导入),这可能导致意外行为(参见“最少惊讶”和可变默认参数 )。

Also, the "default value" has to be an expression , not a statement, so you cannot do any error handling here. 另外,“默认值”必须是表达式 ,而不是语句,因此您不能在此处进行任何错误处理。 wrt/ your case with trying to use sys.argv[2] as a default value, it's wrong for at least two reasons: wrt /您尝试使用sys.argv[2]作为默认值的情况,至少有两个原因是错误的:

  1. as you already noticed, it breaks if len(sys.argv) < 3 正如您已经注意到的,如果len(sys.argv) < 3
  2. it makes your function dependent on sys.argv , so you cannot reuse it in a different context 它使您的函数依赖于sys.argv ,因此您不能在不同的上下文中重用它

The right solution here is to handle all user input ( sys.argv or whatever) in the "entry point" code (the __main__ section) - your function should know nothing about where the arguments values came from ( sys.argv , an HTTP request, a text file or whatever). 正确的解决方案是处理“入口点”代码( __main__部分)中的所有用户输入( sys.argv或其他内容)-您的函数不应该知道参数值的来源( sys.argv ,HTTP请求) ,文本文件等)。

So to make a long story short: use either a hardcoded value (if it makes sense) or a "sentinel" value ( None is a good candidate) as default value for your optional argument, and do all the user inputs parsing in the __main__ section (or even better in a main() function called from the __main__ section so you don't pollute the module's namespace with irrelevant variables): 因此,总而言之:使用硬编码值(如果有意义)或“前哨”值( None是最佳候选值)作为可选参数的默认值,并在__main__进行所有用户输入解析部分(甚至在__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)

您可以通过向要忽略的参数提供默认参数值来编写函数,例如optionalArg = None(无论您想要什么),这样就可以使用单个参数调用该函数。

A very, VERY ugly way is to use exceptions for check if the parameter is defined: 一种非常非常丑陋的方法是使用异常检查参数是否已定义:

import sys

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

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

I advise you not to use it, because you should never be in a situation where you don't know if a variable is defined or not, there are better ways to handle this, but in some cases (not yours) can be usefull, I add it only for this reason. 我建议您不要使用它,因为您永远不要处于不知道是否定义了变量的情况下,可以使用更好的方法来处理它,但是在某些情况下(不是您的)可能会有用,我仅出于这个原因添加它。

Something like this? 像这样吗 kinda code sorry :D 有点代码抱歉:D

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

You can pass a dictionary. 您可以通过字典。 Or a default value which is None if you not explicitly initialize it when calling the function. 如果您在调用函数时未显式初始化它,则默认值为None。

Variant: 变体:

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

You can use *args to pass any number of arguments and receive them as a list, or use **kwargs to send keyword arguments and receive them as a dictionary. 您可以使用*args传递任意数量的参数并将其作为列表接收,或使用**kwargs发送关键字参数并将其作为字典接收。

Here is an example for *args : 这是*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.

This is how you pass optional arguments, not by defining a default value for a variable, which initialises the variable in the memory. 这是通过传递可选参数的方式,而不是通过定义变量的默认值的方式来初始化变量在内存中的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM