มีวิธีใน python ในการเปลี่ยนลอง / ยกเว้นเป็นบรรทัดเดียวหรือไม่?
สิ่งที่ต้องการ...
b = 'some variable'
a = c | b #try statement goes here
b
ตัวแปรที่ประกาศอยู่ที่ไหนและc
ไม่ใช่ ... ดังนั้นc
จะทำให้เกิดข้อผิดพลาดและa
จะกลายเป็นb
...
มีวิธีใน python ในการเปลี่ยนลอง / ยกเว้นเป็นบรรทัดเดียวหรือไม่?
สิ่งที่ต้องการ...
b = 'some variable'
a = c | b #try statement goes here
b
ตัวแปรที่ประกาศอยู่ที่ไหนและc
ไม่ใช่ ... ดังนั้นc
จะทำให้เกิดข้อผิดพลาดและa
จะกลายเป็นb
...
คำตอบ:
ไม่มีวิธีการบีบอัดไฟล์ try
/ except
block ลงในบรรทัดเดียวใน Python
นอกจากนี้ยังเป็นเรื่องเลวร้ายที่จะไม่ทราบว่ามีตัวแปรอยู่ใน Python หรือไม่เช่นเดียวกับที่คุณทำในภาษาไดนามิกอื่น ๆ วิธีที่ปลอดภัยกว่า (และรูปแบบที่แพร่หลาย) คือการตั้งค่าตัวแปรทั้งหมดเป็นบางสิ่ง หากอาจไม่ได้รับการตั้งค่าให้ตั้งค่าเป็นNone
อันดับแรก (หรือ0
หรือ''
หรือบางอย่างหากมีความเกี่ยวข้องมากกว่า)
ถ้าคุณ ทำกำหนดชื่อทั้งหมดที่คุณมีความสนใจในครั้งแรกที่คุณจะมีตัวเลือก
ตัวเลือกที่ดีที่สุดคือคำสั่ง if
c = None
b = [1, 2]
if c is None:
a = b
else:
a = c
อ็อพชันหนึ่งซับคือนิพจน์เงื่อนไข
c = None
b = [1, 2]
a = c if c is not None else b
บางคนละเมิดพฤติกรรมการลัดวงจรของor
การทำเช่นนี้ นี่เป็นข้อผิดพลาดได้ง่ายดังนั้นฉันจึงไม่เคยใช้มัน
c = None
b = [1, 2]
a = c or b
พิจารณากรณีต่อไปนี้:
c = []
b = [1, 2]
a = c or b
ในกรณีนี้a
อาจจะควรจะเป็น[]
แต่มันก็เป็น[1, 2]
เพราะ[]
เป็นเท็จในบริบทแบบบูล เนื่องจากมีค่ามากมายที่อาจเป็นเท็จฉันจึงไม่ใช้or
เคล็ดลับ (นี่เป็นปัญหาเดียวกับที่ผู้คนพบเจอเมื่อพวกเขาพูดif foo:
เมื่อพวกเขาหมายถึงif foo is not None:
)
try
/ except
block โชคดีที่เส้นมีราคาถูกดังนั้นโซลูชัน 4 บรรทัดน่าจะเหมาะกับคุณ ;-)
get
ถ้าคุณไม่ต้องการข้อยกเว้น ใช้filter
แทน
นี่เป็นการแฮ็กอย่างมาก แต่ฉันเคยใช้ที่พรอมต์เมื่อฉันต้องการเขียนลำดับการดำเนินการสำหรับการดีบัก:
exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()"
print "The problem is %s" % problem[1]
ส่วนใหญ่แล้วฉันไม่ได้ใส่ใจกับข้อ จำกัด การไม่ลองบรรทัดเดียวเลย แต่เมื่อฉันเพิ่งทดลองและฉันต้องการให้ Readline เรียกคืนโค้ดทั้งหมดพร้อมกันในล่ามเชิงโต้ตอบดังนั้น ที่ฉันสามารถปรับได้เคล็ดลับเล็ก ๆ น้อย ๆ นี้มีประโยชน์
เพื่อวัตถุประสงค์ที่แท้จริงที่คุณกำลังพยายามที่จะบรรลุคุณอาจลองlocals().get('c', b)
; จะเป็นการดีกว่าถ้าใช้พจนานุกรมจริงแทนบริบทเฉพาะที่หรือเพียงแค่กำหนด c ให้กับ None ก่อนที่จะเรียกใช้สิ่งที่อาจหรือไม่ได้ตั้งค่าไว้
problem[0]
ส่งคืนฟังก์ชันนั้นส่งคืนอะไร?
ใน python3 คุณสามารถใช้contextlib.suppress :
from contextlib import suppress
d = {}
with suppress(KeyError): d['foo']
อีกวิธีหนึ่งคือการกำหนดผู้จัดการบริบท:
class trialContextManager:
def __enter__(self): pass
def __exit__(self, *args): return True
trial = trialContextManager()
จากนั้นใช้with
คำสั่งเพื่อละเว้นข้อผิดพลาดในบรรทัดเดียว:
>>> 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
จะไม่มีข้อยกเว้นเกิดขึ้นในกรณีที่เกิดข้อผิดพลาดรันไทม์ มันเหมือนtry:
ไม่มีexcept:
.
เวอร์ชันของคำตอบ poke53280 พร้อมข้อยกเว้นที่คาดไว้อย่าง จำกัด
def try_or(func, default=None, expected_exc=(Exception,)):
try:
return func()
except expected_exc:
return default
และสามารถใช้เป็น
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
(Exception)
ก็เท่ากับทิ้งวงเล็บไว้ (Exception, )
บอกล่ามว่านี่คือทูเปิล (คล้ายรายการ) ที่มีรายการเดียว ในตัวอย่างนี้ใช้ดังนั้นจึงexpected_exc
สามารถมีข้อยกเว้นได้มากกว่าหนึ่งข้อ
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x)
มีทางออกเสมอ
ปัญหาคือจริงๆแล้วมันเป็นโมเดล django model.objects. รับแบบสอบถามที่ฉันพยายามทดสอบ . get ส่งกลับข้อผิดพลาดหากไม่พบข้อมูล ... มันไม่ส่งคืนไม่มี (ซึ่งทำให้ฉันรำคาญ)
ใช้สิ่งนี้:
print("result:", try_or(lambda: model.objects.get(), '<n/a>'))
โดยที่ try_or เป็นฟังก์ชันยูทิลิตี้ที่คุณกำหนด:
def try_or(fn, default):
try:
return fn()
except:
return default
เลือกที่คุณสามารถ จำกัด ประเภทยกเว้นได้รับการยอมรับไปNameError
, AttributeError
ฯลฯ
วิธีการใช้สองบรรทัด ไหวมั้ย?
>>> try: a = 3; b= 0; c = a / b
... except : print('not possible'); print('zero division error')
...
not possible
zero division error
คุณสามารถทำมันได้โดยการเข้าถึง Dict namespace ใช้vars()
, locals()
หรือglobals()
แล้วแต่จำนวนใดจะเหมาะสมที่สุดสำหรับสถานการณ์ของคุณ
>>> b = 'some variable'
>>> a = vars().get('c', b)
คุณบอกว่าคุณกำลังใช้ django หากเหมาะสมกับสิ่งที่คุณทำคุณอาจต้องการใช้:
my_instance, created = MyModel.objects.get_or_create()
created
จะเป็นจริงหรือเท็จ บางทีนี่อาจจะช่วยคุณได้
ทำงานบน Python3 ซึ่งได้รับแรงบันดาลใจจาก Walter Mundt
exec("try:some_problematic_thing()\nexcept:pass")
สำหรับหลายบรรทัดเป็นหนึ่งบรรทัด
exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")
Ps: Exec ไม่ปลอดภัยที่จะใช้กับข้อมูลที่คุณไม่สามารถควบคุมได้
หากคุณต้องการจัดการข้อยกเว้นจริง:
(แก้ไขจากคำตอบของ 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
>>>
โปรดทราบว่าหากไม่รองรับข้อยกเว้นจะเพิ่มขึ้นตามที่คาดไว้:
>>> 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'
>>>
หากException
ได้รับมันจะตรงกับสิ่งใดด้านล่าง
( BaseException
สูงกว่าจึงไม่ตรงกัน)
>>> try_or( context, {Exception: lambda: print('exception')} )
exception
นี่คือคำตอบในเวอร์ชันที่ง่ายกว่าจาก @surendra_ben
a = "apple"
try: a.something_that_definitely_doesnt_exist
except: print("nope")
...
nope
ใช้with
ไวยากรณ์ในบรรทัดเดียว:
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
ละเว้นข้อผิดพลาดใด ๆ :
with OK(): 1/0
ละเว้นข้อผิดพลาดที่ระบุ:
with OK(ZeroDivisionError, NameError): 1/0