gpt4 book ai didi

python - 如何在运行时就地更改类实例行为?

转载 作者:太空宇宙 更新时间:2023-11-03 20:39:52 24 4
gpt4 key购买 nike

我正在进行一个简单的模拟,我想在运行时更改类实例的方法。我对 OOP 还很陌生,所以我不确定哪种方法最适合我的情况。

我创建了几个示例,示例为 Cat类可以在运行时变成僵尸猫,改变它的行为。

class Cat:
def __init__(self, foo):
self.foo = foo
self.is_zombie = False

def turn_to_zombie(self, bar):
self.is_zombie = True
self.zombie_bar = bar

def do_things(self):
if self.is_zombie:
print('Do zombie cat things')
else:
print('Do cat things')

这是期望的行为,但是我想将 Cat 分开和ZombieCat方法并跳过if声明。

class Cat:
def __init__(self, foo):
self. foo = foo

def do_things(self):
print('Do cat things')

def turn_to_zombie(self, bar):
self.bar = bar
self.__class__ = ZombieCat

class ZombieCat(Cat):
def __init__(self, foo, bar):
super().__init__(self, foo)
self.bar = bar

def do_things(self):
print('Do zombie cat things')

这很有效,但我不确定更改 self.__class__ 是否有任何副作用,看来是泄气了How dangerous is setting self.__class__ to something else?

class Cat:
def __init__(self, foo):
self.foo = foo
self.strategy = CatStrategy

def do_things(self):
self.strategy.do_things(self)

def turn_to_zombie(self, bar):
self.bar = bar
self.strategy = ZombieCatStrategy

class CatStrategy:
@staticmethod
def do_things(inst):
print('Do cat things')

class ZombieCatStrategy(CatStrategy):
@staticmethod
def do_things(inst):
print('Do zombie cat things')

在谷歌搜索时,我发现了策略模式。这也有效,但感觉比创建子类有点困惑。例如,当猫是僵尸时要重写附加方法,需要更改 3 个位置而不是 1 个位置。

请随意提出其他模式,我确信有些事情我还没有考虑过。

<小时/>

编辑:在 @martineau 提供了有用的答案后,我想补充一点,如果有任何对 Cat 的引用,这将会很有用。实例在 .turn_to_zombie 时更新被称为,即

cats_list1 = [cat1, cat2]
cats_list2 = [cat1, cat2]
cats_list1[0].do_things() # -> Do cat things
cats_list1[0].turn_to_zombie('bar')
cats_list2[0].do_things() # -> Do zombie cat things

最佳答案

我认为类似的事情:

class Cat:
def __init__(self, foo):
self.foo = foo

def do_things(self):
print('Do cat things')

def turn_to_zombie(self, bar):
self.bar = bar
self.__class__ = ZombieCat

class ZombieCat(Cat):
def __init__(self, foo, bar):
super().__init__(foo)
self.bar = bar

def do_things(self):
print('Do zombie cat things')

class SchroedingerCat:
_cat = Cat
_zombie = ZombieCat
_schroedinger = None

def __init__(self, foo, bar=None):
if bar is not None:
self._schroedinger = self._zombie(foo, bar)
else:
self._schroedinger = self._cat(foo)

def turn_to_zombie(self, bar):
self._schroedinger = self._zombie(self._schroedinger.foo, bar)
return self

def __getattr__(self, name):
return getattr(self._schroedinger, name)

SchroedingerCat('aaa').do_things()
SchroedingerCat('aaa').turn_to_zombie('bbb').do_things()

我认为,自合并类太复杂而且不直观。

黑魔法注意力不要使用它,但它有效:

from functools import partial

class DarkMagicCat:
_cat = Cat
_zombie = ZombieCat
_schroedinger = None

def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
self._schroedinger = self._cat

def turn_to_zombie(self, bar):
self._schroedinger = self._zombie
return self

def __getattr__(self, name):
return partial(getattr(self._schroedinger, name), self=self)

关于python - 如何在运行时就地更改类实例行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56926046/

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