如何获取数据类中的属性数量?

How to get number of attributes in a dataclass?

我想获取 Recipes class 中的食谱数量。我该怎么做?

from dataclasses import dataclass

@dataclass
class Recipe:
    ing1: str
    ing2: str
    ing3: str
   
class Recipes():
    pass
   
setattr(Recipes, 'Salad', Recipe('cabbage', 'lettuce', 'potato')
setattr(Recipes, 'Salad2', Recipe('tomato', 'lettuce', 'ranch')
print("There are %s number of recipes!" % # thing that gets number of attributes here #)
# prints 2

这就是我目前所拥有的。我想要最后的东西打印 class 中的食谱数量(目前是 2)。

编辑: 我不能使用 dict 或 lists 因为这只是对我正在做的事情的测试。

您可以遍历Recipes.__dict__来统计Recipe类型的所有条目。此字典包含所有设置属性和少量其他条目。

Try it online!

from dataclasses import dataclass

@dataclass
class Recipe:
    ing1: str
    ing2: str
    ing3: str
   
class Recipes():
    pass
   
setattr(Recipes, 'Salad', Recipe('cabbage', 'lettuce', 'potato'))
setattr(Recipes, 'Salad2', Recipe('tomato', 'lettuce', 'ranch'))

cnt = 0
for k, v in Recipes.__dict__.items():
    if type(v) is Recipe:
        cnt += 1

print(f"There are {cnt} number of recipes!")

输出:

There are 2 number of recipes!

我感到困惑的是你提到你不想使用 dict 对象,但是 class __dict__mappingproxy 类型的对象- 你可以为前者确定。使用 type(Recipe.__dict__) - 我认为这在技术上是一种 dict 类型。

下面的替代解决方案根本不使用 class 级别 __dict__ 来存储 Recipies,而是使用函数 locals() 对象来存储它,只是为了绘制一个这和 __dict__ 之间的平行,我觉得在这方面非常相似。

from dataclasses import dataclass


@dataclass
class Recipe:
    ing1: str
    ing2: str
    ing3: str


def perform_recipe_related_hackery():
    locals()['Salad'] = Recipe('cabbage', 'lettuce', 'potato')
    locals()['Salad2'] = Recipe('tomato', 'lettuce', 'ranch')

    print(f'There are {len(locals())} number of recipes!')
    # prints 2


perform_recipe_related_hackery()

但是如果你想真的很聪明,你也可以像最初希望的那样使用__dict__setattr完全没有 使用单独的 class!下面是一个用函数代替 class 的例子,目的相同:

from dataclasses import dataclass


@dataclass
class Recipe:
    ing1: str
    ing2: str
    ing3: str


def perform_recipe_related_hackery():

    def my_func():
        ...

    setattr(my_func, 'Salad', Recipe('cabbage', 'lettuce', 'potato'))
    setattr(my_func, 'Salad2', Recipe('tomato', 'lettuce', 'ranch'))
    
    return my_func


x = perform_recipe_related_hackery()
print(f'There are {len(x.__dict__)} number of recipes!')
# prints 2

输出:

There are 2 number of recipes!