在python中,需要對某個實例attribute增加除訪問與修改之外的其他處理邏輯,比如類型檢查或合法性驗證。下面通過兩種方法進行實現。(具體參考《python cookbook》)
# -*- coding:utf-8 -*-
#getter和setter主要用於實例屬性的檢測
#以下是通過類的方式實現的實例屬性的檢測,
#但是如果有很多屬性需要檢測,則將實現很多冗餘的代碼。
#因此可以通過第二種方法進行解決。
class NameAge:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str):
raise TypeError("name must be a string")
else:
self._name = value
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise TypeError("age must be a int")
else:
self._age = value
#第二種方法
def typed_property(name, expected_type):
storage_name = '%s%s' %('_', name)
@property
def proper(self):
return getattr(self, storage_name)
@proper.setter
def proper(self, value):
if not isinstance(value, expected_type):
raise TypeError("{0} must be a {1}".format(name, expected_type))
else:
setattr(self, storage_name, value)
return proper
class NameAge2:
name = typed_property('name', str)
age = typed_property('age', int)
def __init__(self, name, age):
self.name = name
self.age = age
def main():
obj1 = NameAge("alice", 10)
print("Obj1 -> name: {0} age: {1}".format(obj1.name, obj1.age))
obj1.name = "david"
obj1.age = 20
print("Obj1 -> name: {0} age: {1}".format(obj1.name, obj1.age))
#異常
#obj1.name = 10
obj2 = NameAge2("alex", 11)
print("Obj2 -> name: {0} age: {1}".format(obj2.name, obj2.age))
obj2.name = "bob"
obj2.age = 13
print("Obj2 -> name: {0} age: {1}".format(obj2.name, obj2.age))
#異常
#obj2.age = 'tila'
if __name__ == "__main__":
main()
運行結果:
Obj1 -> name: alice age: 10
Obj1 -> name: david age: 20
Obj2 -> name: alex age: 11
Obj2 -> name: bob age: 13