gpt4 book ai didi

python - 如何在 python 类中属性为 True 时阻止方法

转载 作者:行者123 更新时间:2023-12-05 02:26:29 25 4
gpt4 key购买 nike

我有一个类,其中包含一些属性和更改这些属性的方法。(这是一个最小的例子)

class MyClass:
def __init__(self) -> None:
self.acting = False
self.att1 = None
self.att2 = None
self.att3 = None

def set_att1(self, value):
self.att1 = value

def set_att2(self, value):
self.att2 = value

def set_att3(self, value):
self.att3 = value

def switch_acting(self):
self.acting = not self.acting

我想在 self.acting 为 True 时阻止使用更改某些属性的方法。此 block 可能是引发错误或错误返回。

我知道我可以在每个方法的开头放置一个 if 语句来检查 self.acting 或使用装饰器,但我想以自动方式进行,这样会阻止所有方法的使用以“set”开头的函数,而无需向所有函数添加代码。

我该怎么做?

最佳答案

你可以在这里使用__getattribute__,效果如下:

In [1]: class MyClass:
...: def __init__(self) -> None:
...: self.acting = False
...: self.att1 = None
...: self.att2 = None
...: self.att3 = None
...:
...: def __getattribute__(self, attribute):
...: if attribute.startswith("set_") and not self.acting:
...: raise RuntimeError(f"{self} is not acting")
...: return super().__getattribute__(attribute)
...:
...: def set_att1(self, value):
...: self.att1 = value
...:
...: def set_att2(self, value):
...: self.att2 = value
...:
...: def set_att3(self, value):
...: self.att3 = value
...:
...: def switch_acting(self):
...: self.acting = not self.acting
...:

In [2]: instance = MyClass()

In [3]: instance.set_att1(10)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-3-ead9d2b57142> in <module>
----> 1 instance.set_att1(10)

<ipython-input-1-585c5de84d26> in __getattribute__(self, attribute)
8 def __getattribute__(self, attribute):
9 if attribute.startswith("set_") and not self.acting:
---> 10 raise RuntimeError(f"{self} is not acting")
11 return super().__getattribute__(attribute)
12

RuntimeError: <__main__.MyClass object at 0x7f9a00520af0> is not acting

In [4]: instance.switch_acting()

In [5]: instance.set_att1(10)

In [6]: instance.att1
Out[6]: 10

但是,如评论中所述,这将在查找属性时检查 self.acting 标志,而调用方法时则不一定。

我们可以更小心地处理验证应该在方法被调用而不是被访问时发生的事实:

class MyClass:
def __init__(self) -> None:
self.acting = False
self.att1 = None
self.att2 = None
self.att3 = None

def __getattribute__(self, attribute):
if attribute.startswith("set_"):
bound_method = super().__getattribute__(attribute).__get__(self, type(self))
def _wrapper(*args, **kwargs):
if not self.acting:
raise RuntimeError(f"{self} is not acting")
return bound_method(*args, **kwargs)
return _wrapper
return super().__getattribute__(attribute)

def set_att1(self, value):
self.att1 = value

def set_att2(self, value):
self.att2 = value

def set_att3(self, value):
self.att3 = value

def switch_acting(self):
self.acting = not self.acting

演示:

In [29]: instance = MyClass()

In [30]: instance.set_att1(10)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-30-ead9d2b57142> in <module>
----> 1 instance.set_att1(10)

<ipython-input-28-53d1a32f1498> in _wrapper(*args, **kwargs)
11 def _wrapper(*args, **kwargs):
12 if not self.acting:
---> 13 raise RuntimeError(f"{self} is not acting")
14 return bound_method(*args, **kwargs)
15 return _wrapper

RuntimeError: <__main__.MyClass object at 0x7f99e05bf340> is not acting

In [31]: instance.switch_acting()

In [32]: instance.set_att1(10)

In [33]: instance.att1
Out[33]: 10

In [34]: f = instance.set_att2

In [35]: instance.switch_acting()

In [36]: f(20)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-36-a5c3c0536773> in <module>
----> 1 f(20)

<ipython-input-28-53d1a32f1498> in _wrapper(*args, **kwargs)
11 def _wrapper(*args, **kwargs):
12 if not self.acting:
---> 13 raise RuntimeError(f"{self} is not acting")
14 return bound_method(*args, **kwargs)
15 return _wrapper

RuntimeError: <__main__.MyClass object at 0x7f99e05bf340> is not acting

In [37]: instance.switch_acting()

In [38]: f(20)

In [39]: instance.att2
Out[39]: 20

编辑:我想我做了与你想要的相反的事情,但同样应该有效,只需检查 if self.acting 而不是 if not self.acting

关于python - 如何在 python 类中属性为 True 时阻止方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73747358/

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