我正在编写一个小的验证应用程序接口,并初始化类的__init__方法中每个字段的约束。但是这个设置主要是针对类一次完成的。
class Demo(Validatable):
def __init__(self):
Validatable.__init__(self)
self.count = 11
# could be done at class level
self.constrain_field("count", Max(9), Even())但问题是,每个字段的约束都必须存储在某个地方,这样做的数据结构是继承的类Validatable的一部分。所以所有的派生类都将共享相同的数据结构,如果约束是在类级别设置的,那么什么都不应该发生!
class Demo(Validatable):
# doesn't work!
Validatable.constrain_field("count", Max(9), Even())
def __init__(self):
self.count = 11是否有可能继承数据结构并在派生类中的类级别对其进行初始化,而不共享约束的数据结构?
发布于 2011-05-04 10:06:26
这个问题有两个部分。
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。考虑以下代码,它将Python property函数(用作装饰器)与名为constrain_field的自定义装饰器函数组合在一起
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通过以这种方式使用装饰器,所有初始化都在类的定义过程中完成一次。
https://stackoverflow.com/questions/5875834
复制相似问题