Python 类的创建和属性设置
简要说明
一、代码块一是因嫌创建类时属性太多占用太多行,所以想到了用字典来设置;
二、代码块二是因担心在实例化后更新对象属性时写错属性名,所以在代码块一的基础上重写了类的 __setattr__
方法,以阻止设置对象不存在的属性时抛出异常;
比较发现:
1、代码块一的运行结果一、二都符合预期,但不能阻止错误设置对象的属性;
2、代码块二的运行结果一符合预期,也满足了阻止错误设置对象的属性的要求;
3、从代码块二的运行结果二发现,似乎初始化中的赋值设置属性(self.gou = 9
)是依赖 __setattr__
方法实现的,因此导致设置失败。
代码块一
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Test.py
#
class Temp():
def __init__(self, dic):
self.__dict__.update(dic)
# ~ self.gou = 9
def main(args):
aaaa = {'a': 1, 'b': 2}
test = Temp(aaaa)
print(test.__dict__)
test.b = 3
print(test.__dict__)
test.c = 5
print(test.__dict__)
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
运行结果一
{'a': 1, 'b': 2}
{'a': 1, 'b': 3}
{'a': 1, 'b': 3, 'c': 5}
------------------
(program exited with code: 0)
请按任意键继续. . .
运行结果二(取消第 9 行注释后)
{'a': 1, 'b': 2, 'gou': 9}
{'a': 1, 'b': 3, 'gou': 9}
{'a': 1, 'b': 3, 'gou': 9, 'c': 5}
------------------
(program exited with code: 0)
请按任意键继续. . .
代码块二
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Test.py
#
class Temp():
def __init__(self, dic):
self.__dict__.update(dic)
# ~ self.gou = 9
def __setattr__(self, key, value):
if key in self.__dict__:
self.__dict__[key] = value
else:
message = "'%s' object has no attribute '%s'"
raise AttributeError(message % (self.__class__.__name__, key))
def main(args):
aaaa = {'a': 1, 'b': 2}
test = Temp(aaaa)
print(test.__dict__)
test.b = 3
print(test.__dict__)
test.c = 5
print(test.__dict__)
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
运行结果一
{'a': 1, 'b': 2}
{'a': 1, 'b': 3}
Traceback (most recent call last):
File "Test.py", line 33, in <module>
sys.exit(main(sys.argv))
File "Test.py", line 26, in main
test.c = 5
File "Test.py", line 16, in __setattr__
raise AttributeError(message % (self.__class__.__name__, key))
AttributeError: 'Temp' object has no attribute 'c'
------------------
(program exited with code: 1)
请按任意键继续. . .
运行结果二(取消第 9 行注释后)
Traceback (most recent call last):
File "Test.py", line 33, in <module>
sys.exit(main(sys.argv))
File "Test.py", line 20, in main
test = Temp(aaaa)
File "Test.py", line 9, in __init__
self.gou = 9
File "Test.py", line 16, in __setattr__
raise AttributeError(message % (self.__class__.__name__, key))
AttributeError: 'Temp' object has no attribute 'gou'
------------------
(program exited with code: 1)
请按任意键继续. . .
思考
只要不在初始化时通过逐一赋值设置类的属性,代码块二已经达到了目标,但如果非要逐一赋值呢,又该采用什么方法来阻止实例化后误设对象属性呢?