使一个类成为常量谁的类型是它所在的类

2024-06-16 11:41:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python类,它具有特殊的值“EMPTY”和“UNIVERSE”:

class RealSet:
    """Continuous open, half-open, and closed regions and discreet values of the Reals"""

    # implementation placeholder
    def __init__(self, intervals, *, canonicalize):
        pass

# Outside the class

RealSet.EMPTY = RealSet(tuple(), canonicalize=False)  # type: ignore
RealSet.UNIVERSE = RealSet(((None, None),), canonicalize=False)  # type: ignore

但是,linting、代码完成等不喜欢这样,因为它们不被视为类的静态属性。即使设置它们也会报告为mypy错误,因此# type: ignore

以下操作不起作用,因为我无法在类作用域中构造RealSet,因为它还不存在:

class RealSet:
    """Continuous open, half-open, and closed regions and discreet values of the Reals"""
    ...
    ...

    EMPTY = RealSet(tuple(), canonicalize=False)  # error
    UNIVERSE = RealSet(((None, None),), canonicalize=False)  # error

这不起作用,因为它定义了实例属性,而不是类属性:

class RealSet:
    """Continuous open, half-open, and closed regions and discreet values of the Reals"""
    ...
    ...

    EMPTY: "RealSet"
    UNIVERSE: "RealSet"

# Outside the class

RealSet.EMPTY = RealSet(tuple(), canonicalize=False)
RealSet.UNIVERSE = RealSet(((None, None),), canonicalize=False)

这似乎是Python类设计中的一个关键问题。如果属性的类型是它所在的类,如何生成类属性?奖励:让它们保持不变


Tags: andthenonefalse属性openclassempty
2条回答

可以使用^{}注释类变量:

class RealSet:
    def __init__(self, intervals, *, canonicalize):
        pass

    EMPTY: ClassVar['RealSet']
    UNIVERSE: ClassVar['RealSet']


RealSet.EMPTY = RealSet(tuple(), canonicalize=False)
RealSet.UNIVERSE = RealSet(((None, None),), canonicalize=False)

从Python 3.9开始^{}可以修饰其他描述符,如property。这样就可以创建“类属性”:

class RealSet:
    def __init__(self, intervals, *, canonicalize):
        pass

    @classmethod
    @property
    def EMPTY(cls):
        return cls(tuple(), canonicalize=False)

    @classmethod
    @property
    def UNIVERSE(cls):
        return cls(((None, None),), canonicalize=False)

相关问题 更多 >