在看flask-admin的源码时,经常看到废弃以前类属性的功能,通过实现一个ObsoleteAttr
来使用新名称替换旧的名称。源码如下:
class ObsoleteAttr(object):
def __init__(self, new_name, old_name, default):
self.new_name = new_name
self.old_name = old_name
self.cache = '_cache_' + new_name
self.default = default
def __get__(self, obj, objtype=None):
print('get', self, obj, objtype)
if obj is None:
return self
# Check if we have new cached value
if hasattr(obj, self.cache):
return getattr(obj, self.cache)
# Check if there's old attribute
if hasattr(obj, self.old_name):
print('Property %s is obsolete, please use %s instead' %
(self.old_name, self.new_name))
return getattr(obj, self.old_name)
# Return default otherwise
return self.default
def __set__(self, obj, value):
setattr(obj, self.cache, value)
在ObsoleteAttr
通过使用__get__
和__set__
进行属性替换和设置值。
在使用时如类A中存在old_name属性,使用new_name属性替换,此时使用方法如下:
class A(object):
new_name = ObsoleteAttr('new_name', 'old_name', None)
class B(A):
old_name = {'hello': 'world'}
B.new_name
b = B()
print b.new_name
('get', <__main__.ObsoleteAttr object at 0x10f7a6890>, None, <class '__main__.B'>)
('get', <__main__.ObsoleteAttr object at 0x10f7a6890>, <__main__.B object at 0x10f7a6b90>, <class '__main__.B'>)
Property old_name is obsolete, please use new_name instead
{'hello': 'world'}
__set__
和__get__
的解释可以参考python文档,后续再补充具体解释。