gpt4 book ai didi

Python 如何通过上下文管理器强制对象实例化?

转载 作者:太空狗 更新时间:2023-10-30 01:06:02 26 4
gpt4 key购买 nike

我想通过类上下文管理器强制对象实例化。所以不能直接实例化。

我实现了这个解决方案,但从技术上讲,用户仍然可以实例化对象。

class HessioFile:
"""
Represents a pyhessio file instance
"""
def __init__(self, filename=None, from_context_manager=False):
if not from_context_manager:
raise HessioError('HessioFile can be only use with context manager')

和上下文管理器:

@contextmanager
def open(filename):
"""
...
"""
hessfile = HessioFile(filename, from_context_manager=True)

有更好的解决方案吗?

最佳答案

如果您认为您的客户将遵循基本的 Python 编码原则,那么您可以保证如果您不在上下文中,您的类中的任何方法都不会被调用。

您的客户端不应该显式调用 __enter__,因此如果调用了 __enter__,您就知道您的客户端使用了 with 语句并且是因此在上下文中(__exit__ 将被调用)。

你只需要有一个 bool 变量来帮助你记住你是在上下文中还是在上下文之外。

class Obj:
def __init__(self):
self._inside_context = False

def __enter__(self):
self._inside_context = True
print("Entering context.")
return self

def __exit__(self, *exc):
print("Exiting context.")
self._inside_context = False

def some_stuff(self, name):
if not self._inside_context:
raise Exception("This method should be called from inside context.")
print("Doing some stuff with", name)

def some_other_stuff(self, name):
if not self._inside_context:
raise Exception("This method should be called from inside context.")
print("Doing some other stuff with", name)


with Obj() as inst_a:
inst_a.some_stuff("A")
inst_a.some_other_stuff("A")

inst_b = Obj()
with inst_b:
inst_b.some_stuff("B")
inst_b.some_other_stuff("B")

inst_c = Obj()
try:
inst_c.some_stuff("c")
except Exception:
print("Instance C couldn't do stuff.")
try:
inst_c.some_other_stuff("c")
except Exception:
print("Instance C couldn't do some other stuff.")

这将打印:

Entering context.
Doing some stuff with A
Doing some other stuff with A
Exiting context.
Entering context.
Doing some stuff with B
Doing some other stuff with B
Exiting context.
Instance C couldn't do stuff.
Instance C couldn't do some other stuff.

由于您可能有很多方法想要“保护”不被外部上下文调用,因此您可以编写一个装饰器来避免重复相同的代码来测试您的 bool 值:

def raise_if_outside_context(method):
def decorator(self, *args, **kwargs):
if not self._inside_context:
raise Exception("This method should be called from inside context.")
return method(self, *args, **kwargs)
return decorator

然后将您的方法更改为:

@raise_if_outside_context
def some_other_stuff(self, name):
print("Doing some other stuff with", name)

关于Python 如何通过上下文管理器强制对象实例化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40301963/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com