'id' é um nome de variável incorreto no Python


141

Por que é ruim nomear uma variável idno Python?


33
A maioria das pessoas anexar um sublinhado para identificadores que se chocam com builtins / palavras-chave: ID_, map_, list_, filter_, etc.
cdleary

3
Uma solução mais sorrateira seria usar uma variável ID.
Simon Kuang

45
Uma pergunta melhor seria ... Que gênio pensou que usar um nome genérico tão comum para uma função interna era uma boa idéia?
Basic

Respostas:


143

id() é um elemento fundamental fundamental:

Ajuda na função embutida idno módulo __builtin__:

id(...)

    id(object) -> integer

    Return the identity of an object.  This is guaranteed to be unique among
    simultaneously existing objects.  (Hint: it's the object's memory
    address.)

Em geral, o uso de nomes de variáveis ​​que eclipsam uma palavra-chave ou função interna em qualquer idioma é uma má idéia, mesmo que seja permitida.


3
OK, para 'id' você está certo, mas o comentário "em geral ..." ainda se aplica, você não acha?
22668 Kevin Little

5
Eu evitaria isso para módulos globais certamente. Para variáveis ​​restritas ao escopo local, para que você possa ver que a mesma função nem sempre precisará usar o builtin, não é algo que me preocuparia.
22909 bobince

@Caramdir: Boa captura, idfoi programada para remoção de uma só vez, mas eventualmente eles decidiram não removê-la. Não consigo mais editar meu comentário original, por isso o excluo para evitar confundir as pessoas no futuro.
precisa saber é o seguinte

20
@EliCourtwright Eu gostaria que eles o tivessem removido. Que método mal nomeado! Um nome genérico comum usado em milhares de lugares (onde o contexto dá sentido). Então, alguém decidiu usá-lo como um nome global onde não há contexto?
Basic

2
Surpreendentemente, o próprio tutorial de regex em Python do Google ( developers.google.com/edu/python/regular-expressions ) usa str = 'an example word:cat!!'. Existe algo em algum dos PEPs que diz não fazer isso?
wordsforthewise

57

No PEP 8 - Guia de Estilo para Código Python , a seguinte orientação aparece na seção Descritiva: Estilos de Nomenclatura :

  • single_trailing_underscore_ : usado por convenção para evitar conflitos com a palavra-chave Python, por exemplo

    Tkinter.Toplevel(master, class_='ClassName')

Portanto, para responder à pergunta, um exemplo que aplica essa diretriz é:

id_ = 42

A inclusão do sublinhado à direita no nome da variável torna clara a intenção (para aqueles familiarizados com as orientações do PEP 8).


1
Isso não responder à pergunta real, mas um para a convenção de nomenclatura PEP-8
EGE

Um bom conselho, mas idé um componente interno, não uma palavra-chave, e isso não explica por que é ruim ocultar um componente interno.
wjandrea

51

idé uma função interna que fornece a identidade de um objeto (que também é seu endereço de memória no CPython). Se você nomear uma de suas funções id, terá que dizer builtins.idpara obter a original (ou __builtins__.idno CPython). Renomear idglobalmente é confuso em qualquer coisa, menos em um pequeno script.

No entanto, reutilizar nomes internos como variáveis ​​não é tão ruim, desde que o uso seja local. O Python possui muitas funções internas que (1) têm nomes comuns e (2) você não utilizará muito de qualquer maneira. Usar estas como variáveis ​​locais ou como membros de um objeto é bom porque é óbvio, por contexto, o que você está fazendo:

Exemplo:

def numbered(filename):
    with open(filename) as file:
        for i, input in enumerate(file):
            print("%s:\t%s" % (i, input), end='')

Alguns built-ins com nomes tentadores:

  • id
  • file
  • list, dict
  • map
  • all, any
  • complex, int
  • dir
  • input
  • slice
  • buffer
  • sum
  • min, max
  • object

8
O PEP 8 , que foi atualizado em 01 de agosto de 2013, agora aconselha a evitar possíveis confusões simplesmente anexando _ao nome da variável. Por favor, veja minha resposta .
precisa saber é o seguinte

1
Vale ressaltar que a idfunção que retorna o endereço de memória de um objeto é um detalhe de implementação do CPython. Também é importante notar que a função é necessária apenas para retornar um número diferente para quaisquer dois objetos existentes . Se um objeto for coletado de lixo, seu ID poderá ser reciclado.
Zac Crites 27/03

@Zac Thanks! Editei a resposta para adicionar esse ponto sobre o endereço da memória e um link para que as pessoas possam ler mais.
wjandrea

42

Eu poderia dizer algo impopular aqui: id()é uma função interna bastante especializada que raramente é usada na lógica de negócios. Portanto, não vejo problema em usá-lo como um nome de variável em uma função rígida e bem escrita, onde fica claro que id não significa a função interna.


1
Em resposta a:> id é uma função interna bastante especializada que raramente é usada em lógica de negócios. Portanto, não vejo problema em usá-lo como um nome de variável em uma função> apertada e bem escrita, onde é claro que id> não significa a função interna. Embora isso seja verdade, provavelmente é uma boa idéia ser mais específico com esse nome de variável do que simplesmente "id". Muitas coisas têm IDs (especialmente se você estiver trabalhando com um RDBMS) e, como a segunda linha do The Zen of Python de Tim Peters nos diz:> Explícito é melhor que implícito. Veja o resto executando:import this
Ross

9
Eu ainda o evitaria, se possível. Mesmo que por nenhuma outra razão senão não ouvir os colegas reclamando. :-)
Jason Baker

1
Concordo plenamente: nomear uma variável "id" em uma função pequena (e, portanto, escopo) é inofensivo. Muito poucas pessoas usam o idbuiltin de qualquer maneira. Dito isto, demorei um tempo quando um colega substituiu o listinterno por uma variável local. Portanto, a regra geral que outras pessoas mencionam ainda faz sentido.
silviot

5

É ruim nomear qualquer variável após uma função interna. Uma das razões é porque pode ser confuso para um leitor que não sabe que o nome foi substituído.


2

idé uma função interna do Python. A atribuição de um valor idsubstituirá a função. É melhor adicionar um prefixo como em some_idou usá-lo em uma capitalização diferente como em ID.

A função interna usa um único argumento e retorna um número inteiro para o endereço de memória do objeto que você passou (no CPython).

>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760

2
observe que você pode nomear um atributo de classe ou método 'id', que não toque na função interna.
Toni Ruža 16/09/08


0

Outros mencionaram que é confuso, mas quero expandir o porquê . Aqui está um exemplo, com base em uma história verdadeira. Basicamente, escrevo uma classe que aceita um idparâmetro, mas depois tento usar o incorporado idmais tarde.

class Employee:
    def __init__(self, name, id):
        """Create employee, with their name and badge id."""
        self.name = name
        self.id = id
        # ... lots more code, making you forget about the parameter names
        print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))

tay = Employee('Taylor Swift', 1985)

Saída esperada:

Created Employee 'Taylor Swift' at 0x7efde30ae910

Saída real:

Traceback (most recent call last):
  File "company.py", line 9, in <module>
    tay = Employee('Taylor Swift', 1985)
  File "company.py", line 7, in __init__
    print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))
TypeError: 'int' object is not callable

Hã? Onde estou tentando chamar um int? Esses são todos os ...

Se eu o nomeasse badge_idou id_não teria esse problema.


-6

Como python é uma linguagem dinâmica, geralmente não é uma boa idéia atribuir o mesmo nome a uma variável e uma função. id () é uma função em python, por isso é recomendável não usar uma variável chamada id. Tendo isso em mente, isso se aplica a todas as funções que você pode usar ... uma variável não deve ter o mesmo nome que uma função.


3
"Como o python é uma linguagem dinâmica, geralmente não é uma boa idéia atribuir o mesmo nome a uma variável e uma função". - Você não pode atribuir uma variável e uma função ao mesmo nome. Nada a ver com ser uma linguagem dinâmica. Se você quer dizer dar às propriedades os mesmos nomes que outros objetos no mesmo escopo, eu também discordo. Você pode ter uma classe chamada "Key", uma instância dessa classe chamada "key" e uma propriedade de outro objeto chamado "key", por exemplo, "door.key".
Purrell
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.