之前可能已经提出这个问题,但我不知道如何查找答案,因为我不确定说出问题的好方法。
主题是函数参数,可以在语义上以多种不同的方式表达。例如,要将文件提供给函数,您可以直接提供文件,也可以提供字符串,这是文件的路径。要指定一个数字,您可以允许一个整数作为参数,或者您可能允许一个字符串(数字),或者您甚至可以允许一个字符串,如“one”。另一个例子可能是一个采用列表(数字,例如)的函数,但为方便起见,它会将一个数字转换为包含一个元素的列表:该数字。
Python中是否存在或多或少的标准方法以允许这种灵活性?如果你不确定参数的类型是什么,它肯定会使程序的代码变得复杂,所以我的猜测是尝试将便利函数分解到一个地方,而不是分散到各处,但我真的不知道如何最好做那种保理。
答案 0 :(得分:0)
但如果您仍然想要,我建议你有一个中间类或函数为你处理:
伪代码:
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 1
或string "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)
由于您无法在运行时将方法添加到内置类(如int
或str
),因此您可以根据Daniel Figueroa提到的结构切换案例语句。
另一种方法是转换:
def func(i):
if not isinstance(i, int):
i = int(i) # objects can overwrite __int__ if needed.
如果你有自己的类可以添加方法,你可以使用双重调度来为你做同样的事情。 Smalltalk将此用于Integer-Float -...转换。
另一种方法是使用面向主题的编程我还没有找到实现但我尝试过:https://gist.github.com/niccokunzmann/4971938