如何处理 with 语句中的动态项目数?

How to handle dynamic number of items in with statement?

是否有一种很好的方法来复制以下代码以使用单个 with 语句:

thing1 = Thing()
if two_things: 
    thing2 = Thing()

do_stuff(thing1)

if two_things:
    do_stuff(thing2)

thing1.close()
if two_things: 
    thing2.close()

我可以使用 2 个单独的 with 子句,但如果在这两种情况下共享大量代码,这就很糟糕了。

if two_things:
    with Thing() as thing1, Thing() as thing2:
        do_stuff(thing1)
        do_stuff(thing2)

else: 
    with Thing() as thing:
        do_stuff(thing1)

"Supporting a variable number of context managers"

The primary use case for ExitStack is the one given in the class documentation: supporting a variable number of context managers and other cleanup operations in a single with statement. The variability may come from the number of context managers needed being driven by user input (such as opening a user specified collection of files), or from some of the context managers being optional:

with ExitStack() as stack:
    for resource in resources:
        stack.enter_context(resource)
    if need_special_resource():
        special = acquire_special_resource()
        stack.callback(release_special_resource, special)
    # Perform operations that use the acquired resources