Co oznacza ukośnik w danych wyjściowych help ()?

148

Co /oznacza w helpdanych wyjściowych Pythona 3.4 rangeprzed nawiasem zamykającym?

>>> 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.

                                        ...
Joschua
źródło

Odpowiedzi:

185

Oznacza koniec parametrów tylko pozycyjnych , parametrów, których nie można używać jako parametrów słów kluczowych. Przed Pythonem 3.8 takie parametry można było określić tylko w C API.

Oznacza to, że keyargument do __contains__można przekazać tylko przez funkcję position ( range(5).__contains__(3)), a nie jako słowo kluczowe argument ( range(5).__contains__(key=3)), co można zrobić z argumentami pozycyjnymi w funkcjach czystego języka Python.

Zobacz także dokumentację Argument Clinic :

Aby oznaczyć wszystkie parametry jako tylko pozycyjne w Argument Clinic, dodaj osobny /wiersz po ostatnim parametrze, z wcięciem tak samo jak wiersze parametrów.

oraz (bardzo niedawny dodatek do) Python FAQ :

Ukośnik na liście argumentów funkcji oznacza, że ​​parametry przed nią są tylko pozycyjne. Parametry tylko pozycyjne to te, które nie mają nazwy do użytku zewnętrznego. Po wywołaniu funkcji, która akceptuje parametry tylko pozycyjne, argumenty są mapowane na parametry wyłącznie na podstawie ich pozycji.

Składnia jest teraz częścią specyfikacji języka Python, od wersji 3.8 , patrz PEP 570 - Parametry tylko pozycyjne języka Python . Przed PEP 570 składnia była już zarezerwowana do ewentualnego przyszłego włączenia do Pythona, zobacz PEP 457 - Składnia parametrów tylko pozycyjnych .

Parametry tylko pozycyjne mogą prowadzić do czystszych i bardziej przejrzystych interfejsów API, czynić implementacje czysto Pythonowych modułów tylko w języku C bardziej spójne i łatwiejsze w utrzymaniu, a ponieważ parametry tylko pozycyjne wymagają bardzo niewielkiego przetwarzania, prowadzą do szybszego kodu Pythona.

Martijn Pieters
źródło
22

Sam zadałem to pytanie. :) Dowiedziałem się, że /pierwotnie zaproponował go Guido tutaj .

Alternatywna propozycja: co powiesz na użycie „/”? Jest to przeciwieństwo „*”, które oznacza „argument słowa kluczowego”, a „/” nie jest nowym znakiem.

Wtedy jego propozycja wygrała .

Heh. Jeśli to prawda, wygrywa moja propozycja „/”:

 def foo(pos_only, /, pos_or_kw, *, kw_only): ...

Myślę, że bardzo istotnym dokumentem na ten temat jest PEP 570 . Gdzie sekcja podsumowania wygląda ładnie.

Podsumować

Przypadek użycia określi, których parametrów użyć w definicji funkcji:

 def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

Jako wskazówka:

Użyj tylko pozycyjnego, jeśli nazwy nie mają znaczenia lub nie mają znaczenia, a jest tylko kilka argumentów, które będą zawsze przekazywane w tej samej kolejności. Używaj tylko słów kluczowych, gdy nazwy mają znaczenie, a definicja funkcji jest bardziej zrozumiała, gdy jest jawna w nazwach.


Jeśli funkcja kończy się na /

def foo(p1, p2, /)

Oznacza to, że wszystkie argumenty funkcjonalne są pozycyjne.

prosti
źródło
6
Wybór /tokena, ponieważ „to operacja odwrotna do *” pokazuje, że Python jest trochę szalony. To rodzaj synestezji.
Tomasz Gandor
6

Ukośnik (/) wskazuje, że wszystkie argumenty przed nim są argumentami wyłącznie pozycyjnymi. Funkcja argumentów tylko pozycyjnych została dodana w Pythonie 3.8 po zaakceptowaniu PEP 570 . Początkowo notacja ta została zdefiniowana w PEP 457 - Notacja dla notacji dla parametrów tylko pozycyjnych

Parametry w definicji funkcji przed ukośnikiem Foraward (/) są tylko pozycyjne, a parametry, po których następuje ukośnik (/), mogą być dowolnego rodzaju zgodnie ze składnią. Gdzie argumenty są mapowane tylko na parametry pozycyjne wyłącznie na podstawie ich pozycji podczas wywoływania funkcji. Przekazywanie parametrów tylko pozycyjnych przez słowa kluczowe (nazwę) jest nieprawidłowe.

Weźmy następujący przykład

def foo(a, b, / , x, y):
   print("positional ", a, b)
   print("positional or keyword", x, y)

Tutaj w powyższej definicji funkcji parametry a i b są tylko pozycyjne, podczas gdy x lub y mogą być pozycyjne lub kluczowe.

Następujące wywołania funkcji są prawidłowe

foo(40, 20, 99, 39)
foo(40, 3.14, "hello", y="world")
foo(1.45, 3.14, x="hello", y="world")

Ale następujące wywołanie funkcji nie jest prawidłowe, co powoduje wyjątek TypeError, ponieważ a, b nie są przekazywane jako argumenty pozycyjne zamiast tego przekazywane jako słowo kluczowe

foo(a=1.45, b=3.14, x=1, y=4)

TypeError: foo () otrzymało kilka argumentów tylko pozycyjnych przekazanych jako argumenty słów kluczowych: „a, b”

Wiele funkcji wbudowanych w Pythonie akceptuje tylko argumenty pozycyjne, w przypadku których przekazywanie argumentów przez słowo kluczowe nie ma sensu. Na przykład funkcja wbudowana len akceptuje tylko jeden argument pozycyjny (tylko). Gdy wywołanie len jako len (obj = "hello world") osłabia czytelność, sprawdź help (len).

>>> help(len)
Help on built-in function len in module builtins:

len(obj, /)
    Return the number of items in a container.

Parametry tylko pozycyjne sprawiają, że podstawowe funkcje biblioteki c / są łatwe w utrzymaniu. Pozwala to na zmianę nazw parametrów parametrów pozycyjnych w przyszłości bez ryzyka złamania kodu klienta używającego API

Wreszcie, parametry tylko pozycyjne pozwalają nam używać ich nazw w argumentach słów kluczowych o zmiennej długości. Sprawdź poniższy przykład

>>> 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}

Parametry tylko pozycyjne są lepiej wyjaśnione tutaj w Typy argumentów funkcji w pythonie: Parametry tylko pozycyjne

Składnia parametrów tylko pozycyjnych została oficjalnie dodana do pythona3.8. Zamówienie nowości python3.8 - pozycyjne tylko argumenty

Powiązane z PEP: PEP 570 - parametry tylko pozycyjne w języku Python

neotam
źródło