Bir Python betiğinin ortasındaki tüm değişkenleri nasıl temizlerim?


88

Matlab'da 'temizle'ye benzer bir şey arıyorum: Tüm değişkenleri çalışma alanından kaldıran, sistem belleğinden çıkaran bir komut / işlev. Python'da böyle bir şey var mı?

DÜZENLEME: Bir noktada tüm değişkenleri temizleyen bir komut dosyası yazmak istiyorum.


2
Başlığınızı "Bir Python betiğinin ortasındaki tüm değişkenleri nasıl temizlerim?" Gibi bir şeye değiştirirseniz faydalı olacaktır. konuyla ilgili gelecekteki aramalar için, çünkü "Python'da komut penceresi nasıl yeniden başlatılır?" gerçekte sorduğunuz şeyle hiçbir ilgisi yok.
Sam Dolan

Bunun mantıklı olduğu herhangi bir olası bağlam sağlayabilir misiniz?
S.Lott

2
Kodlama alışkanlıklarını kendi doğal ortamlarından hiçbir anlam ifade etmedikleri bir ortama taşımaya çalışmanın başka bir örneği gibi görünüyor.
Glenn Maynard

Sadece bazı büyük nesneler (resimler veya diğer büyük diziler) hakkında endişeliyseniz, işiniz delbittiğinde bunları yapabilirsiniz . Ad alanının dağınık olması konusunda endişeliyseniz, muhtemelen tasarımınızı bu kadar çok ad kullanarak yeniden gözden geçirmelisiniz. Örneğin, bir dizi görüntü dönüşümü için, her ara adımı sürdürmek muhtemelen gereksizdir.
Nick T

4
@ S.Lott: bir konsolda keşfedici bilimsel analiz. Pek çok istenmeyen değişkenle sonuçlanmak yaygındır (bir şeyler denedikten sonra ve bunun alakalı bir yol olmadığına karar verdikten sonra). Ancak bu durumda John La Rooy'un cevabı en uygun olanıdır.
naught101

Yanıtlar:


70

Aşağıdaki komut dizisi, her adı geçerli modülden kaldırır :

>>> import sys
>>> sys.modules[__name__].__dict__.clear()

Aslında bunu yapmak istediğinizden şüpheliyim, çünkü "her isim" tüm yerleşikleri içerir, bu yüzden böyle bir toplam silme işleminden sonra yapabileceğiniz pek bir şey yoktur. Unutmayın, Python'da "değişken" diye bir şey yoktur - birçok türde nesneler vardır (modüller, işlevler, sınıf, sayılar, dizeler, ... dahil) ve nesnelere bağlı isimler vardır ; dizinin yaptığı şey, bir modülden her ismi kaldırmaktır (karşılık gelen nesneler, ancak ve ancak onlara yapılan her referans kaldırılmışsa kaybolur).

Belki daha seçici olmak istersiniz, ancak daha spesifik olmak istemediğiniz sürece tam olarak ne demek istediğinizi tahmin etmek zordur. Ama bir örnek vermek gerekirse:

>>> import sys
>>> this = sys.modules[__name__]
>>> for n in dir():
...   if n[0]!='_': delattr(this, n)
... 
>>>

Bu sekans, __builtins__tüm yerleşik isimleri barındıran özel ad da dahil olmak üzere özel veya büyülü isimleri yalnız bırakır . Yani, yerleşikler hala çalışıyor - örneğin:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'n']
>>> 

Gördüğünüz gibi, ad n(buradaki kontrol değişkeni for) de ( forher seferinde cümlecikte yeniden bağlandığı için) etrafta kalmaktadır , bu nedenle bu kontrol değişkenini adlandırmak _, örneğin "o özel "(artı, etkileşimli yorumlayıcıda ad _, komut istemine girilen her tam ifadeden sonra, bu ifadenin değerine yeniden bağlanır, böylece uzun süre kalmaz ;-).

Bunun tam olarak ne belirledikten sonra neyse, olan yapmak istediğiniz, bu amaç için bir işlev tanımlayıp ((yalnızca etkileşimli oturumlarda bunu istiyorsanız) başlangıç dosyaya koydu veya site özelleştirme dosyası zor değil her senaryoda istiyorsanız).


2
Başlangıçta her zaman orijinal sözlüğün bir kopyasını saklayabilir ve sonra eklenen isimleri kaldırabilirsiniz;) Ancak bunun dinamik sistemin açık bir şekilde kötüye kullanılması olduğunu düşünüyorum ve bunu yapmak için anlamsız olmayan bir durum düşünemiyorum in.
monoceres

5
Haha, bu Size bunu yaparak kaybetmek ne kadar işlevsellik şaşırtıcı oluyor ... parlak ve henüz ne kadar işlevselliği gibi şeyler yaparak geri alabilirsiniz int = (2).__class__, str = ''.__class__,True = (1 == 1) ... vb
Chinmay Kanchi

@monoceres, bu kopyayı nasıl adlandırırsınız ve silinmemesi için nereye saklarsınız? -)
Alex Martelli

2
Python'u ne kadar çok kullanırsam, onu o kadar çok seviyorum. Sadece harika bir dil değil, aynı zamanda sadece onunla
uğraşarak ve

1
Belki yanlış anladım, ama bir sorunla karşılaştım: for n in dir(): ... if n[0]!='_': delattr(this, n)bir anda kullandığınızda n=thisve döngüde sildiğinizde! Yani bir sonraki yinelemede denerken hata alırsınız delattr(this,n)çünkü onu yeni sildiniz! :) Yani doğru çalışmıyor
Mikhail_Sam

59

Hayır, tercümanı yeniden başlatmanız en iyisidir

IPython , paket yorumlayıcı için mükemmel bir alternatiftir ve %resetgenellikle çalışan bir komuta sahiptir.


1
"Hayır" derken, yapmamam gerektiğini mi yoksa bunun imkansız olduğunu mu söylüyorsun? Yapmamam gerektiğini söylersen, nedenini açıklayabilir misin?
snakile

6
+1: O ctrl-dzaman pyt-> tabtercümana geri dönmem çeyrek saniyeden az sürüyor . Burada süslü bir şey yapmak için bir sebep yok.
Sam Dolan

3
% reset çoğu değişken için çalışır, bazıları için işe yaramaz. Benim için, yalnızca tercümanı yeniden başlatmak her şeyi temizlemeyi garanti eder.
artemis_clyde

3
%reset -fEtkileşimsiz olmak için kullanın . stackoverflow.com/questions/38798181/…
Joachim Wagner

28

Bir fonksiyon yazarsanız, bir kez bıraktığınızda içindeki tüm isimler kaybolur.

Kavramın adı ad alanıdır ve o kadar iyidir ki, onu Python'un Zen'ine dahil etmiştir :

İsim alanları, harika bir fikir - hadi onlardan daha fazlasını yapalım!

IPython ad alanı aynı şekilde sihirli komutla sıfırlanabilir %reset -f. ( -f"Kuvvet" anlamına gelir; başka bir deyişle, "tüm değişkenleri gerçekten silmek isteyip istemediğimi sorma, sadece yap.")


1
Bariz olanı ekleyeceğim: Her şeyi bir ana işlevin (içe aktarmalar dahil) içine koyarsanız, pratikte bu işlevden çıkarak sıfırlayabileceğiniz bir işyeri elde edersiniz. Sanırım soru gerçekten de bunun için tasarlandı.
David

8
from IPython import get_ipython;   
get_ipython().magic('reset -sf')

3

1
ya da basitçe%reset -sf
Bal Krishna Jha

1
aslında, python betiğinizi anaconda komut istemiyle çalıştırdığınızda% reset -sf komutu çalışmıyor ve hata veriyor (try-hariç; çalışmıyor olsa bile). Aynı şeyi deneyebilirsin ve göreceksin. Ancak, ipython kitaplığının kullanılması olası her durumda bu sorunu çözecektir.
Anurag Gupta

5

Bu, Alex'in cevabının değiştirilmiş bir versiyonudur. Bir modülün isim alanının durumunu kaydedebilir ve aşağıdaki 2 yöntemi kullanarak onu geri yükleyebiliriz ...

__saved_context__ = {}

def saveContext():
    import sys
    __saved_context__.update(sys.modules[__name__].__dict__)

def restoreContext():
    import sys
    names = sys.modules[__name__].__dict__.keys()
    for n in names:
        if n not in __saved_context__:
            del sys.modules[__name__].__dict__[n]

saveContext()

hello = 'hi there'
print hello             # prints "hi there" on stdout

restoreContext()

print hello             # throws an exception

SaveContext () 'i çağırmadan önce bir "clear = restoreContext" satırı da ekleyebilirsiniz ve clear () matlab'ın clear gibi çalışacaktır.


1
Mükemmel cevap! Python 3 için restoreContext'i ile ince ayar yapmak isteyeceğinize inanıyorum names = list(sys.modules[__name__].__dict__.keys()), aksi takdirde Python, dict_keysnesnesi boyunca yineleme yaparken sözlük boyutunu değiştirdiğinizden şikayet edecektir .
Sam Bader

Ayrıca, importbu yanıtı isteyenler için (yani bunu kaydettim ve bir ev ödevindeki farklı problemler arasındaki ad alanını temizlemek için bunu bir Jupyter not defterinden içe aktarıyorum), "__main__"bunun yerine kullanmak isteyeceğinizi düşünüyorum __name__.
Sam Bader

3

Spyder'da, Menü'deki her yürütmeden önce tüm değişkenleri temizlemek için her Python dosyası için IPython konsolunu yapılandırabilirsiniz Run -> Configuration -> General settings -> Remove all variables before execution.


2

globals()Fonksiyon tuşları adlandırabilir nesnelerin isimleridir bir sözlük döndürür (ve değerler, bu arada, olan idbu nesnelerin ler) exec()sadece bir piton konsolunda yazın sanki işlev bir dize ve yürütür alır. Yani kod

for i in list(globals().keys()):
    if(i[0] != '_'):
        exec('del {}'.format(i))

Bu kod parçacığı soruyu çözebilir ancak bir açıklama da dahil olmak üzere yanıtınızın kalitesini artırmaya yardımcı olur. Gelecekte okuyucular için soruyu yanıtlayacağınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceklerini unutmayın.
Stefan Crain

Teşekkür ederim. Şimdi daha mı iyi?
Kolay.Ne

0

Boştaki IDE'de Kabuk / Yeniden Başlatma Kabuğu vardır. Cntrl-F6 yapacak.


0

Gerekli tüm değişkenleri içeren bir sınıf oluşturmanın en kolay yolu değil mi? O zaman tüm curretn değişkenleri olan bir nesneniz var ve ihtiyacınız olursa bu değişkenin üzerine yazabilirsiniz?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.