python语法基础学习笔记Task11:魔法方法

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值