这个问题有两个部分。
- 如何,而不是在继承
Validatable
类一组在子类级别Validatable
数据结构的值;和
- 如何定义
constrain_field
方法,以便它可以在类初始化时调用一次,而不是每次创建实例。
关于(1)中,Validatable
类的初始化可以访问类使用其__class__
属性的实例的。例如:
class Validatable(object):
def __init__(self):
self.__class__.fieldName = "value for " + self.__class__.__name__
class Demo(Validatable):
def __init__(self):
super(Demo, self).__init__()
class Demo2(Validatable):
def __init__(self):
super(Demo2, self).__init__()
d = Demo()
d2 = Demo2()
print "Demo.fieldName = " + Demo.fieldName
print "Demo2.fieldName = " + Demo2.fieldName
此代码打印:
Demo.fieldName = value for Demo
Demo2.fieldName = value for Demo2
的constrain_field
方法然后可以定义为使用它被称为与该实例的__class__
属性建立必要的数据结构。
不幸的是,这一切都要求在可以设置数据结构之前创建类的实例,这也意味着每次创建实例时都会调用constrain_field
方法。显然,最好在类初始化时做到这一点,这是问题的第(2)部分。
要解决第(2)部分,我会推荐使用python decorators。考虑下面的代码,一个名为constrain_field
的定制的装饰功能结合了Python property功能(作为装饰):
def Max(maxValue):
def checkMax(value):
return value <= maxValue
checkMax.__doc__ = "Value must be less than or equal to " + str(maxValue)
return checkMax
def Even():
def checkEven(value):
"Value must be even"
return value%2 == 0
return checkEven
def constrain_field(*constraints):
def constraint_decorator(setter):
def checkConstraints(self, value):
ok = True
for c in constraints:
if not c(value):
ok = False
print "Constraint breached: " + c.__doc__
if ok:
setter(self, value)
return checkConstraints
return constraint_decorator
class Demo(object):
def __init__(self):
self._count = 2
@property
def count(self):
return self._count
@count.setter
@constrain_field(Max(9), Even())
def count(self, value):
self._count = value
d = Demo()
print "Setting to 8"
d.count = 8
print "Setting to 9"
d.count = 9
print "Setting to 10"
d.count = 10
print "Count is now " + str(d.count)
它打印:
Setting to 8
Setting to 9
Constraint breached: Value must be even
Setting to 10
Constraint breached: Value must be less than or equal to 9
Count is now 8
通过以这种方式使用的装饰,所有的在类的定义期间初始化完成一次。
'constraint_field()'是类方法还是静态方法?它是如何定义的? – brandizzi 2011-05-03 22:17:50
这是一个通常的(实例)方法,但我想改变它。本质上,该方法将约束添加到字典名称作为关键字和约束作为值列表。 – deamon 2011-05-04 07:42:13