O que a barra significa na saída help ()?

148

O que /significa o helpresultado da saída do Python 3.4 rangeantes do parêntese de fechamento?

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

Respostas:

185

Significa o fim dos parâmetros apenas posicionais , parâmetros que você não pode usar como parâmetros de palavras-chave. Antes do Python 3.8, esses parâmetros só podiam ser especificados na API C.

Isso significa que o keyargumento __contains__só pode ser passado por position ( range(5).__contains__(3)), não como argumento de palavra-chave ( range(5).__contains__(key=3)), algo que você pode fazer com argumentos posicionais em funções de python puro.

Consulte também a documentação da Argument Clinic :

Para marcar todos os parâmetros como somente posicionais na Argument Clinic, adicione um /em uma linha após o último parâmetro, recuado da mesma forma que as linhas de parâmetro.

e a (adição muito recente) à FAQ do Python :

Uma barra na lista de argumentos de uma função indica que os parâmetros anteriores a ela são apenas posicionais. Parâmetros somente posicionais são aqueles sem um nome utilizável externamente. Ao chamar uma função que aceita parâmetros somente posicionais, os argumentos são mapeados para parâmetros baseados apenas em sua posição.

A sintaxe agora faz parte da especificação da linguagem Python, a partir da versão 3.8 , consulte PEP 570 - Parâmetros somente de posição do Python . Antes do PEP 570, a sintaxe já estava reservada para possível inclusão futura no Python, consulte PEP 457 - Sintaxe para parâmetros apenas de posição .

Parâmetros somente posicionais podem levar a APIs mais limpas e claras, tornar as implementações em Python puro de módulos somente C mais consistentes e fáceis de manter, e como os parâmetros somente posicionais requerem muito pouco processamento, eles levam a um código Python mais rápido.

Martijn Pieters
fonte
22

Eu mesma fiz essa pergunta. :) Descobri que /foi originalmente proposto por Guido aqui .

Proposta alternativa: que tal usar '/'? É o oposto de '*', que significa "argumento da palavra-chave", e '/' não é um novo caractere.

Então sua proposta venceu .

Heh. Se isso for verdade, minha proposta '/' vence:

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

Penso que o documento muito relevante que cobre isso é o PEP 570 . Onde a seção de recapitulação parece legal.

Recapitular

O caso de uso determinará quais parâmetros usar na definição da função:

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

Como orientação:

Use apenas posicional se os nomes não importarem ou não tiverem significado e houver apenas alguns argumentos que sempre serão passados ​​na mesma ordem. Use apenas palavras-chave quando os nomes tiverem significado e a definição da função for mais compreensível ao ser explícita com os nomes.


Se a função terminar com /

def foo(p1, p2, /)

Isso significa que todos os argumentos funcionais são posicionais.

prosti
fonte
6
Escolhendo o /token, porque "é a operação inversa de *" shows, que o Python é um pouco louco. É um tipo de sinestesia.
Tomasz Gandor
6

Barra (/) indica que todos os argumentos anteriores a ele são apenas argumentos posicionais. O recurso de argumentos apenas posicionais foi adicionado no python 3.8 após a aceitação do PEP 570 . Inicialmente, essa notação foi definida no PEP 457 - Notação para notação para parâmetros somente posicionais

Os parâmetros na definição da função anterior à barra externa (/) são apenas posicionais e os parâmetros seguidos pela barra (/) podem ser de qualquer tipo, conforme a sintaxe. Onde os argumentos são mapeados para parâmetros posicionais apenas com base em sua posição ao chamar uma função. A passagem de parâmetros apenas de posição por palavras-chave (nome) é inválida.

Vamos dar o seguinte exemplo

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

Aqui, nos parâmetros de definição de função acima, a e b são apenas posicionais, enquanto x ou y podem ser posicionais ou de palavra-chave.

As chamadas de função a seguir são válidas

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

Porém, a chamada de função a seguir não é válida, o que gera uma exceção TypeError, já que a, b não são passados ​​como argumentos posicionais, e sim como palavra-chave

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

TypeError: foo () obteve alguns argumentos somente posicionais passados ​​como argumentos de palavra-chave: 'a, b'

Muitas funções embutidas em python aceitam apenas argumentos posicionais, onde passar argumentos por palavra-chave não faz sentido. Por exemplo, a função interna len aceita apenas um argumento posicional (apenas). Quando a chamada len como len (obj = "olá mundo") prejudica a legibilidade, consulte a ajuda (len).

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

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

Os parâmetros apenas posicionais facilitam a manutenção das funções subjacentes da c / biblioteca. Ele permite que nomes de parâmetros apenas de parâmetros posicionais sejam alterados no futuro sem risco de quebrar o código do cliente que usa API

Por último, mas não menos importante, apenas parâmetros posicionais nos permitem usar seus nomes para serem usados ​​em argumentos de palavras-chave de comprimento variável. Veja o exemplo a seguir

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

Parâmetros apenas posicionais são melhor explicados aqui em Tipos de argumentos de função em python: Parâmetros apenas posicionais

A sintaxe dos parâmetros apenas de posição foi adicionada oficialmente ao python3.8. Caixa que há de novo python3.8 - apenas argumentos posicionais

Relacionados com PEP: PEP 570 - Parâmetros somente de posição do Python

neotam
fonte