Что означает косая черта, когда help() перечисляет сигнатуры методов?
Что /
означает в help
выводе для range
Python 3.4 перед закрывающей скобкой?
>>> help(range)
Help on class range in module builtins:
class range(object)
| range(stop) -> range object
| range(start, stop[, step]) -> range object
|
| Return a virtual sequence of numbers from start to stop by step.
|
| Methods defined here:
|
| __contains__(self, key, /)
| Return key in self.
|
| __eq__(self, value, /)
| Return self==value.
...
Переведено автоматически
Ответ 1
Это означает конец только позиционных параметров, параметров, которые вы не можете использовать в качестве параметров ключевых слов. До Python 3.8 такие параметры могли быть указаны только в C API.
Это означает, что key
аргумент в __contains__
может быть передан только по позиции (range(5).__contains__(3)
), а не как аргумент ключевого слова (range(5).__contains__(key=3)
), что вы можете делать с позиционными аргументами в функциях чистого python.
Также смотрите Документацию по Argument Clinic:
Чтобы пометить все параметры как позиционные в аргументе Clinic, добавьте
/
в отдельной строке после последнего параметра с отступом, таким же, как у строк параметров.
и (совсем недавнее дополнение к) Часто задаваемые вопросы по Python:
Косая черта в списке аргументов функции обозначает, что параметры, предшествующие ей, являются только позиционными. Параметрами, используемыми только для позиции, являются параметры без имени, используемого извне. При вызове функции, которая принимает только позиционные параметры, аргументы сопоставляются параметрам исключительно на основе их положения.
Синтаксис теперь является частью спецификации языка Python, начиная с версии 3.8, см. PEP 570 – Параметры только для Python. До выхода PEP 570 синтаксис уже был зарезервирован для возможного включения в Python в будущем, см. PEP 457 - Синтаксис для параметров только позиционного типа.
Параметры только для позиции могут привести к созданию более чистых и понятных API, сделать реализации на чистом Python модулей, в противном случае предназначенных только для C, более согласованными и простыми в обслуживании, а поскольку параметры только для позиции требуют очень небольшой обработки, они приводят к более быстрому написанию кода на Python.
Ответ 2
Я сам задал этот вопрос. :) Узнал, что /
изначально это было предложено Guido в здесь .
Альтернативное предложение: как насчет использования '/' ? Это своего рода противоположность '*', что означает "аргумент ключевого слова", а '/' не является новым символом.
Тогда его предложение победило.
Хех. Если это правда, мое предложение '/' выигрывает:
def foo(pos_only, /, pos_or_kw, *, kw_only): ...
Я думаю, что очень подходящий документ, описывающий это, - это PEP 570.
Где раздел резюме выглядит неплохо.
Краткое описание
Вариант использования определит, какие параметры использовать в определении функции:
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
В качестве руководства:
Используйте positional-only, если имена не имеют значения или не имеют смысла, и есть только несколько аргументов, которые всегда будут передаваться в одном и том же порядке. Используйте ключевое слово только тогда, когда имена имеют значение, а определение функции более понятно из-за явного указания имен.
Если функция заканчивается /
def foo(p1, p2, /)
Это означает, что все функциональные аргументы являются позиционными.
Ответ 3
Прямая косая черта (/) указывает, что все аргументы перед ней являются аргументами только для позиции. Функция аргументов только для позиции была добавлена в python 3.8 после принятия PEP 570. Изначально это обозначение было определено в PEP 457 - Обозначение только для позиционных параметров
Параметры в определении функции, предшествующие косой черте (/), являются только позиционными, а параметры, за которыми следует косая черта (/), могут быть любого типа в соответствии с синтаксисом. Где аргументы сопоставляются только позиционным параметрам исключительно на основе их положения при вызове функции. Передача только позиционных параметров по ключевым словам (name) недопустима.
Давайте рассмотрим следующий пример
def foo(a, b, / , x, y):
print("positional ", a, b)
print("positional or keyword", x, y)
Здесь, в приведенном выше определении функции, параметры a и b являются только позиционными, в то время как x или y могут быть либо позиционными, либо ключевыми словами.
Допустимы следующие вызовы функций
foo(40, 20, 99, 39)
foo(40, 3.14, "hello", y="world")
foo(1.45, 3.14, x="hello", y="world")
Но следующий вызов функции недопустим, что вызывает исключение TypeError, поскольку a , b передаются не как позиционные аргументы, а как ключевое слово
foo(a=1.45, b=3.14, x=1, y=4)
TypeError: foo () получил некоторые аргументы только позиционного типа, переданные в качестве ключевого слова
аргументы: 'a, b'
Многие встроенные функции в python принимают только позиционные аргументы, где передача аргументов по ключевому слову не имеет смысла. Например, встроенная функция len принимает только один позиционный (единственный) аргумент, где вызов len как len(obj="hello world") ухудшает читаемость, проверьте справку (len).
>>> help(len)
Help on built-in function len in module builtins:
len(obj, /)
Return the number of items in a container.
Параметры только для позиции упрощают обслуживание базовых функций c / библиотеки. Это позволяет изменять имена параметров только для позиции в будущем без риска взлома клиентского кода, использующего API
И последнее, но не менее важное: параметры только позиционного типа позволяют нам использовать их имена в аргументах ключевого слова переменной длины. Проверьте следующий пример.
>>> def f(a, b, /, **kwargs):
... print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3) # a and b are used in two ways
10 20 {'a': 1, 'b': 2, 'c': 3}
Синтаксис параметров только для позиции был официально добавлен в python3.8. Проверка что нового в python3.8 - аргументы только для позиции
Связано с PEP: PEP 570 -- параметры только для Python