Pythonic way to have a choice of 2-3 options as an argument to a function

南楼画角 提交于 2019-12-12 08:25:48

问题


I have a Python function which requires a number of parameters, one of which is the type of simulation to perform. For example, the options could be "solar", "view" or "both.

What is a Pythonic way to allow the user to set these?

I can see various options:

  1. Use a string variable and check it - so it would be func(a, b, c, type='solar')

  2. Set some constants in the class and use func(a, b, c, type=classname.SOLAR)

  3. If there are only two options (as there are for some of my functions) force it into a True/False argument, by using something like func(a, b, c, do_solar=False) to get it to use the 'view' option.

Any preferences (or other ideas) for Pythonic ways of doing this?


回答1:


If the point Niklas' makes in his answer doesn't hold, I would use a string argument. There are Python modules in the standard library that use similar arguments. For example csv.reader().

sim_func(a, b, c, sim_type='solar')

Remember to give a reasonable error inside the function, that helps people out if they type in the wrong thing.

def sim_func(a, b, c, sim_type='solar'):
    sim_types = ['solar', 'view', 'both']
    if sim_type not in sim_types:
        raise ValueError("Invalid sim type. Expected one of: %s" % sim_types)
    ...



回答2:


I don't like any of those options.

I'd define two different functions, perform_solar(a, b, c) and perform_view(a, b, c) and let the caller decide which ones he wants to use, in which order and with which arguments.

If the reason why you thought you'd have to pack these into one single function is that they share state, you should share that state in an object and define the functions as methods.




回答3:


Since functions are objects in python, you could actually process *args as a list of methods and pass the types of simulations as arbitratry args at the end. This would have the benefit of allowing you to define new simulations in the future without having to refactor this code.

def func(a, b, c, *args):
    for arg in args:
        arg(a, b, c)

def foosim(a, b, c):
    print 'foosim %d' % (a + b + c)

def barsim(a, b, c):
    print 'barsim %d' % (a * b * c)

Use:

func(2, 2, 3, foosim)
func(2, 2, 3, barsim)
func(2, 2, 3, foosim, barsim)

Output:

foosim 7
barsim 12
foosim 7
barsim 12



回答4:


You can use the assert statement like this:

assert sim_types in ['solar', 'view', 'both'], 'sim type parameter must be solar, view or both'

If sim_types is not in the list, python will raise an Assertion Error




回答5:


You can use optional (keyword) arguments like this

def func(a, b, c, **kw):
    if kw.get('do_solar'):
        # Do Solar
    if kw.get('do_view'):
        # Do view


来源:https://stackoverflow.com/questions/9522877/pythonic-way-to-have-a-choice-of-2-3-options-as-an-argument-to-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!