Pergunta

Sou bastante novo em linguagens de programação reais e Python é o meu primeiro.Eu conheço um pouco o Linux, o suficiente para conseguir um emprego de verão com ele (ainda estou no ensino médio) e, no trabalho, tenho muito tempo livre que estou usando para aprender Python.

Mas uma coisa está me incomodando.O que exatamente é diferente em Python quando você tem expressões como

x.__add__(y) <==> x+y
x.__getattribute__('foo') <==> x.foo

Eu sei o que os métodos fazem e outras coisas, e entendo o que eles fazem, mas minha pergunta é:Qual a diferença entre esses métodos de sublinhado duplo acima e seus equivalentes de aparência mais simples?

P.S., não me importo de receber palestras sobre história da programação; na verdade, acho muito útil saber :) Se esses são principalmente aspectos históricos do Python, sinta-se à vontade para começar a divagar.

Foi útil?

Solução

Bem, o poder para o programador é bom, então deve haver uma maneira de personalizar o comportamento. Como a sobrecarga do operador (__add__, __div__, __ge__, ...), Acesso de atributo (__getattribute__, __getattr__ (esses dois são diferentes), __delattr__, ...) etc. Em muitos casos, como operadores, os mapas de sintaxe usuais 1: 1 ao respectivo método. Em outros casos, existe um procedimento especial que em algum momento envolve chamar o respectivo método - por exemplo, __getattr__ é chamado apenas se o objeto não tiver o atributo solicitado e __getattribute__ não é implementado ou elevado AttributeError. E alguns deles são tópicos realmente avançados que o levam ao Deeeep na coragem do sistema de objetos e raramente são necessários. Portanto, não há necessidade de aprender todos eles, basta consultar a referência quando você precisar/deseja saber. Falando em referência, aqui está.

Outras dicas

Aqui está o criador de Python explicando isso:

... Em vez de desenvolver uma nova sintaxe para tipos especiais de métodos de classe (como inicializadores e destruidores), decidi que esses recursos poderiam ser tratados simplesmente exigindo __init__, __del__, e assim por diante. Esta convenção de nomenclatura foi retirada de C, onde os identificadores começando com sublinhados são reservados pelo compilador e geralmente têm significado especial (por exemplo, macros como __FILE__ no pré -processador C).

...

Também usei essa técnica para permitir que classes de usuários redefiniram o comportamento dos operadores da Python. Como observado anteriormente, o Python é implementado em C e usa tabelas de ponteiros de função para implementar vários recursos de objetos internos (por exemplo, "Obter atributo", "Add" e "Call"). Para permitir que esses recursos sejam definidos em classes definidas pelo usuário, mapeei os vários ponteiros de função para nomes de métodos especiais, como __getattr__, __add__, e __call__. Existe uma correspondência direta entre esses nomes e as tabelas de ponteiros de função que se deve definir ao implementar novos objetos Python em C.

Quando você inicia um método com dois sublinhados (e sem sublinhados finais), o Python confusão de nomes regras são aplicadas.Esta é uma maneira de simular vagamente o private palavra-chave de outras linguagens OO, como C++ e Java.(Mesmo assim, o método ainda não é tecnicamente privado da mesma forma que os métodos Java e C++ são privados, mas é "mais difícil de obter" de fora da instância.)

Métodos com dois sublinhados iniciais e dois finais são considerados métodos "integrados", ou seja, são usados ​​pelo intérprete e geralmente são implementações concretas de operadores sobrecarregados ou outras funcionalidades integradas.

Eles são usados ​​para especificar que o interpretador Python deve usá-los em situações específicas.

Por exemplo, o __add__ função permite que + operador para trabalhar para classes personalizadas.Caso contrário, você receberá algum tipo de erro não definido ao tentar adicionar.

De uma perspectiva histórica, os sublinhados iniciais têm sido frequentemente usados ​​como um método para indicar ao programador que os nomes devem ser considerados internos ao pacote/módulo/biblioteca que os define.Em linguagens que não fornecem um bom suporte para namespaces privados, o uso de sublinhados é uma convenção para emular isso.Em Python, quando você define um método chamado '__foo__' o programador de manutenção sabe pelo nome que algo especial está acontecendo e que não está acontecendo com um método chamado 'foo'.Se Python tivesse escolhido usar 'add' como método interno para sobrecarregar '+', então você nunca poderia ter uma classe com um método 'add' sem causar muita confusão.Os sublinhados servem como uma dica de que alguma mágica acontecerá.

Várias outras perguntas agora são marcadas como duplicatas desta pergunta, e pelo menos duas delas perguntam o que o __spam__ Os métodos são chamados, ou como a convenção é chamada, e nenhuma das respostas existentes cobre isso, então:

Na verdade, também não há nome oficial.

Muitos desenvolvedores os chamam de "métodos de Dunder", para "sublinhamento duplo".

Algumas pessoas usam o termo "métodos mágicos", mas isso é um tanto ambíguo entre os métodos de Dunder de significado, métodos especiais (veja abaixo) ou algo entre os dois.


é Um termo oficial "atributos especiais", que se sobrepõe de perto, mas não completamente, aos métodos de Dunder. o Modelo de dados O capítulo da referência nunca explica o que é um atributo especial, mas a idéia básica é que é pelo menos um dos seguintes:

  • Um atributo fornecido pelo próprio intérprete ou seu código incorporado, como __name__ em uma função.
  • Um atributo que faz parte de um protocolo implementado pelo próprio intérprete, como __add__ para o + operador, ou __getitem__ para indexação e fatia.
  • Um atributo que o intérprete pode procurar especialmente, ignorando a instância e indo direto para a classe, como __add__ novamente.

A maioria dos atributos especiais são métodos, mas não todos (por exemplo, __name__ não é). E a maioria usa a convenção "Dunder", mas não todos (por exemplo, o next Método sobre iteradores no Python 2.x).

Enquanto isso, a maioria dos métodos de Dunder são atributos especiais, mas não todos - em particular, não é tão incomum para o stdlib ou bibliotecas externas querer definir seus próprios protocolos que funcionam da mesma maneira, como o pickle protocolo.

Especulação Python foi influenciado por Algol68, Guido Possivelmente usado algol68 no Universidade de Amsterdã onde o Algol68 tem um semelhante "Regime Strapping"Chamado" Citação Stropping ". Em Algol68, o operadores, tipos e palavras -chave posso aparecer em um tipo de letra diferente (geralmente **negrito**, ou __sublinhado__), nos arquivos de focecode SourCecode, este tipo de letra é alcançado com citações, por exemplo, 'abs' (citando semelhante a citar em 'Wikitext')

Algol68 ⇒ Python (operadores mapeados para funções de membro)

  • 'e' ⇒ __and__
  • 'ou' ⇒ __or__
  • 'não' ⇒ não
  • 'entier' ⇒ __trunc__
  • 'shl' ⇒ __lshift__
  • 'shr' ⇒ __rshift__
  • 'upb' ⇒ __sizeof__
  • 'Long' ⇒ __long__
  • 'int' ⇒ __int__
  • 'real' ⇒ __float__
  • 'formato' ⇒ __format__
  • 'repr' ⇒ __repr__
  • 'Abs' ⇒ __abs__
  • 'menos' ⇒ __neg__
  • 'menos' ⇒ __sub__
  • 'mais' ⇒ __add__
  • 'vezes' ⇒ __mul__
  • 'mod' ⇒ __mod__
  • 'div' ⇒ __truediv__
  • 'sobre' ⇒ __div__
  • 'Up' ⇒ __pow__
  • 'IM' ⇒ Imag
  • 're' ⇒ real
  • 'conj' ⇒ conjugado

Em Algol68, estes foram referidos nomes ousados, por exemplo abdômen, mas "Under-under-Abs" __abs__ em Python.

Meus 2 centavos: ¢ então às vezes - como um fantasma - quando você corta e cola as aulas de python em um wiki, você vai reencarnar magicamente algol68's negrito palavras-chave. ¢

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top