2011-03-31 5 views
1

나는 내가해야 할 일련의 호출을 가지고 있는데,이 모든 것은 예외를 던질 수 있고 호출을 보호하기위한 좋은 방법이 필요하다. 파이썬에서 다음을 수행하는보다 전문적인 방법을 찾으려고합니다.파이썬에서 보호 된 메서드 호출?

def protected_call(method): 
    result = None 
    try: 
     result= method() 
    except: pass 

    return result 
class Test(): 


    def terminate(): 
    protected_call(self.could_throw_exception) 
    protected_call(self.receiver.stop) 
    protected_call(self.connection.stop) 
    #etc 

더 좋은 방법이 있습니까? 어쩌면 주석이 있습니까?

class Receiver(): 
    @protected 
    def stop(): 
    print 'I dont want to do this' 

class Test(): 
    @protected 
    def could_throw_exception(): 
    print 'dont want this' 
    def stop(): 
    self.could_throw_exception() 
    self.receiver.stop() 

이 내가 원하는 것입니다 :

그냥 내가 원래의 방법, 즉에 주석을 넣어 싶지 않는 , 명확히하기 위해

class Receiver(): 
    def stop(): 
    print 'I want this' 

class Test(): 

    def could_throw_exception(): 
    print 'like this' 

    '''This one cares about crashing''' 
    def stop() 
    self.could_throw_exception() 
    self.receiver.stop() 
    self.connection.stop() 

    '''This one does not''' 
    def terminate(): 
    #i want to define it at the call level. 
    @protected 
    self.could_throw_exception() 
    @protected 
    self.receiver.stop() 
+3

예외를 무시 하시겠습니까? 그것은 좋은 생각처럼 보이지 않습니다. [with] (http://docs.python.org/reference/compound_stmts.html#the-with-with-statement) 및 [finally] (http://docs.python.org/reference/compound_stmts.html#the -try-statement). – nmichaels

+0

나에게 잘 어울리지 만, 왜 모든 예외를 무시하는 테스트가 필요하겠습니까? –

+1

현실에서는 모든 통신/전송 예외를 잡으려고합니다. 그러나 exapmle에 대해서는 복잡한 것을 원하지 않았습니다. 이것은 종료 프로세스의 일부이므로 gracefuly를 종료 할 스레드를 요청하고 있습니다 ... 계속 진행할 때주의 할 사항이 없다면. 나는 예외 목록을 protected_call ..에 전달하는 것에 대해 생각했다. – Nix

답변

3

nmichaels 제안으로는, 이런 종류의 일이 가장 with 문을 통해 처리되는 장식을위한 작업 같은데.

@contextlib.contextmanager 
def suppress_exceptions(*exceptions): 
    if not exceptions: 
     exceptions = Exception 
    try: 
     yield 
    except exceptions: 
     # You would log an error here 
     # If you have logging in your application 
     pass 

with suppress_exceptions(): 
    1/0 

print("Ignored the exception!") 

with suppress_exceptions(IOError): 
    1/0 

# The second one will let the exception through 
+0

이것은 지저분 해 보일지 모르지만, 내가 필요한 것을 성취 할 수있는 유일한 방법이라고 생각합니다 (인스턴스 레벨 "데코레이터"). – Nix

3

실내 장식이 완벽한 것입니다 :

def protected_call(method): 
    def wrapper(*args, **kwargs): 
     try: 
      return method(*args, **kwargs) 
     except: 
      pass 
    return wrapper 

샘플 사용 :

@protected_call 
def foo(): 
    raise Exception() 

# nothing is being raised 
foo() 
+0

이 작업은 인스턴스 수준에서 어떻게 작동합니까? – Nix

+0

데코레이터는 foo = protected_call (foo)를 작성한 것처럼 작동합니다. – slezica

+0

인스턴스에서이를 정의 할 수 있기를 원합니다. 다른 클라이언트가 foo()를 호출하려는 경우가 발생할 것입니다. 예외를 참조하십시오. 나는 위에 설명하려고 노력할 것이다 ... – Nix

0

적어도 로깅 예외가 유용한 기능인 것처럼 보입니다. 예기치 않은 오류를 제어 할 수있는 방법은 무엇입니까?

+0

나는 스레드를 소유하고있다. 종료하지 않으려는 경우 gracefuly 나는 정말로 신경 쓰지 않는다. (어느 정도는 mem 누수가 걱정된다.) 나는 모든 것을 다시 초기화 할 것이다. – Nix

1

def protected_call(func): 
    def inner(*args, **kw): 
     try: 
      return func(*args, **kw) 
    except: 
      pass 
    return inner 

class Test(): 

    @protected_call 
    def throws_exception(self): 
     print 1/0 

    @protected_call 
    def no_exception(self): 
     print 4 

    def sometimes_need_exception(self): 
     print 5 
    protected_sometimes_need_exception = protected_call(sometimes_need_exception) 

    def stop(self): 
     self.throws_exception() 
    self.no_exception() 
+0

전화를 걸 때이 작업을 수행 할 수 있기를 원합니다. 사람들이이 예외가 발생했다는 것을 알아야 할 필요가 있기 때문입니다. 나는 다른 호출에서 이것을 감싸 야한다고 추측하고있다. 위에서 추가 섹션을 추가했습니다. – Nix

+0

@Nix, 데코 레이팅 된 메서드가 다른 이름으로 바인딩 된 예제를 추가했습니다 –

+0

그래서 모든 호출을 래핑하지 않습니까? – Nix

관련 문제