2

我有一个MyClass具有类属性的类SOMETHING

class MyClass(object):
    SOMETHING = 12

我想SOMETHING被强制满足某个条件,例如SOMETHING < 100。我怎么能那样做?

最终,这个类是由用户子类化的,例如:

class MySubClass(MyClass):
    SOMETHING = 13

我一直在研究此处概述的类属性方法,但它们似乎都不能很好地定义主体中的属性。class

例如:

class MyClassMeta(type):
    _SOMETHING = 0

    @property
    def SOMETHING(cls):
        return cls._SOMETHING

    @SOMETHING.setter
    def SOMETHING(cls, something):
        if something < 100:
            cls._SOMETHING = something
        else:
            raise ValueError('SOMETHING must be < 100')


class MyClass(object, metaclass=MyClassMeta):
    # this is ignored
    SOMETHING = 100


x = MyClass()
print(MyClass.SOMETHING)
# 0
print(type(x).SOMETHING)
# 0

但是,如果该属性被正常访问,例如:

MyClass.SOMETHING = 50
print(MyClass.SOMETHING)
# 50
print(type(x).SOMETHING)
# 50

它工作正常,即使是子类化:

class MySubClass(MyClass):
    SOMETHING = 40


y = MySubClass()
print(MySubClass.SOMETHING)
# 50
print(type(y).SOMETHING)
# 50

除了SOMETHING子类中的设置也被忽略。

那么,当在正文中定义时,如何触发@SOMETHING.setter代码的执行?SOMETHINGclass

4

2 回答 2

2

使用以下简单的元类实现在声明阶段验证类特定属性:

class MyClassMeta(type):
    def __new__(cls, clsname, bases, clsdict):
        if clsdict['SOMETHING'] >= 100:  # validate specific attribute value
            raise ValueError(f'{clsname}.SOMETHING should be less than 100')
        return type.__new__(cls, clsname, bases, clsdict)


class MyClass(metaclass=MyClassMeta):
    SOMETHING = 12


class MyChildClass(MyClass):
    SOMETHING = 100

跑步投掷:

ValueError: MyChildClass.SOMETHING should be less than 100

https://docs.python.org/3/reference/datamodel.html#basic-customization

于 2019-08-06T15:10:05.330 回答
0

首先。使用两条下划线保存从外部访问的属性。第二:如果您从基类继承该属性仍然可用。无需重新定义它。

于 2019-08-06T14:35:18.617 回答