Raf*_*l T 4 python arguments method-signature python-3.x
因为在python 3.X中,build-id range()函数不再返回一个列表而是一个可迭代的,一些旧的代码失败,因为我用它range()来方便地生成我需要的列表.
所以我尝试实现我自己的lrange功能:
def lrange(start = 0, stop, step = 1):
ret = []
while start < stop:
ret.append(start)
start += step
return ret
Run Code Online (Sandbox Code Playgroud)
给我一个"非默认参数遵循默认参数"解释器错误.
如果我看看Python的范围()似乎是可能的.
我发布这个问题主要是因为我想知道是否/如何自己实现具有这种签名的功能
当我第一次开始学习Python时出现了这个问题,我认为在这里记录这个方法是值得的.只有一个检查用于模拟原始行为.
def list_range(start, stop=None, step=1):
if stop is None:
start, stop = 0, start
return list(range(start, stop, step))
Run Code Online (Sandbox Code Playgroud)
我认为这个解决方案比使用所有关键字参数或者更优雅*args.
使用Sentinel
获得此权利的关键是使用sentinel对象来确定是否获得第二个参数,如果没有,则在将第一个参数移动到第二个参数时将默认值提供给第一个参数.
None,作为Python的空值,是一个很好的最佳实践哨兵,检查它的惯用方法是使用关键字is,因为它是一个单例.
带有正确文档字符串的示例,声明签名/ API
def list_range(start, stop=None, step=1):
'''
list_range(stop)
list_range(start, stop, step)
return list of integers from start (default 0) to stop,
incrementing by step (default 1).
'''
if stop is None:
start, stop = 0, start
return list(range(start, stop, step))
Run Code Online (Sandbox Code Playgroud)
示范
>>> list_range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list_range(5, 10)
[5, 6, 7, 8, 9]
>>> list_range(2, 10, 2)
[2, 4, 6, 8]
Run Code Online (Sandbox Code Playgroud)
如果没有给出参数,它会引发错误,这与全关键字解决方案不同.
顺便说一下,我希望这只是从读者的理论角度考虑,我不相信这个功能值得维护,除非在中心规范位置使用,使代码在Python 2和3之间交叉兼容. Python,使用内置函数将范围具体化为列表非常简单:
Python 3.3.1 (default, Sep 25 2013, 19:29:01)
[GCC 4.7.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)
我从来没有真正考虑过这个问题,但首先,为了解决你的问题,你应该能够在你的代码中用list(range(...))包装range(...).
使用关键字参数,您可以实现类似的签名,因为在调用时不需要指定实际的键
def f(x=None, y=None, z=None):
print x, y, z
f(1, 2, 3)
#output: 1 2 3
Run Code Online (Sandbox Code Playgroud)
然后,您可以检查值以确定应如何处理它们.所以要模仿范围
def f(x=None, y=None, z=None):
if z is not None: # then all values were assigned
return range(x, y, z)
elif y is not None: # then a start stop was set
return range(x, y):
else: # only one value was given
return range(x)
Run Code Online (Sandbox Code Playgroud)
这里的要点不是作为范围的包装器(如上所述,只是使用列表),而是要提供一些洞察力,确定是否真的试图模仿自定义内容范围的内置范围签名.
另外请记住,这不是一个完整的解决方案,f(z=1)可能会导致上述问题,因此您希望[kwarg]在检查所需时为每个提供合理的默认值kwarg
def f(x=0, y=None, z=1):
if y is None:
raise Exception()
return range(x, y, z)
Run Code Online (Sandbox Code Playgroud)
对具有签名的python方法([start],stop,[step])会更有洞察力
| 归档时间: |
|
| 查看次数: |
1148 次 |
| 最近记录: |