Naprawdę nie mogę wymyślić żadnego powodu, dla którego python potrzebuje del
słowa kluczowego (a większość języków wydaje się nie mieć podobnego słowa kluczowego). Na przykład zamiast usuwać zmienną, można ją po prostu przypisać None
. Podczas usuwania ze słownika del
można dodać metodę.
Czy jest jakiś powód, aby pozostawać del
w Pythonie, czy też jest to pozostałość po czasach, w których Python zbierał śmieci?
python
dictionary
python-internals
del
Jason Baker
źródło
źródło
del
.del
nie jest to pozostałość po śmieciach, ponieważ zawsze można to miećused = None
. Po prostu zawsze warto mieć określoną składnię. Ponieważ mamy teraz cylindryczny GC, przypadki, w których chcesz użyć jednego z nich, są niewielkie.ERASE
(zabijają określone zmienne) iCLEAR
(zabijają wszystkie zmienne)Odpowiedzi:
Po pierwsze, możesz usuwać inne rzeczy oprócz zmiennych lokalnych
Oba powinny być wyraźnie przydatne. Po drugie, użycie
del
zmiennej lokalnej sprawia, że intencja jest bardziej przejrzysta. Porównać:do
Wiem, że w tym przypadku
del foo
chodzi o usunięcie zmiennej z zakresu. Nie jest jasne, czyfoo = None
to robi. Gdyby ktoś właśnie przydzieliłfoo = None
, mógłbym pomyśleć, że to martwy kod. Ale od razu wiem, codel foo
próbował zrobić ktoś, kto koduje .źródło
del
używane w obliczeniach wymagających dużej ilości pamięci, ale kiedy go zobaczyłem, natychmiast zrozumiałem, dlaczego jest to konieczne.del
sygnału do wyrażenia intencji (ponieważ komentarz mógłby zrobić to samo bez dodawania do języka), ale przypuszczam, że to najlepsza odpowiedź.len()
funkcję w ten sam sposób. W takim przypadku kwestia mogła zostać zamknięta w oparciu o opinię lub nawet smak. Python po prostu ma tendencję do dostarczania prymitywów dla podstawowych operacji zamiast polegać na metodach.Jest ta część tego, co
del
robi (z Python Language Reference ):Przypisanie
None
do nazwy nie usuwa wiązania nazwy z przestrzeni nazw.(Przypuszczam, że może być trochę debaty na temat tego, czy usunięcie wiązania nazwy jest rzeczywiście przydatne , ale to inne pytanie.)
źródło
del
usuwa powiązanie nazwy, ponieważ zasugerował przypisanieNone
jako alternatywy.NameError
. Greg Hewgill czyni to bardzo rozróżnieniem. To właśnie to rozróżnienie sprawia, że stwierdzenie, co plakat „wyraźnie” rozumiał, jest dla mnie niejasne.Jednym z miejsc, które uważam za
del
przydatne, jest usuwanie obcych zmiennych w pętlach:Teraz możesz być pewien, że x nie zostanie zdefiniowane, jeśli użyjesz go poza pętlą for.
źródło
del
linia ma być wcięta (tj. Część pętli)?NameError: name 'x' is not defined
, że lista będzie pusta.Usunięcie zmiennej różni się od ustawienia jej na Brak
Usuwanie nazw zmiennych za pomocą
del
prawdopodobnie jest rzadkie, ale jest to coś, czego nie można by w prosty sposób osiągnąć bez słowa kluczowego. Jeśli możesz utworzyć nazwę zmiennej, pisząca=1
, fajnie jest teoretycznie cofnąć to, usuwając.W niektórych przypadkach może to ułatwić debugowanie, ponieważ próba uzyskania dostępu do usuniętej zmiennej wywoła błąd NameError.
Możesz usunąć atrybuty instancji klasy
Python pozwala pisać coś takiego:
Jeśli zdecydujesz się dynamicznie dodawać atrybuty do instancji klasy, z pewnością chcesz mieć możliwość cofnięcia jej poprzez napisanie
źródło
Istnieje konkretny przykład tego, kiedy powinieneś używać
del
(mogą być inne, ale wiem o tym z jednej ręki), kiedy używaszsys.exc_info()
do sprawdzenia wyjątku. Ta funkcja zwraca krotkę, typ zgłoszonego wyjątku, komunikat i komunikat śledzenia.Pierwsze dwie wartości są zwykle wystarczające do zdiagnozowania błędu i działania na jego podstawie, ale trzecia zawiera cały stos wywołań między miejscem zgłoszenia wyjątku a momentem przechwycenia wyjątku. W szczególności, jeśli robisz coś takiego
traceback
tb
kończy się w lokalach stosu wywołań, tworząc cykliczne odwołanie, którego nie można wyrzucić śmieci. Dlatego ważne jest, aby:aby przerwać cykliczne odniesienie. W wielu przypadkach, w których chciałbyś zadzwonić
sys.exc_info()
, np. W przypadku magii metaklasy, funkcja traceback jest przydatna, więc musisz upewnić się, że ją wyczyściłeś, zanim ewentualnie opuścisz program obsługi wyjątków. Jeśli nie potrzebujesz śledzenia, powinieneś go natychmiast usunąć lub po prostu wykonaj:Aby uniknąć tego wszystkiego razem.
źródło
Po prostu inne myślenie.
Podczas debugowania aplikacji http we frameworku takim jak Django stos wywołań pełen niepotrzebnych i pomieszanych zmiennych używanych poprzednio, szczególnie gdy jest to bardzo długa lista, może być bardzo bolesny dla programistów. więc w tym momencie przydatne może być kontrolowanie przestrzeni nazw.
źródło
Bezpośrednie użycie „del” jest również lepszą praktyką niż przypisywanie zmiennej do None. Jeśli spróbujesz usunąć zmienną, która nie istnieje, pojawi się błąd czasu wykonywania, ale jeśli spróbujesz ustawić zmienną, która nie istnieje na Brak, Python po cichu ustawi nową zmienną na Brak, pozostawiając zmienną chciałem usunąć tam, gdzie to było. Więc del pomoże ci wcześniej złapać swoje błędy
źródło
Aby dodać kilka punktów do powyższych odpowiedzi:
del x
Definicja
x
wskazujer -> o
(odniesienier
wskazujące na obiekto
), aledel x
zmienia sięr
raczej niżo
. Jest to operacja na odwołaniu (wskaźniku) do obiektu, a nie na obiekcie powiązanymx
. Kluczowe jest tutaj rozróżnienie międzyr
io
.locals()
.globals()
jeślix
należy tam.x
należy, a nie na gdziex
wskazuje. Jedyną fizyczną zmianą w pamięci jest to. Na przykład, jeślix
znajduje się w słowniku lub liście, jest on (jako odniesienie) stamtąd (i niekoniecznie z puli obiektów). W tym przykładzie słownik, do którego należy, to stos frame (locals()
), który pokrywa się zglobals()
.źródło
Wymuś zamknięcie pliku po użyciu numpy.load:
Być może jest to niszowe zastosowanie, ale przydało mi się przy
numpy.load
czytaniu pliku. Co jakiś czas aktualizowałem plik i musiałem skopiować plik o tej samej nazwie do katalogu.Kiedyś
del
wypuszczałem plik i pozwalałem mi kopiować w nowym pliku.Uwaga Chcę uniknąć
with
menedżera kontekstu, ponieważ bawiłem się fabułami w wierszu poleceń i nie chciałem zbyt często naciskać klawisza Tab!Zobacz to pytanie.
źródło
__del__()
metoda na obiektach typu śmieci zostanie wywołana lub nawet jeśli zostanie w ogóle wywołana. Tak więc interfejsy API, które nie oferują innego sposobu na uwolnienie zasobów niż nadzieja, że__del__()
metoda zostanie wywołana przez jakiś czas (wkrótce po tym, jak obiekt zostanie wyrzucony), zostaną w pewnym stopniu zepsute.del
jest często widoczny w__init__.py
plikach. Każda zmienna globalna zdefiniowana w__init__.py
pliku jest automatycznie „eksportowana” (zostanie uwzględniona w afrom module import *
). Jednym ze sposobów uniknięcia tego jest zdefiniowanie__all__
, ale może to być bałagan i nie wszyscy go używają.Na przykład, jeśli masz
__init__.py
podobny kodNastępnie moduł wyeksportuje
sys
nazwę. Zamiast tego powinieneś pisaćźródło
Jako przykład tego, co
del
można wykorzystać, uważam, że jest to przydatne w następujących sytuacjach:Te dwie funkcje mogą być w różnych opakowaniach / modułów i programista nie musi wiedzieć, co argumentem Domyślna wartość
c
wf
rzeczywistości mają. Tak więc, używając kwargs w połączeniu z del, możesz powiedzieć „Chcę wartość domyślną na c”, ustawiając ją na None (lub w tym przypadku również ją zostaw).Możesz zrobić to samo z czymś takim jak:
Jednak poprzedni przykład uważam za bardziej SUCHY i elegancki.
źródło
Możesz go użyć do usunięcia pojedynczego elementu tablicy zamiast składni plastra
x[i:i+1]=[]
. Może to być przydatne, jeśli na przykład jesteś wos.walk
i chcesz usunąć element z katalogu. Nie uważałbym jednak słowa kluczowego za przydatne do tego celu, ponieważ można po prostu stworzyć[].remove(index)
metodę (.remove
metoda to w rzeczywistości wyszukiwanie i usuwanie pierwszej instancji wartości).źródło
[].pop(index)
a[].remove(item)
. Nie używaj zmiennej nazwanej,"index"
gdy mówisz o wartości, sprawia, że wygląda ona na mylącą.Okazało
del
się przydatne do pseudo-ręcznego zarządzania pamięcią podczas obsługi dużych danych za pomocą Numpy. Na przykład:Może to być różnica między zatrzymaniem skryptu, gdy system zamienia się jak szalony, gdy Python GC nie może nadążyć, i działa idealnie gładko poniżej luźnego progu pamięci, który pozostawia dużo miejsca na używanie maszyny do przeglądania i kod podczas działania.
źródło
Myślę, że jednym z powodów, dla których del ma swoją własną składnię, jest to, że zastąpienie go funkcją może być trudne w niektórych przypadkach, ponieważ działa na powiązaniu lub zmiennej, a nie na wartości, do której się odwołuje. Zatem jeśli utworzonoby wersję funkcji del, należałoby przekazać kontekst. Del foo musiałby stać się globals (). Remove ('foo') lub locals (). Remove ('foo'), co robi się bałagan i mniej czytelne. Nadal mówię, że pozbycie się dela byłoby dobre, biorąc pod uwagę jego pozornie rzadkie użycie. Ale usuwanie cech / wad językowych może być bolesne. Może python 4 go usunie :)
źródło
Chciałbym rozwinąć przyjętą odpowiedź, aby podkreślić niuans między ustawieniem zmiennej
None
a jej usunięciem za pomocądel
:Biorąc pod uwagę zmienną
foo = 'bar'
i następującą definicję funkcji:Po początkowym zadeklarowaniu
test_var(foo)
plony sąvariable tested true
zgodne z oczekiwaniami.Spróbuj teraz:
co daje
variable tested false
.Porównaj to zachowanie z:
co teraz podnosi
NameError: name 'foo' is not defined
.źródło
Jeszcze inne zastosowanie niszowe: w pyroot z ROOT5 lub ROOT6 „del” może być użyteczny do usunięcia obiektu python, który odwoływał się do nieistniejącego już obiektu C ++. Umożliwia to dynamiczne wyszukiwanie pyroot w celu znalezienia identycznie nazwanego obiektu C ++ i powiązania go z nazwą python. Możesz mieć scenariusz taki jak:
Mamy nadzieję, że ta nisza zostanie zamknięta dzięki rozsądnemu zarządzaniu obiektami ROOT7.
źródło
Polecenie „del” jest bardzo przydatne do kontrolowania danych w tablicy, na przykład:
Wynik:
[„B”, „C”, „D”]
źródło
Raz musiałem użyć:
ponieważ używając tylko:
nie zwolnił portu szeregowego wystarczająco szybko, aby natychmiast go ponownie otworzyć. Z tej lekcji dowiedziałem się, że to
del
naprawdę znaczy: „GC to TERAZ! I poczekaj, aż się skończy”, a to jest naprawdę przydatne w wielu sytuacjach. Oczywiście możesz miećsystem.gc.del_this_and_wait_balbalbalba(obj)
.źródło
__del__()
zawsze jest złe w Pythonie (chociaż nie znam przyczyn tego projektu) i lepiej jest użyć interfejsu API menedżera kontekstu (with
instrukcja).serial
Moduł współpracuje również z Jython więc siekać nie wszystko działa!del jest odpowiednikiem „unset” w wielu językach i jako punkt odniesienia przenoszący się z innego języka na python. ludzie zwykle szukają poleceń, które robią to samo, co kiedyś w swoim pierwszym języku ... również ustawiają var na „” lub żaden tak naprawdę nie usuwa var z zakresu .. po prostu opróżnia swoją wartość sama nazwa var nadal byłaby przechowywana w pamięci ... dlaczego?!? w skrypcie intensywnie korzystającym z pamięci .. utrzymywanie śmieci za jego po prostu „nie”, a zresztą… każdy język ma jakąś formę funkcji „unset / delete” var. dlaczego nie python?
źródło
del
nie wywołuje śmietnika ani szybciej= None
, ani nie pozostawia śmieci w dłuższej perspektywie. Możesz chcieć zagłębić się w zbiór śmieci w Pythonie.Każdy obiekt w pythonie ma powiązany z nim identyfikator Typ, liczba referencji, kiedy używamy del liczba referencji jest zmniejszana, gdy liczba referencji staje się zerowa, jest to potencjalny kandydat na zbieranie śmieci. To odróżnia del w porównaniu z ustawieniem identyfikatora na None. W późniejszym przypadku oznacza to po prostu, że obiekt jest po prostu pomijany (dopóki nie znajdziemy się poza zasięgiem, w którym to przypadku liczba zostanie zmniejszona) i po prostu teraz identyfikator wskazuje na inny obiekt (lokalizację pamięci).
źródło