如何输入检查 class 属性
How to input-check a class property
我有一个 class MyClass
具有 class 属性 SOMETHING
:
class MyClass(object):
SOMETHING = 12
我希望 SOMETHING
被强制执行以满足特定条件,例如SOMETHING < 100
。
我该怎么做?
最终,此 class 应由用户 class 编辑,例如:
class MySubClass(MyClass):
SOMETHING = 13
我一直在研究 class-属性 概述的方法 here,但它们似乎都不能很好地定义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
它工作正常,即使使用 subclassing:
class MySubClass(MyClass):
SOMETHING = 40
y = MySubClass()
print(MySubClass.SOMETHING)
# 50
print(type(y).SOMETHING)
# 50
除了subclass中的设置SOMETHING
也会被忽略。
那么,当 class
的正文中定义了 SOMETHING
时,如何触发 @SOMETHING.setter
代码的执行?
首先。使用两个下划线来保存从外部访问的属性。
第二:如果您从基础 class 继承,则 属性 仍然可用。不需要重新定义它。
使用以下简单的 metaclass 实现来验证 class
声明阶段的特定属性:
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
我有一个 class MyClass
具有 class 属性 SOMETHING
:
class MyClass(object):
SOMETHING = 12
我希望 SOMETHING
被强制执行以满足特定条件,例如SOMETHING < 100
。
我该怎么做?
最终,此 class 应由用户 class 编辑,例如:
class MySubClass(MyClass):
SOMETHING = 13
我一直在研究 class-属性 概述的方法 here,但它们似乎都不能很好地定义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
它工作正常,即使使用 subclassing:
class MySubClass(MyClass):
SOMETHING = 40
y = MySubClass()
print(MySubClass.SOMETHING)
# 50
print(type(y).SOMETHING)
# 50
除了subclass中的设置SOMETHING
也会被忽略。
那么,当 class
的正文中定义了 SOMETHING
时,如何触发 @SOMETHING.setter
代码的执行?
首先。使用两个下划线来保存从外部访问的属性。 第二:如果您从基础 class 继承,则 属性 仍然可用。不需要重新定义它。
使用以下简单的 metaclass 实现来验证 class 声明阶段的特定属性:
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