Tidak ada cara untuk mengompres try
/except
blok menjadi satu baris dengan Python.
Juga, adalah hal yang buruk untuk tidak mengetahui apakah sebuah variabel ada di Python, seperti yang Anda lakukan di beberapa bahasa dinamis lainnya. Cara yang lebih aman (dan gaya yang berlaku) adalah mengatur semua variabel menjadi sesuatu. Jika mereka mungkin tidak diatur, atur ke None
pertama (atau 0
atau ''
atau sesuatu jika lebih dapat diterapkan.)
Jika Anda melakukan assign semua nama yang Anda tertarik pertama, Anda memiliki pilihan.
Pilihan terbaik adalah pernyataan if.
c = None
b = [1, 2]
if c is None:
a = b
else:
a = c
Opsi satu baris adalah ekspresi bersyarat.
c = None
b = [1, 2]
a = c if c is not None else b
Beberapa orang menyalahgunakan perilaku arus pendek or
untuk melakukan ini. Ini rawan kesalahan, jadi saya tidak pernah menggunakannya.
c = None
b = [1, 2]
a = c or b
Pertimbangkan kasus berikut:
c = []
b = [1, 2]
a = c or b
Dalam hal ini, a
mungkin harus menjadi []
, tetapi [1, 2]
karena []
adalah palsu dalam konteks boolean. Karena ada banyak nilai yang bisa salah, saya tidak menggunakan or
triknya. (Ini adalah masalah yang sama yang dialami orang-orang ketika mereka mengatakan if foo:
ketika mereka bermaksud if foo is not None:
.)
try
/except
. Untungnya garis-garis itu murah, jadi solusi 4-garis cocok untuk Anda. ;-)get
jika Anda tidak menginginkan pengecualian. Gunakanfilter
sebagai gantinya.Ini sangat hackish, tetapi saya telah menggunakannya pada prompt ketika saya ingin menulis urutan tindakan untuk debugging:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" print "The problem is %s" % problem[1]
Untuk sebagian besar, saya sama sekali tidak terganggu oleh batasan no-single-line-try-exception, tetapi ketika saya hanya bereksperimen dan saya ingin readline untuk mengingat seluruh potongan kode sekaligus dalam interpreter interaktif jadi bahwa saya bisa menyesuaikannya entah bagaimana, trik kecil ini berguna.
Untuk tujuan sebenarnya yang ingin Anda capai, Anda dapat mencobanya
locals().get('c', b)
; idealnya akan lebih baik menggunakan kamus yang sebenarnya daripada konteks lokal, atau cukup tetapkan c ke None sebelum menjalankan pengaturan may-or-may-not apapun.sumber
problem[0]
mengembalikan apa yang dikembalikan fungsi itu?Di python3 Anda bisa menggunakan contextlib.suppress :
from contextlib import suppress d = {} with suppress(KeyError): d['foo']
sumber
Cara lain adalah dengan mendefinisikan pengelola konteks:
class trialContextManager: def __enter__(self): pass def __exit__(self, *args): return True trial = trialContextManager()
Kemudian gunakan
with
pernyataan tersebut untuk mengabaikan kesalahan dalam satu baris:>>> with trial: a = 5 # will be executed normally >>> with trial: a = 1 / 0 # will be not executed and no exception is raised >>> print a 5
Tidak ada pengecualian yang akan dimunculkan jika terjadi error runtime. Ini seperti
try:
tanpaexcept:
.sumber
Versi jawaban poke53280 dengan pengecualian yang diharapkan terbatas.
def try_or(func, default=None, expected_exc=(Exception,)): try: return func() except expected_exc: return default
dan itu bisa digunakan sebagai
In [2]: try_or(lambda: 1/2, default=float('nan')) Out[2]: 0.5 In [3]: try_or(lambda: 1/0, default=float('nan'), expected_exc=(ArithmeticError,)) Out[3]: nan In [4]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError,)) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) [your traceback here] TypeError: unsupported operand type(s) for /: 'str' and 'int' In [5]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError, TypeError)) Out[5]: nan
sumber
(Exception)
sama dengan mengosongkan tanda kurung.(Exception, )
memberitahu penerjemah bahwa ini adalah tupel (seperti daftar) dengan satu entri. Dalam contoh ini, ini digunakan sehinggaexpected_exc
bisa ada lebih dari satu pengecualian.parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
Selalu ada solusi.
sumber
Gunakan sesuatu seperti ini:
print("result:", try_or(lambda: model.objects.get(), '<n/a>'))
Di mana try_or adalah fungsi utilitas yang ditentukan oleh Anda:
def try_or(fn, default): try: return fn() except: return default
Opsional Anda dapat membatasi jenis pengecualian diterima untuk
NameError
,AttributeError
, dllsumber
Bagaimana kalau menggunakan dua baris. apakah itu baik-baik saja
>>> try: a = 3; b= 0; c = a / b ... except : print('not possible'); print('zero division error') ... not possible zero division error
sumber
Anda dapat melakukannya dengan mengakses dict namespace menggunakan
vars()
,locals()
atauglobals()
, mana yang paling sesuai untuk situasi Anda.>>> b = 'some variable' >>> a = vars().get('c', b)
sumber
Anda menyebutkan bahwa Anda menggunakan django. Jika masuk akal untuk apa yang Anda lakukan, Anda mungkin ingin menggunakan:
created
akan menjadi Benar atau Salah. Mungkin ini akan membantu Anda.sumber
Bekerja pada Python3, terinspirasi oleh Walter Mundt
exec("try:some_problematic_thing()\nexcept:pass")
Untuk garis mulitiples menjadi satu baris
exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")
NB: Exec tidak aman untuk digunakan pada data yang tidak dapat Anda kendalikan.
sumber
jika Anda benar-benar perlu mengelola pengecualian:
(dimodifikasi dari jawaban poke53280)
>>> def try_or(fn, exceptions: dict = {}): try: return fn() except Exception as ei: for e in ei.__class__.__mro__[:-1]: if e in exceptions: return exceptions[e]() else: raise >>> def context(): return 1 + None >>> try_or( context, {TypeError: lambda: print('TypeError exception')} ) TypeError exception >>>
perhatikan bahwa jika pengecualian tidak didukung, itu akan muncul seperti yang diharapkan:
>>> try_or( context, {ValueError: lambda: print('ValueError exception')} ) Traceback (most recent call last): File "<pyshell#57>", line 1, in <module> try_or( context, {ValueError: lambda: print('ValueError exception')} ) File "<pyshell#38>", line 3, in try_or return fn() File "<pyshell#56>", line 2, in context return 1 + None TypeError: unsupported operand type(s) for +: 'int' and 'NoneType' >>>
juga jika
Exception
diberikan, itu akan cocok dengan apapun di bawah ini.(
BaseException
lebih tinggi, jadi tidak akan cocok)>>> try_or( context, {Exception: lambda: print('exception')} ) exception
sumber
Ini adalah versi sederhana dari jawaban yang diberikan oleh @surendra_ben
a = "apple" try: a.something_that_definitely_doesnt_exist except: print("nope") ... nope
sumber
Gunakan
with
sintaks dalam satu baris:class OK(): __init__ = lambda self, *isok: setattr(self, 'isok', isok); __enter__ = lambda self: None; __exit__ = lambda self, exc_type, exc_value, traceback: (True if not self.isok or issubclass(exc_type, self.isok) else None) if exc_type else None
Abaikan kesalahan apa pun:
with OK(): 1/0
Abaikan kesalahan tertentu:
with OK(ZeroDivisionError, NameError): 1/0
sumber