【问题标题】:How to get attributes in class that extends from the same parent class如何获取从同一父类扩展的类中的属性
【发布时间】:2019-12-04 03:19:16
【问题描述】:

我定义了几个类

class Animal:
    def do_parent_method():
        pass

class Monkey(Animal):
    pass


class Elephant(Animal):
    pass


@dataclass
class Zoo:
    monkey: Monkey= Monkey()
    elephant: Elephant = Elephant()
    start_time: datetime = None
    name: str = 'Not important at all'

    def data_format(self):
        items = [self.monkey, self.elephant]  # Now I hard code here
        for item in items:
            do_something()

重点是如何获取Zoo类中的属性

也许有一天,我们会在代码中添加另一种动物

@dataclass
class Zoo:
    monkey: Monkey= Monkey()
    elephant: Elephant = Elephant()
    start_time: datetime = None
    name: str = 'Not important at all'

    def data_format(self):
        items = [get the attributes that extends from Animal]  # How to do?
        for item in items:
            do_parent_method()

现在我只希望items 成为一个列表,以便我可以对其进行循环。

或者如果你有其他好主意对我也有好处。

注意:

Zoom 类中的所有属性只有一些 str、datetime、int 类型。所有其他实例将是 Animal 类的子类。

固定:

不小心把'zoo'输入'zoom'

【问题讨论】:

  • @Pynchia:我不明白这有什么关系。简单的isinstance 检查在这里工作得很好,你不需要所有子类的详尽集合来做到这一点。
  • 鉴于 OP 想要所有的动物,为什么必须按名称实例化一个类 var 并进行硬编码?自动实例化它们,每个子类一个并将它们存储在列表中items = [s() for s in Animal.__subclasses__()]

标签: python python-3.x python-dataclasses


【解决方案1】:

The dataclasses.fields function 可以返回一个类的字段信息,包括每个字段的名称和类型。所以你的list理解可以写成:

items = [getattr(self, field.name) for field in fields(self) if issubclass(field.type, Animal)]

这里的缺陷是它不适用于字符串注释,包括模块使用from __future__ import annotations的所有情况。您可以使用技巧 here 解析为实际类型,或者您可以无条件获取所有字段,然后使用 isinstance 检查过滤它们(验证运行时类型,而不是可以在运行时):

items = [attr for attr in (getattr(self, field.name) for field in fields(self)) if isinstance(attr, Animal)]

【讨论】:

  • 尚不清楚 OP 是否希望 Animal 子类的实例出现在数据类中,例如使用zoom_inst.dog。毕竟,Zoom 是一个数据类。
  • @Pynchia:看起来很清楚。他们想要动态生成的[self.monkey, self.elephant] 版本,它可以提取数据类具有的任何属性,这些属性恰好是Animal 子类,而不必一一明确列出。
  • 好的,那我将取消删除我的答案
  • @Pynchia:您的答案是创建一堆new Animal 子类实例,而不是提取任何现有 Animal 子类实例作为属性附加到Zoom 数据类的现有实例。我不确定您从哪里得到创建子类的其他实例有意义的想法。
  • 我知道 OP 想要所有的动物。那么为什么要全部输入呢?除非它们还需要作为数据类的属性出现。这就是为什么我会在这种情况下自动设置这些名称
猜你喜欢
  • 2019-08-11
  • 2013-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多