Python中的灵活参数

时间:2013-04-08 15:28:34

标签: python arguments

之前可能已经提出这个问题,但我不知道如何查找答案,因为我不确定说出问题的好方法。

主题是函数参数,可以在语义上以多种不同的方式表达。例如,要将文件提供给函数,您可以直接提供文件,也可以提供字符串,这是文件的路径。要指定一个数字,您可以允许一个整数作为参数,或者您可能允许一个字符串(数字),或者您甚至可以允许一个字符串,如“one”。另一个例子可能是一个采用列表(数字,例如)的函数,但为方便起见,它会将一个数字转换为包含一个元素的列表:该数字。

Python中是否存在或多或少的标准方法以允许这种灵活性?如果你不确定参数的类型是什么,它肯定会使程序的代码变得复杂,所以我的猜测是尝试将便利函数分解到一个地方,而不是分散到各处,但我真的不知道如何最好做那种保理。

4 个答案:

答案 0 :(得分:0)

  1. 不要那样做! ;)
  2. 但如果您仍然想要,我建议你有一个中间类或函数为你处理:

    伪代码:

    def printTheNumber(num):
        print num
    
    
    def intermediatePrintTheNumber(input):
    
        num_int_dict = {'one':1, "two":2 ....
        if input.isstring():
            printTheNumber(num_int_dict[input])
        elif input.isint():
            printTheNumber(input)
        else:
            print "Sorry Dave, I don't understand you"
    

    如果这是pythonic我不知道,但如果我不得不这样做,我当然会更多地检查输入以确认它有效。

    在您的评论中,您提到了语义相似性,即"one"1可能意味着同样的事情。

    你应该在哪里进行这种转换。

    那取决于你的系统的设计,但我可以告诉你,它不应该在我调用printTheNumber的同一个函数中完成,原因很简单,那就是功能方式要承担很多责任。

    根据输入的复杂程度,可能是integer 1string "1",或者更糟糕的情况是,"one"或更差"uno"|"one"|"yxi"|"ett" .. and so on。这应该由一个函数来处理,该函数只对处理映射的数据库负责。

    我会拆分它,以便我有一个函数处理字符串“one”,“two”......等,一个处理整数,并有第三个函数检查输入,看看它是否可以转换是否为整数。

    正如我所看到的,如果您必须采取措施来应对这种复杂性,那么设计中存在{strong>警告 <{1}}缺陷,但您似乎意识到这一点所以我不会继续谈论它。

答案 1 :(得分:0)

分解几个函数共有代码的好方法是decorators。例如,

from functools import wraps

def takes_list(func):
    @wraps(func)
    def wrapper(arg):
        if not isinstance(arg, list):
            arg = [arg]
        return func(arg)
    return wrapper

@takes_list
def my_func(x):
    "Does something with list x."

我应该注意,对于像文件这样的情况,你不想妨碍Python的鸭子打字:做一个检查isinstance(arg, file)有一个问题,它不会允许像文件一样的东西为io.StringIO。相反,请检查str(或basestring),或者让open为您进行检查,尝试使用try-except。

然而,通常更好的做法是让调用者将他们喜欢的内容传递给函数,如果无效则失败。

答案 2 :(得分:0)

不,没有或多或少的“标准”方法。

答案 3 :(得分:-1)

  1. 由于您无法在运行时将方法添加到内置类(如intstr),因此您可以根据Daniel Figueroa提到的结构切换案例语句。

    < / LI>
  2. 另一种方法是转换:

    def func(i):
        if not isinstance(i, int):
            i = int(i) # objects can overwrite __int__ if needed.
    
  3. 如果你有自己的类可以添加方法,你可以使用双重调度来为你做同样的事情。 Smalltalk将此用于Integer-Float -...转换。

  4. 另一种方法是使用面向主题的编程我还没有找到实现但我尝试过:https://gist.github.com/niccokunzmann/4971938