函数如何设置变量的值而不返回该变量的值?

How can a function set the value of a variable without returning the value of that variable?

我想导入一个特殊的、不寻常的模块。为了导入此模块,我必须为其导入准备环境,导入模块,然后在导入后再次更改环境。我可以这样做的方法如下:

argv_tmp = sys.argv
sys.argv = []
from ROOT import *
sys.argv = argv_tmp

我想将围绕实际导入的过程抽象为两个函数,从而产生以下形式的主要代码:

pre_ROOT_import()
from ROOT import *
post_ROOT_import()

这些函数——不带参数且 return 没有值的函数——如何执行这些过程?

是这样的吗?我认为只需将 arg_tmp 拉到函数之外就可以了,函数仍然可以访问它。

import sys
argv_tmp = None

def pre_ROOT_import():
  #set argv_tmp and modify sys.argv
def post_ROOT_import():
  #restore sys.argv to argv_tmp

pre_ROOT_import()
from ROOT import *
post_ROOT_import()

这是 context manager.

的一个非常好的用例
class ArgvContext(object):
    def __enter__(self):
        self.tmp_argv = sys.argv
        sys.argv = []
    def __exit__(self, exc_type, exc_val, exc_tb):
        sys.argv = sys.tmp_argv

用法:

with ArgvContext():
    from ROOT import *

__enter__中的代码在上下文之前执行,__exit__中的代码在上下文之后执行。此处的上下文仅表示 with 语句下缩进的所有内容。使用属性 self 从前到后携带信息。

一个简单的例子:

class Context(object):
    def __enter__(self):
        print('start')
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('end')

with Context():
    print('doing')

打印:

start
doing
end

__exit__中的代码在异常情况下也会执行:

with Context():
    1 / 0

输出:

start
end
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
...
ZeroDivisionError: division by zero

上下文管理器在这里工作得很好。即使在 ROOT 中引发异常,它也会在本地保存 sys.argv 并恢复它。

import contextlib
@contextlib.contextmanager
def argv_tmp():
    tmp = sys.argv
    sys.argv = []
    try:
        yield
    finally:
        sys.argv = tmp

with argv_tmp():
    from ROOT import *