之前也有讲到过,Python 没有真正意义上的私有属性。然后这就导致了对 Python 类的封装性比较差。我们有时候会希望 Python 能够定义私有属性,然后提供公共可访问的 get 方法和 set 方法。Python 其实可以通过魔术方法来实现封装。
通过上面的方法表可以知道,在进行属性访问控制定义的时候你可能会很容易的引起一个错误,可以看看下面的示例:
def __setattr__(self, name, value):
self.name = value
# 每当属性被赋值的时候, ``__setattr__()`` 会被调用,这样就造成了递归调用。
# 这意味这会调用 ``self.__setattr__('name', value)`` ,每次方法会调用自己。这样会造成程序崩溃。
def __setattr__(self, name, value):
# 给类中的属性名分配值
self.__dict__[name] = value
# 定制特有属性上面方法的调用具体示例如下:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
class User(object):
def __getattr__(self, name):
print('调用了 __getattr__ 方法')
return super(User, self).__getattr__(name)
def __setattr__(self, name, value):
print('调用了 __setattr__ 方法')
return super(User, self).__setattr__(name, value)
def __delattr__(self, name):
print('调用了 __delattr__ 方法')
return super(User, self).__delattr__(name)
def __getattribute__(self, name):
print('调用了 __getattribute__ 方法')
return super(User, self).__getattribute__(name)
if __name__ == '__main__':
user = User()
# 设置属性值,会调用 __setattr__
user.attr1 = True
# 属性存在,只有__getattribute__调用
user.attr1
try:
# 属性不存在, 先调用__getattribute__, 后调用__getattr__
user.attr2
except AttributeError:
pass
# __delattr__调用
del user.attr1输出的结果:
调用了 __setattr__ 方法
调用了 __getattribute__ 方法
调用了 __getattribute__ 方法
调用了 __getattr__ 方法
调用了 __delattr__ 方法