Max*_*axB 12 python python-2.7 python-decorators python-descriptors
我经常发现我需要临时分配一些成员变量,例如
old_x = c.x
old_y = c.y
# keep c.z unchanged
c.x = new_x
c.y = new_y
do_something(c)
c.x = old_x
c.y = old_y
Run Code Online (Sandbox Code Playgroud)
但我希望我能简单地写一下
with c.x = new_x; c.y = new_y:
do_something(c)
Run Code Online (Sandbox Code Playgroud)
甚至
do_something(c with x = new_x; y = new_y)
Run Code Online (Sandbox Code Playgroud)
Python的装饰器或其他语言功能能够实现这种模式吗?(我可以c根据需要修改课程)
Łuk*_*ski 20
可以轻松地使用上下文管理器.
引用官方文档:
上下文管理器的典型用途包括保存和恢复各种全局状态,锁定和解锁资源,关闭打开的文件等.
似乎保存和恢复状态正是我们想要在这里做的.
例:
from contextlib import contextmanager
@contextmanager
def temporary_change_attributes(something, **kwargs):
previous_values = {k: getattr(something, k) for k in kwargs}
for k, v in kwargs.items():
setattr(something, k, v)
try:
yield
finally:
for k, v in previous_values.items():
setattr(something, k, v)
class Something(object):
def __init__(self, x, y):
self.x = x
self.y = y
def say_hello(self):
print("hello", self.x, self.y)
s = Something(1, 2)
s.say_hello() # hello 1 2
with temporary_change_attributes(s, x=4, y=5):
s.say_hello() # hello 4 5
s.say_hello() # hello 1 2
Run Code Online (Sandbox Code Playgroud)
我认为contextmanager应该做你想做的事:
from contextlib import contextmanager
@contextmanager
def current_instance(c, temp_x, temp_y):
old_x, old_y = c.x, c.y
c.x, c.y = temp_x, temp_y
yield c
c.x, c.y = old_x, old_y
with current_instance(c, x, y) as c_temp:
do_something(c_temp)
Run Code Online (Sandbox Code Playgroud)