如何键入提示类属性和实例属性之间的链接?

问题描述 投票:0回答:1

我有以下代码:

class ParentClass():
    """ParentClass code goes here"""

class ParentCategoryClass():
    """Subclasses of this class are supposed to regroup instances of one or several ParentClass subclasses"""
    elements:dict[str, type[ParentClass]] #This lists the ParentClass subclasses that the category is going to hold

    def __init__(self)
        self.content:dict[str,ParentClass] = {} #This will be filled later with instances of the classes in elements

我想以某种方式指定

content
属性将专门具有
ParentClass
中的
elements
子类的实例。

例如,另一个文件可能有:

class ChildClass(ParentClass):
    """This one is actually going to be instanciated"""

class ChildCategoryClass(ParentCategoryClass):
    """This one is also going to be instanciated"""
    elements: {"child class": ChildClass}
    # The values in the content dictionary of a ChildCategoryClass will always be ChildClass instances. But I'm not redefining the __init__, so I can't specify that (plus it would be redundant with the elements attribute).

elements
类属性中还可以有多个子类。

我尝试使用

TypeVar
和以下代码:

class ParentClass():
    """ParentClass code goes here"""

ChildClassVar = TypeVar("ChildClassVar", bound=ParentClass)
class ParentCategoryClass():
    """Subclasses of this class are supposed to regroup instances of one or several ParentClass subclasses"""
    elements:dict[str, type[ChildClassVar]] #This lists the ParentClass subclasses that the category is going to hold

    def __init__(self)
        self.content:dict[str,ChildClassVar] = {} #This will be filled later with instances of classes in elements

但是 linter 说

ChildClassVar
在这种情况下没有任何意义。我也怀疑这首先是否适用于几个儿童班级。

如何指定

content
属性的值始终是
elements
值中的类的实例?

python type-hinting python-typing
1个回答
0
投票

你不能。

dict
的类型根据键和值的类型进行参数化,而不是根据值本身进行参数化。

您想要强制执行的是严格的动态属性,即

isinstance(contents[x], elements[x])

适用于所有按键

x
。这是应该通过运行时类型检查来处理的事情,无论将元素添加到任一字典中。


如果

elements
的内容实际上是静态确定的(并且无法在运行时更改),您可以定义一个
TypeDict
来用于
content
的类型,并使用该定义来填充
elements 
.

class ContentType(TypedDict):
    foo: FooSubclass
    bar: BarSubclass


class ParentCategoryClass():
    elements = ContentType.__annotations__

    def __init__(self)
        self.content: ContentType = {}
© www.soinside.com 2019 - 2024. All rights reserved.