如何在Python类内调用类方法?

0 投票
3 回答
52 浏览
提问于 2025-04-14 17:40

当我在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"])

撰写回答