2016-06-20 10 views
0

두 개의 매개 변수를 반환하는 함수 f이 있습니다. 이 함수 다음에 첫 번째 매개 변수를 사용합니다. 다른 함수와 함께 물건을 붙이기 위해 두 번째 것이 필요합니다. g. 그래서 내 코드는 다음과 같이 보일 것입니다 :with 문에서 함수 호출을 숨기기

이 것은 매우 반복적입니다. 그것 뿐이다

with F() as a: 
    # do stuff with a 

: 나는 객체가 죽을 때 모르는 내 주요 목표는 반복적 인 코드를 제거 할 수 있기 때문에 그러나, 나는 with 문을 사용했다. 나는 기본적으로 이라는 객체를 생성하여 __enter____exit__ 함수 (그리고 분명히 __init__ 함수)를 제공한다.

그러나 with 문이 예외 처리를위한 것이기 때문에이 문제를 처리하는 데 "Python"방식이 적합한 지 궁금합니다. 특히이 __exit__ 함수에는 3 개의 인수가 있는데, 지금은 사용하지 않습니다.

편집 (자세한 설명) : f()으로 전화 할 때마다 b으로 무엇인가를해야합니다. 그 사이에 무슨 일이 있었는지는 중요하지 않습니다. 나는 이것을 g(b)으로 표현했다. 그리고 정확히 이것은 with 문에서 숨어 있습니다. 따라서 프로그래머는 f()을 호출 할 때마다 g(b)을 반복해서 입력 할 필요가 없으므로 매우 복잡하고 혼란스러워 질 수 있습니다. #do stuff with a이 길어질 수 있기 때문입니다.

+0

* * 그것은 매우 반복적인가? 문제가 무엇인지, 또는 컨텍스트 관리자가 최상의 솔루션이라고 생각한 이유는 분명하지 않습니다. 이 코드를 많이 사용한다면, 매개 변수 'a'와'b'를 가진 함수로 만드십시오. 중간에있는 비트가 변경된 경우 추출 할 수 없다고 생각되면 'g'를 호출하기 전에 'a'로 호출하는 함수 인 새 매개 변수를 추가하십시오 (함수는 Python에서 최상위 클래스입니다). 달성하려는 목표에 대해 덜 추상적 인 예를 들어 줄 수 있습니까? 'g' * do *는 무엇을합니까? – jonrsharpe

+1

정확히 어떻게 반복적인지 설명 할 수 있습니까? 또한, 현재 with 문에서'b'를 어떻게 사용하고 있습니까? 개인적으로, 나는 자원처럼 보이는 것에'with'를 사용하는 것을 선호합니다. 다른 대안은 데코레이터를 사용하는 것입니다. – SuperSaiyan

+0

'g'는 정확히 무엇입니까? 예외가 발생하더라도 여전히 발생해야합니까? 그것이 일어나지 않아야한다면, 다른 종류의 정리가 대신 발생해야합니까? – user2357112

답변

1

약간 더 파이썬 방법은 contextlib 모듈을 사용하는 것입니다. 자신의 클래스를 __enter____exit__ 함수로 전개 할 수 있습니다.

from contextlib import contextmanager 

def g(x): 
    print "printing g(..):", x 

def f(): 
    return "CORE", "extra" 

@contextmanager 
def wrap(): 
    a, b = f() 
    try: 
     yield a 
    except Exception as e: 
     print "Exception occurred", e 
    finally: 
     g(b) 
if __name__ == '__main__': 
    with wrap() as x: 
     print "printing f(..):", x 
     raise Exception() 

출력 :

$ python temp.py 
printing f(..): CORE 
Exception occurred 
printing g(..): extra 
+0

틀린 함수에서'@ contextmanager' 데코레이터를 붙 였다고 생각합니다. – user2357112

+0

예, 복사 붙여 넣기 문제였습니다. 고쳐 주셔서 고마워요! – SuperSaiyan

+0

그래, 그게 내가 원하는거야. 하지만 (미래에) 예외를 처리해야한다면 exit와 entry 함수를 가진 자신 만의 멋진 클래스가 필요 하겠지? – hr0m

1

코드를 읽는 다른 사람 (또는 6 개월 만에)의 컨텍스트 관리자는 아마도 자원의 생성/초기화 및 종결/삭제를 의미 할 것이며 이디언을 다시 의도하는 것에 매우주의해야합니다.

당신은 오히려 컨텍스트 매니저보다, 구성을 사용할 수 있습니다 : 그 일의

def func(a, b): 
    # do stuff with a & optionally b 

def new_f(do_stuff): 
    a, b = f() 
    do_stuff(a, b) 
    g(b) 


new_f(func) 
+0

이것은 좋은 것이지만 슬프게도 옵션이 아니다. 좀 더 일반적 일 수 있습니다. 하나의 함수로 다룰 수없는 복잡한'do_stuff'로 보자. – hr0m

+0

당신은 언제나 여러 함수를 하나의 함수로 끌어 올 수있다. 잘 명명되고 잘 문서화 된 함수는 큰 코드 블록보다 낫다. –