Python'daki EAFP prensibi nedir?


Yanıtlar:


217

Gönderen sözlüğü :

Affetmek, izin vermekten daha kolaydır. Bu yaygın Python kodlama stili, geçerli anahtarların veya niteliklerin varlığını varsayar ve varsayımın yanlış olduğunu kanıtlarsa istisnaları yakalar. Bu temiz ve hızlı stil, birçok tryve exceptifadenin varlığı ile karakterizedir . Teknik , C gibi diğer birçok dilde ortak olan LBYL stiliyle zıttır .

Bir örnek, bir sözlük anahtarına erişme girişimidir.

EAFP:

try:
    x = my_dict["key"]
except KeyError:
    # handle missing key

LBYL:

if "key" in my_dict:
    x = my_dict["key"]
else:
    # handle missing key

LBYL sürümü sözlüğün içindeki anahtarı iki kez aramalıdır ve ayrıca biraz daha az okunabilir olarak değerlendirilebilir.


34
Başka bir avantaj, yarış koşullarından kaçınmaktır ... örneğin, sadece bir dosyayı açmayı deneyin ve eğer alırsanız, anladınız. Bunu elde edip edemeyeceğinizi görmek yerine , daha sonra almayı denemek ve kontrol ve erişim girişimi arasındaki minik zaman diliminde daha uzun süre elde edebileceğinizi fark etmek.
Jon Clements

23
Python da işleyici sadece varsayılan bir değer atamak edilirse, bunların her ikisi de kaçınmanın bir yolu sağlar xanahtar yoksa zaman: x = mydict.get('key')dönecektir Noneeğer 'key'değil my_dict; siz de yapabilirsiniz .get('key', <something>)ve sonra anahtar sözlükte değilse x'e bir şey atanacaktır. dict.setdefault()ve collections.defaultdictfazla koddan kaçınmak için güzel şeyler.
JAB

1
Bence except KeyErrorsıra sıra AttributeErrorbasit ama en kötü örneklerden bazılarıdır. Çoğu zaman bir şey hata ayıklama sıkışmıştı çünkü except AttributeErroryanlış yere konuldu, bu da zincirde daha derinlere doğru yanlış özellik hatası yakaladı. Bence iyi örnekler şunlardır: try: open() ... except: IOError. Veyatry: parseLine() ... except ParseError
Kayak

4
@ski Bu biraz farklı bir sorun. Sen gerektiğini hep yanlış istisna yakalamak önlemek için olabildiğince düşük deneyin bloğu tutun. Ayrıca genel olarak EAFP stilini tercih etmediğimi de unutmayın. Ben sadece burada soruyu cevaplıyorum ve bazı insanların bunu tercih ettiğini belirtiyorum. Hangi kodun benim için en okunaklı göründüğünü vaka bazında tanımlarım.
Sven Marnach

1
Grace Hopper'ın bu cümlenin kaynağı olduğunu söylemeye değer olacağını düşündüm , "Alıntı ile Cesaret Et ve Yap. Affetmek, izin almaktan daha kolaydır" (programlama ile sınırlı değil).
Fabien Snauwaert

9

Başka bir örnekle açıklamaya çalışacağım.

Burada dosyaya erişmeye ve içeriği konsolda yazdırmaya çalışıyoruz.

LBYL - Sıçramadan Önce Bak:

Dosyaya erişip erişemeyeceğimizi kontrol etmek isteyebiliriz ve eğer yapabilirsek, dosyayı açıp içeriği yazdıracağız. Dosyaya erişemezsek, elseparçayı vuracağız . Bunun bir yarış koşulu olmasının nedeni, öncelikle bir erişim kontrolü yapmamızdır. Ulaştığımız zaman with open(my_file) as f:, bazı izin sorunları nedeniyle artık erişemiyoruz (örneğin, başka bir işlem özel bir dosya kilidi kazanıyor). Bu kod büyük olasılıkla bir hata verir ve dosyaya erişebileceğimizi düşündüğümüz için bu hatayı yakalayamayız.

import os

my_file = "/path/to/my/file.txt"

# Race condition
if os.access(my_file, os.R_OK):
    with open(my_file) as f:
        print(f.read())
else:
    print("File can't be accessed")

EAFP - Bağışlama İzninden Daha Kolay Sorulur:

Bu örnekte, sadece dosyayı açmaya çalışıyoruz ve dosyayı açamıyorsak, bir dosya atar IOError. Eğer yapabilirsek, dosyayı açıp içindekileri yazdıracağız. Yani bir şey sormak yerine yapmaya çalışıyoruz . Çalışırsa harika! Eğer değilse, hatayı yakalayıp hallederiz.

# # No race condition
try:
    f = open(my_file)
except IOError as e:
    print("File can't be accessed")
else:
    with f:
        print(f.read())

Bunu bir yarış koşulu olarak tanımlamanın doğru olduğundan emin değilim. Dosyaya erişilebilir veya erişilemez.
ds4940

3
@ ds4940 Dosya erişilebilirliğinin 6. ve 7. satırlar arasında değişmesi, dosyanın erişilebilir olup olmadığını kontrol etme ve açma arasındaki yarış koşuludur.
Markus von Broady

@MarkusvonBroady kabul etti, yarış koşulundaki diğer katılımcının bir örneğini sunmak için cevabı düzenledi.
ds4940

6

Ben buna "iyimser programlama" diyorum. Fikir, çoğu zaman insanların doğru şeyi yapacağı ve hataların az olması gerektiğidir. Bu yüzden önce "doğru olanın" gerçekleşmesini kodlayın ve sonra yapmazsanız hataları yakalayın.

Benim düşüncem, eğer bir kullanıcı hata yapacaksa, zamanın sonuçlarından muzdarip olması gerekir. Aracı doğru şekilde kullanan kişiler hızlandırılır.

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.