python语法基础学习笔记Task11:魔法方法
程序员文章站
2024-03-15 22:56:24
...
1、python的魔法方法
魔法方法是指Python内部已经包含的,被双下划线所包围的方法,这些方法在进行特定的操作时会自动被调用,它们是Python面向对象下智慧的结晶
2、关于属性的魔法方法
- __ getattribute __(self, name)----定义了属性被访问时的行为,而__getattr__只有该属性不存在时才会起作用,因此,在支持__getattribute__的Python版本,调用__getattr__前必定会调用 __ getattribute __,调用时应注意避免"无限递归"的错误。
- __ getattr __(self, name)----该方法定义了你试图访问一个不存在的属性时的行为。因此,重载该方法可以实现捕获错误拼写然后进行重定向, 或者对一些废弃的属性进行警告。
- __ setattr __(self, name, value)----是实现封装的解决方案,它定义了你对属性进行赋值和修改操作时的行为。不管对象的某个属性是否存在,它都允许你为该属性进行赋值,因此你可以为属性的值进行自定义操作,但是要注意避免"无限递归"的错误。
- __ delattr __(self, name)----定义的是删除属性时的行为,调用时注意避免"无限递归"的错误。
classAccess(object):
def__getattr__(self, name):
print '__getattr__'
return super(Access, self).__getattr__(name)
def__setattr__(self, name, value):
print '__setattr__'
return super(Access, self).__setattr__(name, value)
def__delattr__(self, name):
print '__delattr__'
return super(Access, self).__delattr__(name)
def__getattribute__(self, name):
print '__getattribute__'
return super(Access, self).__getattribute__(name)
access = Access()
access.attr1 = True # __setattr__调用
access.attr1 # 属性存在,只有__getattribute__调用
try:
access.attr2 # 属性不存在, 先调用__getattribute__, 后调用__getattr__
except AttributeError:
pass
del access.attr1 # __delattr__调用
- 无限递归错误
# 以上例子都是,每一次属性赋值时, 方法都会被调用,因此不断调用自身导致无限递归了
def __setattr__(self, name, value):
self.name = value
def __getattribute__(self, item):
print('__getattribute__')
return self.item
def __getattribute__(self, name):
return self.__dict__[name]
# 正确的写法
def __setattr__(self, name, value):
self.__dict__[name] = value
def __getattribute__(self, item):
print('__getattribute__')
return super().__getattribute__(self, item)
3、实例对象属性寻找的顺序
- 首先访问 __ getattribute __() 魔法方法(隐含默认调用,无论何种情况,均会调用此方法)。
- 接着,去t.__dict__中查找是否具备该属性。
- 若在 t.__ dict __ 中找不到对应的属性, 则去t.__ class __.__dict__中寻找。
- 若在实例的类中也找不到该属性,则去父类中寻找,即 t.__ class . bases __.__dict__中寻找。
- 若以上均无法找到,则会调用 __ getattr __ 方法,执行内部的命令(若未重载 __ getattr __ 方法,则直接报错:AttributeError)
class Test:
def __getattr__(self, item):
print('__getattr__')
def __getattribute__(self, item):
print('__getattribute__')
#super().__getattribute__(item)
#object.__getattribute__(self,item)
def __setattr__(self, item, value):
print('__setattr__')
def __delattr__(self, item):
print('__delattr__')
t = Test()
t.x
#__getarrtribute__
以上这个程序在访问一个不存在的属性的时候并没有调用__ getattr __ ,而只是调用了__ getatrrribute __ 。这个的问题就出在了步骤的第④步,因为,一旦重载了 __ getattribute __ () 方法,如果找不到属性,则必须要手动加入第④步,否则是无法进入到 第⑤步 (__ getattr __)的。
- 方法一:采用 object(所有类的基类)
class Test:#父类
def __getattr__(self, item):
print('__getattr__')
def __getattribute__(self, item):
print('__getattribute__')
#super().__getattribute__(item)
object.__getattribute__(self,item)
def __setattr__(self, item, value):
print('__setattr__')
def __delattr__(self, item):
print('__delattr__')
t = Test()
t.x
#__getattribute__
#__getattr__
- 方法二:采用 super() 方法
class Test:#父类
def __getattr__(self, item):
print('__getattr__')
def __getattribute__(self, item):
print('__getattribute__')
super().__getattribute__(item)
#object.__getattribute__(self,item)
def __setattr__(self, item, value):
print('__setattr__')
def __delattr__(self, item):
print('__delattr__')
t = Test()
t.x
#__getattribute__
#__getattr__
4、一些基础魔法方法
5、属性相关的方法
6、比较操作符
7、算数运算符
参考文献
- https://blog.csdn.net/LSGO_MYP/article/details/102573292
- https://blog.csdn.net/qq_38520096/article/details/79237593
- https://www.cnblogs.com/zhouyixian/p/11129347.html
- https://www.cnblogs.com/blackmatrix/p/5681480.html