복붙노트

[PYTHON] 파이썬에서 중첩 된 try 문?

PYTHON

파이썬에서 중첩 된 try 문?

다음을 수행하는 더 좋은 방법이 있습니까?

try:
    a.method1()
except AttributeError:
    try:
        a.method2()
    except AttributeError:
        try:
            a.method3()
        except AttributeError:
            raise

그것은 꽤 더러운 것처럼 보입니다. 나는 차라리하지 않을 것입니다.

if hasattr(a, 'method1'):
    a.method1()
else if hasattr(a, 'method2'):
    a.method2()
else if hasattr(a, 'method3'):
    a.method3()
else:
    raise AttributeError

최대 효율성을 유지합니다.

해결법

  1. ==============================

    1.아마 당신은 이런 식으로 시도 할 수 있습니다 :

    아마 당신은 이런 식으로 시도 할 수 있습니다 :

    def call_attrs(obj, attrs_list, *args):
        for attr in attrs_list:
            if hasattr(obj, attr):
                bound_method = getattr(obj, attr)
                return bound_method(*args)
    
        raise AttributeError
    

    당신은 이것을 다음과 같이 부를 것입니다 :

    call_attrs(a, ['method1', 'method2', 'method3'])
    

    이렇게하면 목록에있는 순서대로 메소드가 호출됩니다. 인수를 전달하려면 다음과 같이 인수를 전달하면됩니다.

    call_attrs(a, ['method1', 'method2', 'method3'], arg1, arg2)
    
  2. ==============================

    2.두 번째로의 약간의 변경은 꽤 멋지고 단순 해 보인다. 난 당신이 둘 사이의 성능 차이를 확인할 수 있을지 정말 의심 스럽지만, 이것은 중첩 된 try / excepts보다 약간 더 멋지다.

    두 번째로의 약간의 변경은 꽤 멋지고 단순 해 보인다. 난 당신이 둘 사이의 성능 차이를 확인할 수 있을지 정말 의심 스럽지만, 이것은 중첩 된 try / excepts보다 약간 더 멋지다.

    def something(a):
        for methodname in ['method1', 'method2', 'method3']:
            try:
                m = getattr(a, methodname)
            except AttributeError:
                pass
            else:
                return m()
        raise AttributeError
    

    다른 아주 읽을 수있는 방법은 할 ..

    def something(a):
        try:
            return a.method1()
        except:
            pass
    
        try:
            return a.method2()
        except:
            pass
    
        try:
            return a.method3()
        except:
            pass
    
        raise AttributeError
    

    오랫동안 함수가 수행하는 작업은 매우 분명합니다. 성능은 실제로 문제가되어서는 안됩니다 (몇 가지 try / except 문이 스크립트를 눈에 띄게 감속 시키면 스크립트 구조에 더 큰 문제가 있음)

  3. ==============================

    3.

    method = (
            getattr(a, 'method1', None) or
            getattr(a, 'method2', None) or
            getattr(a, 'method3')
            )
    method()
    

    그러면 먼저 method1을 찾은 다음 method2를 찾은 다음 method3을 찾습니다. 검색 중 하나가 발견되는 즉시 검색이 중지됩니다. 메소드가 발견되지 않으면 마지막 getattr은 예외를 발생시킵니다.

  4. ==============================

    4.함수 호출을 캡슐화하는 것은 어떻습니까?

    함수 호출을 캡슐화하는 것은 어떻습니까?

    def method_1_2_or_3():
        try:
            a.method1()
            return
        except AttributeError:
            pass
        try:
            a.method2()
            return
        except AttributeError:
            pass
        try:
            a.method3()
        except AttributeError:
            raise
    
  5. ==============================

    5.소형 솔루션 :

    소형 솔루션 :

    getattr(a, 'method1',
        getattr(a, 'method2',
            getattr(a, 'method3')))()
    
  6. ==============================

    6.새로운 스타일의 객체를 사용하는 경우 :

    새로운 스타일의 객체를 사용하는 경우 :

    methods = ('method1','method2','method3')
    for method in methods:
        try:
            b = a.__getattribute__(method)
        except AttributeError:
            continue
        else:
            b()
            break
    else:
        # re-raise the AttributeError if nothing has worked
        raise AttributeError
    

    물론 새로운 스타일의 객체를 사용하지 않는 경우 __getattribute__ 대신 __dict__을 시도 할 수 있습니다.

    편집 :이 코드는 비명을 혼란을 증명할 수 있습니다. __getattribute__ 또는 __dict__을 찾지 못하면 어떤 종류의 오류가 발생했는지 야생으로 추측하십시오.

  7. from https://stackoverflow.com/questions/701466/nested-try-statements-in-python by cc-by-sa and MIT license