0

这可能以前被问过,但我不知道如何查找答案,因为我不确定什么是表达问题的好方法。

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

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

4

4 回答 4

0

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

于 2013-04-08T15:43:21.953 回答
0
  1. 不要那样做!;)

但如果你仍然想要,我建议你有一个中间类或函数为你处理这个:

伪代码:

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原因很简单,那就是这会给这个函数带来很多责任。

根据输入的复杂性,它可能是 the integer 1or the string "1"or,在更坏的情况下,"one"甚至可能更糟"uno"|"one"|"yxi"|"ett" .. and so on。这应该由仅具有该职责的函数处理,可能由处理映射的数据库来处理。

我会将其拆分,以便我有一个函数处理字符串“一”、“二”……等,一个处理整数,并有第三个函数检查输入以查看它是否可以转换为整数或不。

在我看来,如果您必须针对这种复杂性采取措施,则会警告设计存在fundamental缺陷,但您似乎已经意识到这一点,所以我不会继续讨论。

于 2013-04-08T15:36:09.553 回答
0

分解出几个函数共有的代码的一个好方法是通过装饰器。例如,

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. 相反,使用 try-except 检查str(或basestring) 甚至让open您进行检查。

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

于 2013-04-08T15:37:46.243 回答
-1
  1. 由于您不能在运行时将方法添加到内置类中,int或者str您会像 Daniel Figueroa 提到的那样创建 switch case 语句。

  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

于 2013-04-08T15:40:51.360 回答