range non-default parameter follows default one

大城市里の小女人 提交于 2019-12-01 03:55:22

I think the question is based on a wrong premise:

I understand that the fact it is implemented in C probably allows for behavior that would be a violation in Pythonland.

It's implemented in C but the behaviour isn't a violation in "Pythonland". The signature in the documentation is just incorrect (not actually incorrect, it's an approximation of the "real signature" - that can be easily understood).

For example range doesn't even support named parameters - but according to the documentation it should:

>>> range(stop=10)
TypeError: range() does not take keyword arguments

So the implementation is more along the lines of:

class range(object):
    def __init__(self, *args):
        start, step = 0, 1
        if len(args) == 1:
            stop = args[0]
        elif len(args) == 2:
            start, stop = args
        elif len(args) == 3:
            start, stop, step = args

That's valid Python and (roughly) does what range internally does (the actual implementation (CPython, Python 3.6.1) could be slightly different so don't take that class to seriously).

However a signature like range(*args) is probably not really helpful for users (especially new users that don't even know what *args means). Having a documentation that says range has 2 signatures: range(stop) and range(start, stop[, step]) may not be (technically) accurate but it "explains" how the signature is interpreted.


As for the why: I don't have any creditable sources but I quickly scanned my code:

I use range(stop) much more often than range(start, stop) or range(start, stop, step). So the one argument case was probably special and common enough to have a convenience for it. It would be pretty annoying to always write range(0, stop) all over the place.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!