我有一个函数,可以直接调用,也可以通过with语句调用,它的行为应该根据调用方式的不同而有所不同,如果通过with语句调用,则返回一个上下文管理器,否则执行上下文管理器将直接执行的操作。你知道吗
例如
class Context(object):
def __enter__(self):
print('start')
def __exit__(self, exc_type, exc_val, exc_tb):
print('end')
return False
def myfunc():
if called_from_with:
return Context()
else:
print('start')
print('end')
当使用以下命令从调用时:
>>> with myfunc():
>>> print('foo')
start
foo
end
直接调用时:
>>> myfunc()
start
end
有办法吗?你知道吗
编辑:我的用例是针对一个我正在编写html的工具。我把我的初始代码放在这里:https://github.com/garyvdm/htmlwrite(请注意,它目前正在进行中。)
我希望用户能够这样写:
writer = Writer(sys.stdout)
with writer(Tag('div')):
writer('Hello world')
writer(Tag('div', c=("Hello world 2", )))
相反:(注意对.wrapped
的调用)
writer = Writer(sys.stdout)
with writer.wrapped(Tag('div')):
writer('Hello world')
writer(Tag('div', c=("Hello world 2", )))
上下文管理器不限于} 中使用上下文管理器,或者分别调用
with
语句。除了在将管理器与with
(cm = writer(Tag('div'))
,然后是with cm:
)一起使用之前将其分配给变量之外,还可以在^{__enter__
和__exit__
方法。你知道吗更好的选择是始终从函数返回上下文管理器。如果这意味着您还需要提供一个不同的函数来提供行为的非contextmanager版本,那就这样吧。你知道吗
也就是说,您可以根据参数的数量调整行为;这就是^{} 所做的。在内部,您总是创建一个上下文管理器,但是如果有更多的参数,您只需立即应用上下文:
假设您要避免的是双重上下文管理器调用,即同一个上下文管理器不应双重调用,我建议您将上下文管理器修改为可重入的。你知道吗
下面是一个使用事务的简单示例:
相关问题 更多 >
编程相关推荐