在对象中设置属性时进行类型检查的最有效方式是什么(“高效”不一定意味着快速,而是“优雅”或“可维护”)?
我可以用它__slots__
来定义允许的属性,但是我应该如何限制类型呢?
当然,我可以为每个属性编写“setter”方法,但我发现维护起来有点麻烦,因为我的类型检查通常很简单。
所以我正在做这样的事情:
import datetime
# ------------------------------------------------------------------------------
# MyCustomObject
# ------------------------------------------------------------------------------
class MyCustomObject(object):
pass
# ------------------------------------------------------------------------------
# MyTypedObject
# ------------------------------------------------------------------------------
class MyTypedObject(object):
attr_types = {'id' : int,
'start_time' : datetime.time,
'duration' : float,
'reference' : MyCustomObject,
'result' : bool,
'details' : str}
__slots__ = attr_types.keys()
# --------------------------------------------------------------------------
# __setattr__
# --------------------------------------------------------------------------
def __setattr__(self, name, value):
if name not in self.__slots__:
raise AttributeError(
"'%s' object has no attribute '%s'"
% (self.__class__.__name__, name))
if type(value) is not self.attr_types[name]:
raise TypeError(
"'%s' object attribute '%s' must be of type '%s'"
% (self.__class__.__name__, name,
self.attr_types[name].__name__))
# call __setattr__ on parent class
super(MyTypedObject, self).__setattr__(name, value)
这对我的目的很好:
>>> my_typed_object = MyTypedObject()
>>> my_typed_object.id = "XYZ"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'id' must be of type 'int'
>>> my_typed_object.id = 123
>>> my_typed_object.reference = []
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'reference' must be of type 'MyCustomObject'
>>> my_typed_object.reference = MyCustomObject()
>>> my_typed_object.start_time = "13:45"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'start_time' must be of type 'time'
>>> my_typed_object.start_time = datetime.time(13, 45)
有一个更好的方法吗?使用 Python 已经有一段时间了,我觉得我正在重新发明轮子。