如何在Python类内调用类方法?
当我在init方法中调用类方法时,也就是在我初始化一个对象的时候,类方法count_genre每次都会被调用,导致之前的值不断增加。我只想让这个方法调用一次。
class Furniture:
materials = []
material_count = {}
def __init__(self, name, material):
self.name = name
self.material = material
Furniture.materials.append(self.material)
Furniture.count_material()
@classmethod
def count_material(cls):
for material in cls.materials:
cls.material_count[material] = cls.material_count.get(material, 0) + 1
Furniture("Chair", "Wood")
Furniture("Cushion", "Cotton")
Furniture("Table", "Glass")
print(Furniture.material_count)
这是我在终端上看到的结果:{'Chair': 3, 'Cushion': 2, 'Table': 1}
而我想要的结果是:{'Chair': 1, 'Cushion': 1, 'Table': 1}
相关问题:
3 个回答
0
问题在于,每次创建一件新家具时,材料都会被添加到物料清单(BOM)中,而物料清单里的所有材料都会被计算一次。这就意味着,如果你用同样的材料创建了好几件家具,这种材料就会被重复计算多次。
一个简单的解决办法是用一个集合来代替材料列表,这样可以自动去掉重复的材料。然后在计算材料数量之前,可以把这个集合转换成列表。
下面是解决这个问题的逻辑:
定义一个家具类(Furniture),里面有两个属性:材料(materials)和材料计数(material_count)。材料是一个数组,用来存储家具中使用的独特材料,而材料计数是一个字典,用来记录每种材料的数量。
定义一个init方法,这个方法在创建新家具对象时会被执行。这个方法会把新对象的材料添加到材料集合中,然后调用计数材料的方法。
定义一个计数材料的方法,这个方法会更新材料计数字典,记录每种材料在材料集合中的数量。因为材料是一个集合,所以每种材料只会被计算一次,无论有多少个家具对象使用了它。
创建一些家具,并打印材料计数字典,以验证每种材料只被计算了一次。
class Furniture:
materials = set()
material_count = {}
def __init__(self, name: str, material: str):
self.name = name
self.material = material
Furniture.materials.add(self.material)
Furniture.count_material()
@classmethod
def count_material(cls):
cls.material_count = {material: 1 for material in cls.materials}
Furniture("Chair", "Wood")
Furniture("Cushion", "Cotton")
Furniture("Table", "Glass")
print(Furniture.material_count) # {'Cotton': 1, 'Wood': 1, 'Glass': 1}
0
这里是根据你的问题逻辑,以及你最后一个问题对我回答的补充:
class Furniture:
materials = set()
material_count = {}
def __init__(self, name: str, material: str):
self.name = name
self.material = material
Furniture.materials.add(self.material)
Furniture.count_material(self.material)
@classmethod
def count_material(cls, material):
if material in cls.material_count:
cls.material_count[material] += 1
else:
cls.material_count[material] = 1
Furniture("Chair", "Wood")
Furniture("Cushion", "Cotton")
Furniture("Table", "Glass")
Furniture("Cushion", "Cotton")
print(Furniture.material_count) # {'Wood': 1, 'Cotton': 2, 'Glass': 1}
1
用 Furniture 来表示一件家具。再用一个单独的类来表示一组特定的家具信息。
import dataclass
import collections
@dataclasses.dataclass
class Furniture:
name: str
material: str
class FurnitureCollection:
def __init__(self):
self.material_count = collections.Counter()
self.pieces = []
def add(self, f: Furniture):
self.pieces.append(f)
self.material_count[f.material] += 1
@property
def materials(self):
return list(self.material_count)
fc = FurnitureCollection()
fc.add(Furniture("Char", "Wood"))
fc.add(Furniture("Cushion", "Cotton"))
fc.add(Furniture("Table", "Glass"))
assert fc.material_count["Wood"] == 1
assert all(x in fc.materials for x in ["Wood", "Cotton", "Glass"])