ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

暂时在Python中更改变量的值

2019-06-12 11:47:00  阅读:320  来源: 互联网

标签:python with-statement contextmanager


Python 3.4提供了这个简洁的工具来暂时重定向stdout:

# From https://docs.python.org/3.4/library/contextlib.html#contextlib.redirect_stdout
with redirect_stdout(sys.stderr):
    help(pow)

The code并不是非常复杂,但我不想一遍又一遍地写它,特别是因为一些想法已经进入它使它重新进入:

class redirect_stdout:
    def __init__(self, new_target):
        self._new_target = new_target
        # We use a list of old targets to make this CM re-entrant
        self._old_targets = []

    def __enter__(self):
        self._old_targets.append(sys.stdout)
        sys.stdout = self._new_target
        return self._new_target

    def __exit__(self, exctype, excinst, exctb):
        sys.stdout = self._old_targets.pop()

我想知道是否有一般方法使用with语句来临时更改变量的值. sys中的另外两个用例是sys.stderr和sys.excepthook.

在一个完美的世界中,这样的东西会起作用:

foo = 10
with 20 as foo:
    print(foo) # 20
print (foo) # 10

我怀疑我们能做到这一点,但也许这样的事情是可能的:

foo = 10
with temporary_set('foo', 20):
    print(foo) # 20
print (foo) # 10

我可以通过在globals()中生根来解决这个问题,但是没有人会选择使用它.

更新:虽然我认为我的“foo = 10”示例澄清了我正在尝试做的事情,但它们没有传达实际的用例.这是两个:

>重定向stderr,就像redirect_stdout一样
>暂时更改sys.excepthook.我以交互方式进行了大量的开发,当我向excepthook添加一些内容时(通过将原始函数包装在我自己的函数中,比如使用日志记录模块记录异常),我通常希望它在某些时候被删除.这样我就不会有越来越多的函数包装本身. This question面临一个密切相关的问题.

解决方法:

我知道这个问题有点陈旧,但当我遇到同样的问题时,这是我的解决方案:

class test_context_manager():
    def __init__(self, old_object, new_object):
        self.new = new_object
        self.old = old_object
        self.old_code = eval(old_object)
    def __enter__(self):
        globals()[self.old] = self.new
    def __exit__(self, type, value, traceback):
        globals()[self.old] = self.old_code

它并不漂亮,因为它大量使用全局变量,但似乎有效.

例如:

x = 5
print(x)
with test_context_manager("x", 7):
    print(x)

print(x)

结果:

5
7
5

或具有功能:

def func1():
    print("hi")

def func2():
    print("bye")

x = 5
func1()
with test_context_manager("func1", func2):
    func1()

func1()

结果:

hi
bye
hi

标签:python,with-statement,contextmanager
来源: https://codeday.me/bug/20190612/1225540.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有