我有一个python的单例类,它的示例就是这样使用的:
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中的globals永远不会被实际调整,因此该函数永远不会被重写。
当从另一个模块导入上下文管理器类时,是否有方法实现相同的行为?
暂无答案!
目前还没有任何答案,快来回答吧!