python 模式装饰器中的奇怪 class 行为
strange class behavior in the python pattern decorator
我想对英雄施加狂暴效果。
Abstract classes:AbstractEffect和AbstractPositive(class继承人),可以接受base参数。接下来,还将创建 AbstractNegative。我不确定继承方案是否正确(Hero ---> AbstractEffect)。
from abc import ABC, abstractmethod
class Hero:
def __init__(self):
self.stats = {"HP": 128}
def get_stats(self):
return self.stats.copy()
class AbstractEffect(ABC):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats()
class AbstractPositive(AbstractEffect):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats()
class Berserk(AbstractPositive):
def __init__(self, base):
self.base = base
self.stats= self.base.stats
self.stats["HP"] += 7
def get_stats(self):
return self.stats
hero = Hero()
brs1 = Berserk(hero)
print('brs1', brs1.get_stats())
brs2 = Berserk(brs1)
print('brs2', brs2.get_stats())
print('brs1', brs1.get_stats())
我要领取
brs1 {'HP': 135}
brs2 {'HP': 142}
brs1 {'HP': 135}
但我明白了
brs1 {'HP': 135}
brs2 {'HP': 142}
brs1 {'HP': 142}
我的错误是什么?
你被路过引用虐了。
在您的代码中,您有 self.stats = self.base.stats
。这不会制作副本。因此,self.stats
对于brs1
和brs2
指的是一样dict
。当您实例化 brs2
时,您更改它,并且该更改反映在 brs1
.
中
self.stats = self.base.stats.copy()
将是一个好的开始,如果 你不希望这种情况发生。
也就是说,我觉得你想用这种方式编写状态效果很奇怪......如果是我,我会让每个状态效果只包含一个修饰符,这取决于角色class 依次处理这些修饰符。
因为以下代码
self.stats = {"HP": 128}
{"HP": 128} 是一个容器
并且,
self.stats = self.base.stats
因此,
当你使用Berserk(heroxxx)增强英雄时,self.stats["HP"] += 7
实际上是在修改原始数据。所以你需要把它改成self.stats = self.base.get_stats()
,然后你就可以得到你想要的了。可以使用以下代码进行测试。
from abc import ABC, abstractmethod
class Hero:
def __init__(self):
self.stats = {"HP": 128}
def get_stats(self):
return self.stats.copy()
class AbstractEffect(ABC):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats
class AbstractPositive(AbstractEffect):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats
class Berserk(AbstractPositive):
def __init__(self, base):
self.base = base
self.stats = self.base.get_stats()
self.stats["HP"] += 7
def get_stats(self):
return self.stats.copy()
hero = Hero()
brs1 = Berserk(hero)
print('brs1', brs1.get_stats())
brs2 = Berserk(brs1)
print('brs2', brs2.get_stats())
print('brs1', brs1.get_stats())
我想对英雄施加狂暴效果。 Abstract classes:AbstractEffect和AbstractPositive(class继承人),可以接受base参数。接下来,还将创建 AbstractNegative。我不确定继承方案是否正确(Hero ---> AbstractEffect)。
from abc import ABC, abstractmethod
class Hero:
def __init__(self):
self.stats = {"HP": 128}
def get_stats(self):
return self.stats.copy()
class AbstractEffect(ABC):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats()
class AbstractPositive(AbstractEffect):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats()
class Berserk(AbstractPositive):
def __init__(self, base):
self.base = base
self.stats= self.base.stats
self.stats["HP"] += 7
def get_stats(self):
return self.stats
hero = Hero()
brs1 = Berserk(hero)
print('brs1', brs1.get_stats())
brs2 = Berserk(brs1)
print('brs2', brs2.get_stats())
print('brs1', brs1.get_stats())
我要领取
brs1 {'HP': 135}
brs2 {'HP': 142}
brs1 {'HP': 135}
但我明白了
brs1 {'HP': 135}
brs2 {'HP': 142}
brs1 {'HP': 142}
我的错误是什么?
你被路过引用虐了。
在您的代码中,您有 self.stats = self.base.stats
。这不会制作副本。因此,self.stats
对于brs1
和brs2
指的是一样dict
。当您实例化 brs2
时,您更改它,并且该更改反映在 brs1
.
self.stats = self.base.stats.copy()
将是一个好的开始,如果 你不希望这种情况发生。
也就是说,我觉得你想用这种方式编写状态效果很奇怪......如果是我,我会让每个状态效果只包含一个修饰符,这取决于角色class 依次处理这些修饰符。
因为以下代码
self.stats = {"HP": 128}
{"HP": 128} 是一个容器
并且,
self.stats = self.base.stats
因此,
当你使用Berserk(heroxxx)增强英雄时,self.stats["HP"] += 7
实际上是在修改原始数据。所以你需要把它改成self.stats = self.base.get_stats()
,然后你就可以得到你想要的了。可以使用以下代码进行测试。
from abc import ABC, abstractmethod
class Hero:
def __init__(self):
self.stats = {"HP": 128}
def get_stats(self):
return self.stats.copy()
class AbstractEffect(ABC):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats
class AbstractPositive(AbstractEffect):
def __init__(self, base):
self.base = base
@abstractmethod
def get_stats(self):
return self.base.stats
class Berserk(AbstractPositive):
def __init__(self, base):
self.base = base
self.stats = self.base.get_stats()
self.stats["HP"] += 7
def get_stats(self):
return self.stats.copy()
hero = Hero()
brs1 = Berserk(hero)
print('brs1', brs1.get_stats())
brs2 = Berserk(brs1)
print('brs2', brs2.get_stats())
print('brs1', brs1.get_stats())