以下程序测试三个函数,旨在确定类或实例属性是否支持 CRUD 操作。类或实例是can_* 函数的第一个参数,第二个参数是应该检查的属性的名称。类型检查是自动完成的,以确保函数按预期使用。请注意,这仅适用于使用来自 builtins 模块的 property 类创建的属性。
#! /usr/bin/env python3
def main():
for kind in Test, TestG, TestS, TestGS, TestD, TestGD, TestSD, TestGSD:
print(kind.__name__, 'Class')
print(' can_get:', can_get(kind, 'data'))
print(' can_set:', can_set(kind, 'data'))
print(' can_del:', can_del(kind, 'data'))
print()
instance = kind('Hello, world!')
print(kind.__name__, 'Instance')
print(' can_get:', can_get(instance, 'data'))
print(' can_set:', can_set(instance, 'data'))
print(' can_del:', can_del(instance, 'data'))
print()
def can_get(obj, key):
return _get_property(obj, key).fget is not None
def can_set(obj, key):
return _get_property(obj, key).fset is not None
def can_del(obj, key):
return _get_property(obj, key).fdel is not None
def _get_property(obj, key):
if not isinstance(obj, type):
obj = type(obj)
pro = vars(obj).get(key)
if not isinstance(pro, property):
raise TypeError('{.__name__}.{} is not a property'.format(obj, key))
return pro
class Test:
def __init__(self, value):
self.__data = value
def get_data(self):
return self.__data
def set_data(self, value):
self.__data = value
def del_data(self):
del self.__data
data = property()
class TestG(Test):
data = property(fget=Test.get_data)
class TestS(Test):
data = property(fset=Test.set_data)
class TestGS(Test):
data = property(fget=Test.get_data, fset=Test.set_data)
class TestD(Test):
data = property(fdel=Test.del_data)
class TestGD(Test):
data = property(fget=Test.get_data, fdel=Test.del_data)
class TestSD(Test):
data = property(fset=Test.set_data, fdel=Test.del_data)
class TestGSD(Test):
data = property(fget=Test.get_data, fset=Test.set_data, fdel=Test.del_data)
if __name__ == '__main__':
main()