„id” to zła nazwa zmiennej w Pythonie

141

Dlaczego nazwanie zmiennej idw Pythonie jest złe ?

Brian Buck
źródło
33
Większość ludzi dodaje podkreślenie do identyfikatorów, które kolidują z elementami wbudowanymi / słowami kluczowymi: id_, map_, list_, filter_ itp.
cdleary
3
Bardziej przebiegłym rozwiązaniem byłoby użycie zmiennej ID.
Simon Kuang,
46
Lepszym pytaniem byłoby… Jaki genialny pomysł przy użyciu tak powszechnej, ogólnej nazwy dla funkcji wbudowanej był dobrym pomysłem?
Podstawowy

Odpowiedzi:

143

id() to podstawowa wbudowana:

Pomoc dotycząca funkcji wbudowanej idw module __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.)

Ogólnie rzecz biorąc, używanie nazw zmiennych, które przesłaniają słowo kluczowe lub funkcję wbudowaną w dowolnym języku, jest złym pomysłem, nawet jeśli jest dozwolone.

Kevin Little
źródło
3
OK, jeśli chodzi o „id”, masz rację, ale komentarz „ogólnie…” nadal obowiązuje, nie sądzisz?
Kevin Little,
5
Z pewnością unikałbym tego w przypadku modułów globalnych. W przypadku zmiennych ograniczonych do zakresu lokalnego, więc możesz zobaczyć, że ta sama funkcja nigdy nie będzie potrzebować funkcji wbudowanej, nie jest to coś, o co bym się martwił.
bobince
@Caramdir: Dobry haczyk, idbył kiedyś przeznaczony do usunięcia, ale ostatecznie zdecydowali się go nie usuwać. Nie mogę już edytować swojego oryginalnego komentarza, więc usunę go, aby w przyszłości nie wprowadzać ludzi w błąd.
Eli Courtwright,
20
@EliCourtwright Szkoda, że ​​go nie usunęli. Co za słabo nazwana metoda! Ogólna, powszechna nazwa używana w tysiącach miejsc (tam, gdzie kontekst nadaje znaczenie). Więc ktoś zdecydował się użyć go jako nazwy globalnej, gdzie nie ma kontekstu?
Podstawowy
2
O dziwo, własny samouczek Google dotyczący wyrażeń regularnych Pythona ( developers.google.com/edu/python/regular-expressions ) używa str = 'an example word:cat!!'. Czy w którymś z PEP jest coś, co mówi, że nie rób tego?
słowa z
57

W PEP 8 - Przewodnik po stylach dla kodu w języku Python następujące wskazówki pojawiają się w sekcji Opisowe: Style nazewnictwa :

  • single_trailing_underscore_ : używany przez konwencję, aby uniknąć konfliktów ze słowem kluczowym Python, np

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

Tak więc, odpowiadając na pytanie, przykładem zastosowania tej wytycznej jest:

id_ = 42

Umieszczenie końcowego podkreślenia w nazwie zmiennej wyjaśnia intencję (dla osób zaznajomionych z wytycznymi w PEP 8).

DavidRR
źródło
1
To nie jest odpowiedź na rzeczywiste pytania, ale +1 dla PEP-8 Naming Convention
EGE
Dobra rada, ale idjest elementem wbudowanym, a nie słowem kluczowym, a to nie wyjaśnia, dlaczego źle jest cienia element wbudowany.
wjandrea
51

idjest funkcją wbudowaną, która podaje tożsamość obiektu (który jest również adresem pamięci w CPythonie). Jeśli nazwiesz jedną ze swoich funkcji id, będziesz musiał powiedzieć, builtins.idaby uzyskać oryginał (lub __builtins__.idw CPythonie). Globalna zmiana nazwy idjest myląca z wyjątkiem małego skryptu.

Jednak ponowne użycie wbudowanych nazw jako zmiennych nie jest takie złe, o ile jest to użycie lokalne. Python ma wiele wbudowanych funkcji, które (1) mają pospolite nazwy i (2) i tak niewiele będziesz używać. Używanie ich jako zmiennych lokalnych lub elementów obiektu jest OK, ponieważ z kontekstu wynika, co robisz:

Przykład:

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

Niektóre wbudowane funkcje o kuszących nazwach:

  • id
  • file
  • list, dict
  • map
  • all, any
  • complex, int
  • dir
  • input
  • slice
  • buffer
  • sum
  • min, max
  • object
Nathan Shively-Sanders
źródło
8
PEP 8 , który został zaktualizowany 1 sierpnia 2013 r., Radzi teraz unikać potencjalnego nieporozumień poprzez zwykłe dołączanie _do nazwy zmiennej. Zobacz moją odpowiedź .
DavidRR
1
Warto zauważyć, że idfunkcja zwracająca adres pamięci obiektu jest szczegółem implementacji CPythona. Warto również zauważyć, że funkcja jest wymagana tylko do zwrócenia innej liczby dla dowolnych dwóch istniejących obiektów. Jeśli obiekt jest odśmiecany, jego identyfikator może zostać odtworzony.
Zac Crites
@Zac Thanks! Zredagowałem odpowiedź, dodając punkt dotyczący adresu pamięci i link, aby ludzie mogli przeczytać więcej.
wjandrea
42

Mógłbym powiedzieć coś niepopularnego: id()jest to raczej wyspecjalizowana wbudowana funkcja, która jest rzadko używana w logice biznesowej. Dlatego nie widzę problemu w używaniu go jako nazwy zmiennej w ciasnej i dobrze napisanej funkcji, gdzie jest jasne, że id nie oznacza funkcji wbudowanej.

Sebastian Rittau
źródło
1
W odpowiedzi na:> id jest raczej wyspecjalizowaną wbudowaną funkcją>, która jest rzadko używana w logice biznesowej>. Dlatego nie widzę> problemu w używaniu go jako zmiennej> nazwa w ciasnej i dobrze napisanej> funkcji, więc jasne jest, że id> nie oznacza funkcji wbudowanej. Chociaż to prawda, prawdopodobnie dobrym pomysłem jest bardziej szczegółowe określenie nazwy tej zmiennej niż zwykłe „id”. Wiele rzeczy ma identyfikatory (zwłaszcza jeśli pracujesz z RDBMS), a jak mówi druga linia książki Tima Petersa The Zen of Python :> Wyraźne jest lepsze niż ukryte. Resztę zobacz biegiem:import this
Ross
9
Jednak nadal bym tego unikał, jeśli to w ogóle możliwe. Nawet jeśli nie ma innego powodu niż nie słyszeć narzekania współpracowników. :-)
Jason Baker
1
Całkowicie się zgadzam: nazwanie zmiennej „id” w małej funkcji (a tym samym zakresie) jest nieszkodliwe. idZresztą bardzo niewiele osób korzysta z wbudowanego. Powiedział, że zajęło mi to trochę czasu, gdy kolega zastąpił listwbudowaną zmienną lokalną. Zatem ogólna zasada, o której wspominają inni, nadal ma sens.
silviot
5

Źle jest nazywać każdą zmienną po funkcji wbudowanej. Jednym z powodów jest to, że może to być mylące dla czytelnika, który nie wie, że nazwa została zastąpiona.

Toni Ruža
źródło
2

idto funkcja wbudowana w Pythonie. Przypisanie wartości idspowoduje przesłonięcie funkcji. Najlepiej jest albo dodać przedrostek jak w, some_idalbo użyć go z inną wielkością niż wID .

Wbudowana funkcja przyjmuje pojedynczy argument i zwraca liczbę całkowitą dla adresu pamięci przekazanego obiektu (w CPythonie).

>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760
Brian Buck
źródło
2
zwróć uwagę, że możesz nazwać atrybut klasy lub metodę „id”, która nie wpłynie na wbudowaną funkcję.
Toni Ruža,
0

Ponieważ jest to nazwa funkcji wbudowanej.

ahockley
źródło
0

Inni wspominali, że jest to mylące, ale chcę wyjaśnić, dlaczego . Oto przykład oparty na prawdziwej historii. Zasadniczo piszę klasę, która przyjmuje idparametr, ale później próbuję użyć wbudowanej id.

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)

Oczekiwany wynik:

Created Employee 'Taylor Swift' at 0x7efde30ae910

Rzeczywista wydajność:

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

Co? Gdzie próbuję zadzwonić do int? To wszystko jest wbudowane ...

Gdybym to nazwał badge_idlub id_, nie miałbym tego problemu.

wjandrea
źródło
-6

Ponieważ Python jest językiem dynamicznym, nadawanie zmiennej i funkcji tej samej nazwy zwykle nie jest dobrym pomysłem. id () jest funkcją w Pythonie, więc nie zaleca się używania zmiennej o nazwie id. Mając to na uwadze, dotyczy to wszystkich funkcji, których możesz użyć ... zmienna nie powinna mieć takiej samej nazwy jak funkcja.

Koteczek
źródło
3
„Ponieważ Python jest językiem dynamicznym, nadawanie zmiennej i funkcji tej samej nazwy zazwyczaj nie jest dobrym pomysłem”. - Nie można nadać zmiennej i funkcji tej samej nazwy. Nie ma to nic wspólnego z tym, że jest to język dynamiczny. Jeśli masz na myśli nadanie właściwościom takich samych nazw, jak innym obiektom w tym samym zakresie, ja też się nie zgadzam. Możesz mieć klasę o nazwie „Key”, instancję tej klasy o nazwie „key” oraz właściwość innego obiektu o nazwie „key”, np. „Door.key”.
Purrell