這個問題有兩個部分。
- 如何,而不是在繼承
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