如何解决在另一个模块中定义的上下文管理器中使本地函数显示为全局
instance = class_with_internal_functionality()
instance.func1()
instance.func2()
instance.func3()
几乎普遍情况下,实例会以各种顺序调用其各种方法来改变其内部状态,有时多达十几次。此外,实例始终用作单例。永远不会同时有两个不同的 class_with_internal_functionality
实例。
简而言之,我试图找到一种方法来用下面的内容替换上面的代码段,而不会一遍又一遍地重复 instance
。此外,如果方法名称在 with- 语句之前已经在全局范围内定义,我们应该只是暂时覆盖它们,直到块结束。
with class_with_internal_functionality() as instance:
func1()
func2()
func3()
这是我的第一次尝试,如果 class_with_internal_functionality
与块在同一个模块中定义,那么效果非常好。
class class_with_internal_functionality:
def __init__(self):
self.defined_globals = dict()
self.local_methods = ['func1']
def __enter__(self):
"""Functionality necessary to use the construction as a context manager.
This makes an instance's methods available as "global" within the context."""
print('entering')
for method_name in self.local_methods:
# If method_name is defined globally,stash its deFinition away until after we exit.
if method_name in globals():
self.defined_globals[method_name] = globals()[method_name]
# Replace the global deFinition with our local deFinition
globals()[method_name] = self.__getattribute__(method_name)
def __exit__(self,*args,**kwargs):
print('exiting')
for method_name in self.local_methods:
# If method_name was prevIoUsly defined before the with-statement,we need to replace it when we leave
if method_name in self.defined_globals:
globals()[method_name] = self.defined_globals[method_name]
else:
del globals()[method_name]
def func1(self):
print('I am inside func1 inside the manager')
def func1():
print('I am the global function')
if __name__ == '__main__':
func1()
print(f'{func1=}')
instance = class_with_internal_functionality()
with instance:
func1()
print(f'{func1=}')
func1()
print(f'{func1=}')
当 with 语句与类在同一个模块中时,这完全按预期工作,具有以下(期望和预期)输出:
I am the global function
func1=<function func1 at 0x112c039d0>
entering
I am inside func1 inside the manager
func1=<bound method class_with_internal_functionality.func1 of <__main__.class_with_internal_functionality object at 0x112c11280>>
exiting
I am the global function
func1=<function func1 at 0x112c039d0>
I am the global function
func1=<function func1 at 0x12103e430>
entering
I am the global function
func1=<function func1 at 0x12103e430>
exiting
I am the global function
func1=<function func1 at 0x12103e430>
我发现这种差异是由 globals()
函数仅在模块范围内工作造成的。因此,当从另一个模块导入类时,它确实确实改变了全局变量,但仅在导入模块的上下文中,而不是在主模块的上下文中。因此,main 中的全局变量实际上从未进行过调整,因此该函数从未被覆盖。
当从另一个模块导入上下文管理器类时,有没有办法完成同样的行为?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。