假设我想编写一个类似于range
的函数回想一下,范围有一个参数和2/3参数形式:
class range(object)
| range(stop) -> range object
| range(start, stop[, step]) -> range object
如果我希望方法或函数具有相同的接口,是否有比这更优雅的方法:
def range_like(*args):
start,stop,step=[None]*3
if len(args)==1:
stop=args[0]
elif len(args)==2:
start,stop=args
elif len(args)==3:
start,stop,step=args
else:
raise ValueError
print(start,stop,step)
答案 0 :(得分:5)
这里没有多少建议,但是一个替代方案可能是使用可选参数并交换前两个如果只提供了一个:
def range_like(start, stop=None, step=1):
if stop is None:
start, stop = 0, start
...
答案 1 :(得分:4)
我会把它写成:
def range_like(start=None, stop=None, step=1):
if stop is None:
start, stop = stop, start
...
如果那样做你想要的?
[更新]您还可以添加:
if stop is start is None:
raise ValueError()
另外,使用sentinel对象而不是None(这在Python中不正常,但有时你会看到它):
NOTSET = object()
def range_like(start=NOTSET, stop=NOTSET, step=1):
if stop is NOTSET:
start, stop = stop, start
允许None
作为参数。
答案 2 :(得分:2)
您不能在强制参数之前显示可选参数。
您可以设计像交换参数的解决方法:
def range_like(s, t=None, u=None):
if t is None:
s,t = t,s