最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Why does range() in Python require positional arguments when called, but keyword arguments in a match statement? - Stack Overflo

programmeradmin0浏览0评论

All examples tested using Python 3.13.2 on Windows 10.

When calling range(), I must use positional arguments, or otherwise I get an exception.

>>> range(2, 5)
range(2, 5)
>>> range(start=2, stop=5)
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    range(start=2, stop=5)
    ~~~~~^^^^^^^^^^^^^^^^^
TypeError: range() takes no keyword arguments

However, when trying to match pattern, it only works with keyword arguments instead.

>>> match range(2, 5):
...     case range(0, y, 1):
...         print('1 argument')
...     case range(x, y, 1):
...         print('2 arguments')
...     case range(x, y, z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    case range(0, y, 1):
         ~~~~~^^^^^^^^^
TypeError: range() accepts 0 positional sub-patterns (3 given)
>>> match range(2, 5):
...     case range(start=0, stop=y, step=1):
...         print('1 argument')
...     case range(start=x, stop=y, step=1):
...         print('2 arguments')
...     case range(start=x, stop=y, step=z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
2 arguments

Interestingly, those arguments can't just use any arbitrary names. Using different ones causes the pattern match to fail, without raising an exception.

>>> match range(2, 5):
...     case range(aaa=0, bbb=y, ccc=1):
...         print('1 argument')
...     case range(aaa=x, bbb=y, ccc=1):
...         print('2 arguments')
...     case range(aaa=x, bbb=y, ccc=z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
none of the above

All examples tested using Python 3.13.2 on Windows 10.

When calling range(), I must use positional arguments, or otherwise I get an exception.

>>> range(2, 5)
range(2, 5)
>>> range(start=2, stop=5)
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    range(start=2, stop=5)
    ~~~~~^^^^^^^^^^^^^^^^^
TypeError: range() takes no keyword arguments

However, when trying to match pattern, it only works with keyword arguments instead.

>>> match range(2, 5):
...     case range(0, y, 1):
...         print('1 argument')
...     case range(x, y, 1):
...         print('2 arguments')
...     case range(x, y, z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    case range(0, y, 1):
         ~~~~~^^^^^^^^^
TypeError: range() accepts 0 positional sub-patterns (3 given)
>>> match range(2, 5):
...     case range(start=0, stop=y, step=1):
...         print('1 argument')
...     case range(start=x, stop=y, step=1):
...         print('2 arguments')
...     case range(start=x, stop=y, step=z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
2 arguments

Interestingly, those arguments can't just use any arbitrary names. Using different ones causes the pattern match to fail, without raising an exception.

>>> match range(2, 5):
...     case range(aaa=0, bbb=y, ccc=1):
...         print('1 argument')
...     case range(aaa=x, bbb=y, ccc=1):
...         print('2 arguments')
...     case range(aaa=x, bbb=y, ccc=z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
none of the above
Share Improve this question asked 2 days ago Qba23Qba23 111 silver badge2 bronze badges New contributor Qba23 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

2 Answers 2

Reset to default 3

case range(start=0, stop=y, step=1): isn't a function call with keyword arguments. It's a class pattern, which has confusingly similar syntax but means something completely different.

The actual meaning of case range(start=0, stop=y, step=1): is

  • match an instance of the range class (yes, that's a class),
  • which has attributes start, stop, and step,
  • and match those attributes against patterns 0, y, and 1 respectively.

0 and 1 are literal patterns, so they'll check that the range's start and step attributes are equal to 0 and 1 respectively. y is a capture pattern, so it'll assign the range's stop attribute to the y variable.

At no point in this process does a class pattern actually care what arguments a class's constructor takes. It only cares about the type and attributes of the object being matched.

Python's range() function and the match statement treat ranges differently. You create a range using range(start, stop, step) (only positional arguments). But when you match a range in a case statement, you must use case range(start=x, stop=y, step=z). It's a weird quirk, but that's how it works. Don't try to use other keyword names or positional arguments in the case – it won't work.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论