在一个类中,我想定义N个持久属性。我可以按照以下方式实现它们:
@property
def prop1(self):
return self.__prop1
@prop1.setter
def prop1(self, value):
self.__prop1 = value
persistenceManagement()
@property
def prop2(self):
return self.__prop2
@prop2.setter
def prop2(self, value):
self.__prop2 = value
persistenceManagement()
[...]
@property
def propN(self):
return self.__propN
@propN.setter
def propN(self, value):
self.__propN = value
persistenceManagement()
当然,这些块之间唯一不同的是属性名称(prop1,prop2,...,propN)。 persistenceManagement()是一个函数,当其中一个属性的值发生变化时,必须调用它。
由于除了单个信息(即属性名称)之外,这些代码块是相同的,我想必须有一些方法用单行代替这些块中的每一个,声明存在具有给定名称的持久属性。像
这样的东西def someMagicalPatternFunction(...):
[...]
someMagicalPatternFunction("prop1")
someMagicalPatternFunction("prop2")
[...]
someMagicalPatternFunction("propN")
...或者也许是我目前看不到的一些装饰技巧。有人知道如何做到这一点吗?
答案 0 :(得分:3)
属性只是descriptor个类,您可以创建自己的类并使用它们:
class MyDescriptor(object):
def __init__(self, name, func):
self.func = func
self.attr_name = '__' + name
def __get__(self, instance, owner):
return getattr(self, self.attr_name)
def __set__(self, instance, value):
setattr(self, self.attr_name, value)
self.func(self.attr_name)
def postprocess(attr_name):
print 'postprocess called after setting', attr_name
class Example(object):
prop1 = MyDescriptor('prop1', postprocess)
prop2 = MyDescriptor('prop2', postprocess)
obj = Example()
obj.prop1 = 'answer' # prints 'postprocess called after setting __prop1'
obj.prop2 = 42 # prints 'postprocess called after setting __prop2'
您可以选择使用以下内容:
def my_property(name, postprocess=postprocess):
return MyDescriptor(name, postprocess)
class Example(object):
prop1 = my_property('prop1')
prop2 = my_property('prop2')
如果您喜欢装饰器@
语法,您可以这样做(这也减轻了必须两次输入属性的名称) - 但是它需要的虚拟函数看起来有点奇怪......
def my_property(method):
name = method.__name__
return MyDescriptor(name, postprocess)
class Example(object):
@my_property
def prop1(self): pass
@my_property
def prop2(self): pass
答案 1 :(得分:1)
property
类(是的它是一个类)只是descriptor
协议的一种可能实现(这里有完整的文档记录:http://docs.python.org/2/howto/descriptor.html)。只需编写自己的自定义描述符即可完成。