code

한 줄에 try/except를 어떻게 넣어야 합니까?

starcafe 2023. 7. 22. 10:19
반응형

한 줄에 try/except를 어떻게 넣어야 합니까?

파이썬에서 try/except를 한 줄로 바꾸는 방법이 있습니까?

뭐랄까...

b = 'some variable'
a = c | b #try statement goes here

어디에b는 선언된 변수이고c그렇지 않아요... 그래서c실수를 범할 수도 있고,a될 것입니다b...

python3에서는 contextlib을 사용할 수 있습니다.억제:

from contextlib import suppress

d = {}
with suppress(KeyError): d['foo']

이것은 매우 진부하지만 디버깅을 위한 일련의 작업을 작성하고 싶을 때 프롬프트에서 사용했습니다.

exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()"
print "The problem is %s" % problem[1]

대부분의 경우, 저는 한 줄로 시도하지 않는 제한이 전혀 신경 쓰이지 않습니다. 하지만 제가 단지 실험을 할 때, 그리고 제가 리드라인이 대화형 인터프리터에서 코드 덩어리 전체를 한 번에 기억해서 어떻게든 조정할 수 있도록 하고 싶을 때, 이 작은 속임수는 도움이 됩니다.

당신이 성취하려는 실제 목적을 위해, 당신은 시도할 수 있습니다.locals().get('c', b)이상적으로는 로컬 컨텍스트 대신 실제 사전을 사용하거나 설정 가능하거나 설정하지 않은 사전을 실행하기 전에 c를 None에 할당하는 것이 좋습니다.

압축할 방법이 없습니다.try/exceptPython에서 한 줄로 차단합니다.

또한 다른 동적 언어에서와 같이 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]왜냐면[]부울 컨텍스트에서는 false입니다.거짓이 될 수 있는 많은 값이 있기 때문에, 저는 다음을 사용하지 않습니다.or속임수. (이것은 사람들이 말할 때 마주치는 것과 같은 문제입니다.if foo:그들이 의미하는 바로는if foo is not None:.)

제한된 예상 예외가 있는 53280 응답의 버전입니다.

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

또 다른 방법은 컨텍스트 관리자를 정의하는 것입니다.

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:.

문제는 실제로 내가 테스트하려고 하는 django model.objects.get query입니다..get은 데이터를 찾을 수 없는 경우 오류를 반환합니다...그것은 None을 반환하지 않습니다 (나를 짜증나게 하는).

다음과 같은 방법을 사용합니다.

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
parse_float = lambda x, y=exec("def f(s):\n try:\n  return float(s)\n except:  return None"): f(x)

항상 해결책이 있습니다.

Walter Mundt에서 영감을 받아 Python3에서 작업합니다.

exec("try:some_problematic_thing()\nexcept:pass")

여러 개의 선을 하나의 선으로 묶습니다.

exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")

Ps: 제어할 수 없는 데이터에서 Exec을 사용하는 것은 안전하지 않습니다.

다음을 사용하여 네임스페이스 딕트에 액세스하여 이 작업을 수행할 수 있습니다.vars(),locals()또는globals()당신의 상황에 가장 적합한 것.

>>> b = 'some variable'
>>> a = vars().get('c', b)

장고를 사용한다고 말씀하셨습니다.작업에 적합한 경우 다음을 사용할 수 있습니다.

my_instance, created = MyModel.objects.get_or_create()

createdTrue 또 False 됩니 다는가다니.이게 도움이 될지도 몰라요

사용하다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

실제로 예외를 관리해야 하는 경우:
53280의 (poke 53280의 수정서됨에변답

>>> 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

두 줄짜리 버전은 제게 맞지 않습니다.Ubuntu 20.04 x64에서 VSCode를 사용합니다.예외 문을 새 줄로 이동하는 경우에만 작동합니다.시도는 한 줄로 유지될 수 있습니다.그래서 최소한 3줄은 필요합니다.이것이 버그인지 기능인지 알 수 없습니다.

try-except 블록처럼 (어느 정도) 판독되고 매우 더럽지 않은 실제 클린 하나의 라이너는 다음과 같습니다.

val = (lambda: dictionary["wrong key"]) % cept(KeyError) % (lambda: "default value")

이런 설정이 필요합니다.

from infix import mod_infix

def cept(*args, as_exc=False):
    if not args:
        args = Exception

    @mod_infix
    def _cept(f1, f2):
        try:
            return f1()
        except args as e:
            if as_exc:
                return f2(e)
            else:
                return f2()
    return _cept

람다를 없애버리고 싶지만 방법이 없습니다.

는 개인적으로 https://peps.python.org/pep-0463/ 에 대한 거절 통지가 만족스럽지 못하다고 생각합니다.Guido, 만약 당신이 이것을 읽고 있다면, 우리에게 알려주세요.

을 제외하고 try라는 단어를 사용합니다.사전 키를 다루는 것을 제외하고.그러한 경우, 적절한 방법은 다음과 같습니다..getNone사용할 수 없을 때

my_dict = {'a': 1, 'b': 2}
print(my_dict.get('c'))
# Output: None

언급URL : https://stackoverflow.com/questions/2524853/how-should-i-put-try-except-in-a-single-line

반응형