我有以下代码:
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
值中的类的实例?
你不能。
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 = {}