Python 如何在装饰器中使用上下文管理器,以及如何将在装饰器中创建的对象传递给装饰函数
我有一个测试类,需要在最后做一些清理。为了确保用户不会忘记这样做,我想在类中添加一个上下文管理器。我还有一个装饰器,在里面我想使用这个上下文管理器创建一个测试类的对象,并将其传递给装饰函数。有可能吗 这就是我想要做的:Python 如何在装饰器中使用上下文管理器,以及如何将在装饰器中创建的对象传递给装饰函数,python,python-decorators,contextmanager,Python,Python Decorators,Contextmanager,我有一个测试类,需要在最后做一些清理。为了确保用户不会忘记这样做,我想在类中添加一个上下文管理器。我还有一个装饰器,在里面我想使用这个上下文管理器创建一个测试类的对象,并将其传递给装饰函数。有可能吗 这就是我想要做的: class test: def __init__(self, name): self._name = name print "my name is {0}".format(name) def exit(): pri
class test:
def __init__(self, name):
self._name = name
print "my name is {0}".format(name)
def exit():
print "exiting"
@contextmanager
def testcm(self):
print "inside cm"
try:
yield self
finally:
self.exit()
def randomtest(self, str):
print "Inside random test {0}".format(str)
def decorate(name):
def wrapper(testf):
def testf_wrapper(test):
with test(name).testcm() as testobj:
return testf(testobj)
return testf_wrapper
return wrapper
return decorate
@decorate("whatever")
def testf(testobj):
testobj.randomtest("randomness")
函数testf
获取测试类对象-testobj
,并对其进行处理。之后,由于使用了上下文管理器,testcm
确保调用了cleanup函数
因此有两个问题:
您的示例程序中有几个错误,我在所有的
test
/testf
/testobj
冗余中迷失了方向。请允许我直接回答你的问题
如何在装饰器中使用上下文管理器
正如您在其他任何地方使用上下文管理器一样。考虑这个程序,在调用函数:时,使用装饰器透明地将<代码> STR >转换为<代码>文件>代码>。
def opener(func):
def wrapper(name):
with open(name) as input_file:
func(input_file)
return wrapper
@opener
def first_line(fd):
print fd.readline()
first_line('/etc/passwd')
如您所见,decorator函数在调用修饰函数时使用上下文管理器
我如何将在decorator中创建的对象传递给修饰函数,如果我像上面的代码那样传递它,我将如何调用修饰函数
正如您将对象传递给任何函数一样。见我上面的例子。装饰器创建一个文件
对象,并将其传递给装饰函数
为完整起见,以下是您的示例程序,错误已修复:
from contextlib import contextmanager
class test:
def __init__(self, name):
self._name = name
print "my name is {0}".format(name)
def exit(self):
print "exiting"
@contextmanager
def testcm(self):
print "inside cm"
try:
yield self
finally:
self.exit()
def randomtest(self, str):
print "Inside random test {0}".format(str)
def decorate(name):
def wrapper(testf):
def testf_wrapper():
with test(name).testcm() as testobj:
return testf(testobj)
return testf_wrapper
return wrapper
@decorate("whatever")
def testf(testobj):
testobj.randomtest("randomness")
testf()