여러 콘텍스트 매니저에 "with" 블록을 생성하시겠습니까?
컨텍스트 매니저를 통해 취득한 오브젝트(A lock, db connection, ip socket 등)가 3개 있다고 가정합니다.다음 방법으로 입수할 수 있습니다.
with lock:
with db_con:
with socket:
#do stuff
하지만 한 블록 안에 할 수 있는 방법은 없을까?비슷한 것
with lock,db_con,socket:
#do stuff
또한 컨텍스트 매니저가 있는 알 수 없는 길이의 객체가 배열되어 있는 경우 다음과 같은 작업을 수행할 수 있습니까?
a=[lock1, lock2, lock3, db_con1, socket, db_con2]
with a as res:
#now all objects in array are acquired
"아니오"라고 대답한 경우, 이러한 기능의 필요성은 디자인이 나쁘기 때문일까요, 아니면 격려로 제안해야 할까요? :-P
Python 2.7 및 3.1 이상에서는 다음과 같이 쓸 수 있습니다.
with A() as X, B() as Y, C() as Z:
do_something()
일반적으로 이 방법을 사용하는 것이 가장 좋지만, 알 수 없는 길이의 컨텍스트 관리자 목록이 있는 경우 다음 방법 중 하나가 필요합니다.
Python 3.3에서는 다음을 사용하여 알 수 없는 길이의 컨텍스트 매니저 목록을 입력할 수 있습니다.
with ExitStack() as stack:
for mgr in ctx_managers:
stack.enter_context(mgr)
# ...
이것에 의해, 콘텍스트 매니저를 추가하면서, 그것들을 작성할 수 있습니다.ExitStack이를 통해 에 발생할 수 있는 문제를 방지할 수 있습니다.contextlib.nested(아래 참조).
contextlib2는 Python 2.6 및 2.7의 백포트를 제공합니다.
Python 2.6 이하에서는 다음을 사용할 수 있습니다.
from contextlib import nested
with nested(A(), B(), C()) as (X, Y, Z):
do_something()
는 다음과 같습니다.
m1, m2, m3 = A(), B(), C()
with m1 as X:
with m2 as Y:
with m3 as Z:
do_something()
이것은 보통 nested를 사용하는 것과 완전히 동일하지 않습니다.with,왜냐면A(),B(),그리고.C()콘텍스트 매니저로 이행하기 전에, 처음에 모든 것이 콜 됩니다.이러한 함수 중 하나가 예외를 발생시키면 올바르게 작동하지 않습니다.
contextlib.nested는 위의 메서드보다 새로운 Python 버전에서는 권장되지 않습니다.
python 3.10부터 괄호 안의 콘텍스트 매니저를 사용할 수 있게 되었습니다!감사합니다 @iforapsy!
with (
mock.patch('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') as a,
mock.patch('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb') as b,
mock.patch('cccccccccccccccccccccccccccccccccccccccccc') as c,
):
do_something()
python 버전 3.10 미만의 경우
@interjay's Answer는 정답입니다.그러나 mock.patch 콘텍스트 매니저 등 긴 콘텍스트 매니저에 대해 이 작업을 수행해야 하는 경우에는 이 작업을 여러 회선에 걸쳐 중단해야 한다는 것을 금방 알 수 있습니다.파렌으로 포장할 수 없기 때문에 백슬래시를 사용해야 합니다.다음은 예를 제시하겠습니다.
with mock.patch('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') as a, \
mock.patch('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb') as b, \
mock.patch('cccccccccccccccccccccccccccccccccccccccccc') as c:
do_something()
항목이 여러 개일 경우 컨텍스트 매니저는 문이 여러 개 중첩된 것처럼 처리됩니다.
with A() as a, B() as b: suite와 동등하다
with A() as a: with B() as b: suite버전 3.1에서 변경: 멀티 컨텍스트 표현 지원
, 그럼 두 은 '어울리지 않다'로 .contextlib.ExitStackPython 3.3에 있습니다.
@sage88의 응답에 따라 패치를 입력하기 전에 항상 의미 있는 변수 이름을 지정하도록 패치를 할당할 수 있습니다.
이러한 패치를 여러 줄에 걸쳐 생성할 수 있습니다.
a_patch = mock.patch('aaaaaaa')
b_patch = mock.patch('bbbbbbb')
c_patch = mock.patch('ccccccc')
with a_patch as a, b_patch as b, c_patch as c:
do_something()
언급URL : https://stackoverflow.com/questions/3024925/create-a-with-block-on-several-context-managers
'source' 카테고리의 다른 글
| MYSQL의 LIMIT 값이 클수록 쿼리가 느려지는 이유는 무엇입니까? (0) | 2023.01.06 |
|---|---|
| JSON에서 새로운 회선을 처리하려면 어떻게 해야 합니까? (0) | 2023.01.06 |
| API를 이용하여 인스타그램에 사진을 올리는 방법 (0) | 2023.01.06 |
| 비동기 화살표 함수의 구문 (0) | 2023.01.06 |
| MySQL Alias 값을 기반으로 한 더하기 및 빼기 (0) | 2023.01.06 |