else
İfadenin isteğe bağlı maddesinin kullanım amacı nedir try
?
else
İfadenin isteğe bağlı maddesinin kullanım amacı nedir try
?
Yanıtlar:
İfadeler else
yürütme altındaki kapalı düşerse bloğu yürütülür try
- istisna olmadığını. Dürüst olmak gerekirse, hiç bir ihtiyaç bulamadım.
Ancak, İstisnalarla İlgili Notlar:
Else yan tümcesinin kullanımı, try deyimi tarafından korunan kod tarafından korunmayan bir istisna yakalamadan kaçındığından, try yan tümcesine ek kod eklemekten daha iyidir.
Eğer, örneğin, bir atmak verebilecek bir yöntem var ise, IOError
ve bunu yükseltir istisnaları yakalamak istiyorum, ama ilk operasyon başarılı olursa yapmak istediğim başka bir şey var ve siz değilsiniz bir IOError yakalamak istiyor bu işlem, şöyle bir şey yazabilirsiniz:
try:
operation_that_can_throw_ioerror()
except IOError:
handle_the_exception_somehow()
else:
# we don't want to catch the IOError if it's raised
another_operation_that_can_throw_ioerror()
finally:
something_we_always_need_to_do()
Sadece koyarsanız another_operation_that_can_throw_ioerror()
sonra operation_that_can_throw_ioerror
, except
ikinci çağrının hatalarını yakalamak istiyorum. Ve tüm try
bloktan sonra koyarsanız , her zaman çalıştırılır ve sonrasına kadar değil finally
. else
Eğer emin olalım
finally
bloktan önce çalıştırılır veIOError
yükselttiği herhangi bir şey burada yakalanmazreturn
, continue
veya nedeniyle de olur break
.
Kullanmak için büyük bir neden var else
- stil ve okunabilirlik. Onlarla ilgilenen kodun yanında istisnalara neden olabilecek kodu tutmak genellikle iyi bir fikirdir. Örneğin, bunları karşılaştırın:
try:
from EasyDialogs import AskPassword
# 20 other lines
getpass = AskPassword
except ImportError:
getpass = default_getpass
ve
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
else:
# 20 other lines
getpass = AskPassword
İkincisi, except
erken dönemediğinde veya istisnayı yeniden atamadığında iyidir . Mümkünse şunu yazardım:
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
return False # or throw Exception('something more descriptive')
# 20 other lines
getpass = AskPassword
Not: Yanıt burada son gönderilen kopyadan kopyalandı , bu nedenle tüm bu "AskPassword" şeyler.
Bir kullanım: bir istisnayı yükseltmesi gereken bazı kodları test edin.
try:
this_should_raise_TypeError()
except TypeError:
pass
except:
assert False, "Raised the wrong exception type"
else:
assert False, "Didn't raise any exception"
(Bu kod pratikte daha genel bir teste tabi tutulmalıdır.)
Python try-else
else
Try ifadesinin isteğe bağlı maddesinin kullanım amacı nedir ?
Amaçlanan kullanım, işlenmesi beklenen istisnalar yoksa, daha fazla kodun çalışması için bir içeriğe sahip olmaktır.
Bu bağlam, beklemediğiniz hataların yanlışlıkla giderilmesini önler.
Ama bunun nedeni, kaçak başka maddesini neden kesin koşullarını anlamak önemlidir return
, continue
ve break
kontrol akışını kesintiye uğratabilir else
.
else
Varsa deyimi çalıştırır hiçbir istisna ve kesintiye değilse return
, continue
ya da break
deyimi.
Opsiyonel
else
fıkra halinde çalıştırılır ve kontrol zaman sonunda kapalı akar aittry
maddesi. *
(Kalın yazı eklendi.) Ve dipnotta şunlar yazıyor:
* Şu anda, kumanda bir istisna veya yürütülmesi durumunda dışında “Sonunda kapalı akar”
return
,continue
ya dabreak
deyimi.
Madde hariç en az bir tane daha olmasını gerektirir ( bkz. Dilbilgisi ). Yani gerçekten "dene-başkası" değil, ("son-başkası (-nihayet))" ile else
(vefinally
) isteğe bağlı.
Python Kılavuzu amaçlanan kullanıma da genişliyor:
Try ... hariç deyimi, varsa tüm maddeler hariç tüm isteğe uyması gereken isteğe bağlı başka bir maddeye sahiptir. Try yan tümcesi bir özel durum oluşturmazsa yürütülmesi gereken kod için kullanışlıdır. Örneğin:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close()
Else yan tümcesinin kullanımı, try deyimi tarafından korunan kod tarafından korunmayan bir istisna yakalamadan kaçındığından, try yan tümcesine ek kod eklemekten daha iyidir.
else
Aşağıdaki kod ile farklılaştırma örneğitry
BloğuBir hatayı ele alırsanız, else
blok çalışmaz. Örneğin:
def handle_error():
try:
raise RuntimeError('oops!')
except RuntimeError as error:
print('handled a RuntimeError, no big deal.')
else:
print('if this prints, we had no error!') # won't print!
print('And now we have left the try block!') # will print!
Ve şimdi,
>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!
Try-hariç-else, EAFP desenini ördek yazma ile birleştirmek için harika :
try:
cs = x.cleanupSet
except AttributeError:
pass
else:
for v in cs:
v.cleanup()
Bu saf kodun iyi olduğunu düşünebilirsiniz:
try:
for v in x.cleanupSet:
v.clenaup()
except AttributeError:
pass
Bu, kodunuzdaki ciddi hataları yanlışlıkla gizlemenin harika bir yoludur. Orada yazım temizleme yaptım, ama bana haber verecek AttributeError yutuluyor. Daha da kötüsü, doğru yazmış olsaydım, ancak temizleme yöntemi bazen yanlış adlandırılmış bir özniteliğe sahip bir kullanıcı türünden geçiriliyordu, bu da sessizce yarı yolda başarısız olmasına ve bir dosyayı kapatılmamasına neden oldu? Hata ayıklamada iyi şanslar.
Bir istisna olsa bile yapılması gereken bir temizlik yaptığınızda bunu gerçekten yararlı buluyorum:
try:
data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
handle_exception(e)
else:
do_stuff(data)
finally:
clean_up()
Şu anda bir kullanımını düşünemeseniz de, bunun bir kullanımı olması gerektiğine bahse girebilirsiniz. İşte yaratıcı olmayan bir örnek:
İle else
:
a = [1,2,3]
try:
something = a[2]
except:
print "out of bounds"
else:
print something
Olmadan else
:
try:
something = a[2]
except:
print "out of bounds"
if "something" in locals():
print something
Burada something
herhangi bir hata verilmezse tanımlanmış değişkeniniz vardır . Bunu try
blok dışında kaldırabilirsiniz , ancak daha sonra bir değişken tanımlanırsa dağınık algılama gerekir.
something = a[2]; print something
Try: block'un içinde yanlış olan ne ?
Güzel bir örneği var try-else
içinde PEP 380 . Temel olarak, algoritmanın farklı bölümlerinde farklı istisna işlemleri yapmaya gelir.
Bunun gibi bir şey:
try:
do_init_stuff()
except:
handle_init_suff_execption()
else:
try:
do_middle_stuff()
except:
handle_middle_stuff_exception()
Bu, kural dışı durum işleme kodunu kural dışı durumun oluştuğu yere yakın yazmanıza olanak tanır.
Gönderen istisnalar Handling Hatalar ve İstisnalar # - docs.python.org
try ... except
İfadesi isteğe bağlı sahiptirelse
mevcut, maddeleri dışındaki tüm uymalı, maddeyi,. Try yan tümcesi bir özel durum oluşturmazsa yürütülmesi gereken kod için kullanışlıdır. Örneğin:for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close()
Else yan tümcesinin kullanımı, try deyimi tarafından korunan kod tarafından korunmayan bir istisna yakalamadan kaçındığından, try yan tümcesine ek kod eklemekten daha iyidir.
Python referansına bakıldığında, istisna olmadığında else
çalıştırıldığı görülüyor try
. İsteğe bağlı else yan tümcesi, denetim try yan tümcesinin sonunda akarsa ve ne zaman yürütülür. 2 Diğer fıkrasındaki istisnalar, fıkralar dışında bir önceki fıkra ile ele alınmaz.
Python'a dalın , doğru bir şekilde anlarsam, try
blokta bir modülü içe aktarmaya çalıştıkları, istisna ve varsayılan bağlama yapamadığınızda ancak çalıştığında else
bloğa girip gerekli olanı bağlama seçeneğiniz olduğu bir örneğe sahiptir (bkz. örnek ve açıklama için bağlantı).
Eğer catch
blokta çalışmayı denerseniz, başka bir istisna atabilir - sanırım else
blok burada işe yarar.
try
blokta.
Bu kadar. Bir try-hariç yantümcesinin 'else' bloğu, denenen işlem başarılı olduğunda (ve yalnızca) çalıştığında kod için vardır. Kullanılabilir ve kötüye kullanılabilir.
try:
fp= open("configuration_file", "rb")
except EnvironmentError:
confdata= '' # it's ok if the file can't be opened
else:
confdata= fp.read()
fp.close()
# your code continues here
# working with (possibly empty) confdata
Şahsen, beğendim ve uygun olduğunda kullanıyorum. Anlamsal olarak ifadeleri gruplandırır.
Belki bir kullanım olabilir:
#debug = []
def debuglog(text, obj=None):
" Simple little logger. "
try:
debug # does global exist?
except NameError:
pass # if not, don't even bother displaying
except:
print('Unknown cause. Debug debuglog().')
else:
# debug does exist.
# Now test if you want to log this debug message
# from caller "obj"
try:
if obj in debug:
print(text) # stdout
except TypeError:
print('The global "debug" flag should be an iterable.')
except:
print('Unknown cause. Debug debuglog().')
def myfunc():
debuglog('Made it to myfunc()', myfunc)
debug = [myfunc,]
myfunc()
Belki bu size bir kullanım getirecektir.
Ben try: ... else:
veritabanı sorguları çalıştırmak ve aynı lezzet / türü ayrı bir veritabanına bu sorguların sonuçlarını günlüğe kaydetme durumda yararlı buldum . Diyelim ki bir kuyruğa gönderilen tüm veritabanı sorgularını işleyen çok sayıda iş parçacığı var
#in a long running loop
try:
query = queue.get()
conn = connect_to_db(<main db>)
curs = conn.cursor()
try:
curs.execute("<some query on user input that may fail even if sanitized">)
except DBError:
logconn = connect_to_db(<logging db>)
logcurs = logconn.cursor()
logcurs.execute("<update in DB log with record of failed query")
logcurs.close()
logconn.close()
else:
#we can't put this in main try block because an error connecting
#to the logging DB would be indistinguishable from an error in
#the mainquery
#We can't put this after the whole try: except: finally: block
#because then we don't know if the query was successful or not
logconn = connect_to_db(<logging db>)
logcurs = logconn.cursor()
logcurs.execute("<update in DB log with record of successful query")
logcurs.close()
logconn.close()
#do something in response to successful query
except DBError:
#This DBError is because of a problem with the logging database, but
#we can't let that crash the whole thread over what might be a
#temporary network glitch
finally:
curs.close()
conn.close()
#other cleanup if necessary like telling the queue the task is finished
Elbette, atılabilecek olası istisnalar arasında ayrım yapabiliyorsanız, bunu kullanmak zorunda değilsiniz, ancak başarılı bir kod parçasına tepki gösteren kod, başarılı parça ile aynı istisnayı atabilir ve sadece İkinci olası istisnanın gitmesine izin verin veya hemen başarıya dönün (bu benim durumumda iş parçacığını öldürür), o zaman bu kullanışlı olur.
Her else
blokta oluşan işlevselliği tamamlamak için genellikle bir blok bulunabilir except
.
try:
test_consistency(valuable_data)
except Except1:
inconsistency_type = 1
except Except2:
inconsistency_type = 2
except:
# Something else is wrong
raise
else:
inconsistency_type = 0
"""
Process each individual inconsistency down here instead of
inside the except blocks. Use 0 to mean no inconsistency.
"""
Bu durumda, inconsistency_type
blok hariç her birinde ayarlanır, böylece davranışı içindeki no-error durumunda tamamlanır else
.
Tabii ki, bunu bir gün kendi kodunuzda ortaya çıkabilecek bir model olarak tanımlıyorum. Bu özel durumda, yine inconsistency_type
de try
engellemeden önce 0'a ayarladınız .
İşte bu deseni kullanmak istediğim başka bir yer:
while data in items:
try
data = json.loads(data)
except ValueError as e:
log error
else:
# work on the `data`
continue
yerine kullanabilirsiniz - "erken kırılma" kalıbı. Bu, kodun okunmasını kolaylaştırmak için "else" yan tümcesini ve girintisini bırakmanıza izin verir.
Düşünebileceğim kullanım senaryolarından biri, tekrar denerseniz atlatılabilecek öngörülemeyen istisnalar. Örneğin, try bloğundaki işlemler rastgele sayılar içerdiğinde:
while True:
try:
r = random.random()
some_operation_that_fails_for_specific_r(r)
except Exception:
continue
else:
break
Ancak istisna öngörülebilirse, bir istisna yerine daima doğrulamayı önceden seçmelisiniz. Ancak, her şey tahmin edilemez, bu nedenle bu kod deseninin yeri vardır.
break
iç kısımda, try
daha temiz IMO olan koyarak yapabilirsiniz ve ihtiyacınız yoktur else
. Ayrıca continue
gerçekten gerekli değildir, sadece yapabilirsiniz pass
.
else
Muhtemelen yanlış bir yapılandırma dosyası ile uğraşmak için yararlı buldum :
try:
value, unit = cfg['lock'].split()
except ValueError:
msg = 'lock monitoring config must consist of two words separated by white space'
self.log('warn', msg)
else:
# get on with lock monitoring if config is ok
lock
Yapılandırmayı okuyan bir kural dışı durum kilit izlemeyi devre dışı bırakır ve ValueErrors yardımcı bir uyarı iletisi kaydeder.
Programlama mantığınızın, bir sözlüğün belirli bir tuşa sahip bir girişi olup olmadığına bağlı olduğunu varsayalım. Yapı dict.get(key)
kullanarak sonucu test edebilir if... else...
veya şunları yapabilirsiniz:
try:
val = dic[key]
except KeyError:
do_some_stuff()
else:
do_some_stuff_with_val(val)
DB oturumları işlerken düz görünüyor başka bir kullanım durumu eklemek istiyorum:
# getting a DB connection
conn = db.engine.connect()
# and binding to a DB session
session = db.get_session(bind=conn)
try:
# we build the query to DB
q = session.query(MyTable).filter(MyTable.col1 == 'query_val')
# i.e retrieve one row
data_set = q.one_or_none()
# return results
return [{'col1': data_set.col1, 'col2': data_set.col2, ...}]
except:
# here we make sure to rollback the transaction,
# handy when we update stuff into DB
session.rollback()
raise
else:
# when no errors then we can commit DB changes
session.commit()
finally:
# and finally we can close the session
session.close()
else:
Blok kafa ve (hemen hemen) işe yaramaz. Ayrıca for
ve while
ifadelerinin bir parçasıdır .
Aslında, bir if
statüde bile, else:
bulmak çok zor böcekler yaratarak gerçekten korkunç yollarla istismar edilebilir.
Bunu düşün.
if a < 10:
# condition stated explicitly
elif a > 10 and b < 10:
# condition confusing but at least explicit
else:
# Exactly what is true here?
# Can be hard to reason out what condition is true
İki kere düşünün else:
. Bu genellikle bir sorundur. Bir durum haricinde bundan kaçının if
ve hatta else
- durumunu açıkça belirtmek için - koşulunu belgelemeyi düşünün .
if x > 0: return "yes"
ve if x <= 0: return "no"
. Şimdi bir kişi gelir ve söyleyecek koşullardan x > 1
birini değiştirir, ancak diğerini değiştirmeyi unutur. Bu nasıl işlenecek hata sayısını azaltır. if else
cümlecikleri bazen birbirinden ayrı satırlar olur. KURU gerçekten çok iyi bir uygulamadır. (çift yazı için üzgünüm).