繁体   English   中英

我怎样才能干净地将 class 属性分配为 Python 中的 class 的实例?

[英]How can I cleanly assign class attributes as an instance of that class in Python?

考虑下面的代码:

class Color:
    RED: "Color"
    GREEN: "Color"
    BLUE: "Color"
    WHITE: "Color"
    BLACK: "Color"

    def __init__(self, r: int, g: int, b: int) -> None:
        self.r = r
        self.g = g
        self.b = b


Color.RED = Color(255, 0, 0)
Color.GREEN = Color(0, 255, 0)
Color.BLUE = Color(0, 0, 255)
Color.WHITE = Color(255, 255, 255)
Color.BLACK = Color(0, 0, 0)

在这里,我正在创建一些颜色定义,可以从Color class 访问它们,并创建自定义颜色实例。 但是,需要在文件的两个不同位置声明然后实例化值感觉有点重复。 最理想的是,我会执行以下操作,但因为它是自引用的,所以我得到了NameError

class Color:
    RED = Color(255, 0, 0)
    GREEN = Color(0, 255, 0)
    BLUE = Color(0, 0, 255)
    WHITE = Color(255, 255, 255)
    BLACK = Color(0, 0, 0)

    def __init__(self, r: int, g: int, b: int) -> None:
        self.r = r
        self.g = g
        self.b = b

有没有一种方法可以让我在一个地方干净地定义我的预设 colors,同时保持类型安全和可读性,或者第一个例子已经和它一样好了吗?

我认为您可以使用两种方法。 您可以为附加到 class 的属性定义装饰器:

class classproperty(property):
    def __get__(self, _, cls):
        return self.fget(cls)

class Color:
    @classproperty
    def RED(cls) -> "Color":
        return cls(255,0,0)
    @classproperty
    def GREEN(cls) -> "Color":
        return cls(0,255,0)
    @classproperty
    def BLUE(cls) -> "Color":
        return cls(0,0,255)
    @classproperty
    def WHITE(cls) -> "Color":
        return cls(255,255,255)
    @classproperty
    def BLACK(cls) -> "Color":
        return cls(0,0,0)

    def __init__(self, r: int, g: int, b: int) -> None:
        self.r = r
        self.g = g
        self.b = b

或者您可以使用元类构建表示 class 类型的“对象”时的属性:

class __Color__metaclass__(type):
    @property
    def RED(cls) -> "Color":
        return cls(255,0,0)
    @property
    def GREEN(cls) -> "Color":
        return cls(0,255,0)
    @property
    def BLUE(cls) -> "Color":
        return cls(0,0,255)
    @property
    def WHITE(cls) -> "Color":
        return cls(255,255,255)
    @property
    def BLACK(cls) -> "Color":
        return cls(0,0,0)

class Color(metaclass=__Color__metaclass__):
    def __init__(self, r: int, g: int, b: int) -> None:
        self.r = r
        self.g = g
        self.b = b

我个人更喜欢元类,因为出于某种原因,我的 IDE 可以从中计算出自动完成,但不能在我装饰的“类属性”上计算。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM