属性的魔法方法

__getattribute__(self,name):当该类的属性被访问时,自动触发,是最先被触发的属性方法

__setattr__(self,name,value):当一个属性被设置时,自动触发

__delattr__(self,name):当一个属性被删除时,自动触发

>>>class C:
  def __getattribute__(self,name):
    print('getattribute')
  def __getattr__(self,name):
    print('getattr')
  def __setattr__(self,name,value):
    print('setattr')
  def __delattr__(self,name):
    print('delattr')
>>>c = C()
>>>c.x
getarrribute

此处没有调用并打印getattr的原因,要从实例对象属性的访问顺序说起:

首先调用getattribute -> 然后在实例对象中查找 -> 继续在实例的类中查找 -> 最后在父类中查找 -> 均无法找到时调用getattr方法

是要当所有流程都走完,都没找到该属性,才会调用getattr方法,但由于重写了getattribute方法,所以需要用super()函数来调用父类

>>>class C:
  def __getattribute__(self,name):
    print('getattribute')
    super().__getattribute__(name)
  def __getattr__(self,name):
    print('getattr')
  def __setattr__(self,name,value):
    print('setattr')
  def __delattr__(self,name):
    print('delattr')
>>>c = C()
>>>c.x
getarrribute
getattr
>>>c.x = 1
setattr
>>>c.x
getarrribute
1
>>>del c.x
delattr

__getattr__(self,name):当访问一个不存在的属性时,自动触发,默认返回值为None

正常情况下,当我们调用类的属性时,如果不存在这个属性会报错

但如果我们在类中重写了__getattr__方法,当用户访问不存在的类的属性时,python会自动调用__getattr__来获得在类中重写的属性或异常

>>>class Rectangle:
  def __init__(self,height=5):
    self.height = height
  def __getattr__(self,name):
    if name == 'width':
      width = 10
      return width
    raise AttributeError('This attribute does not exist')
>>>r = Rectangle()
>>>r.height #调用类中存在的属性,不会触发__getattr__方法
5
>>>r.width #调用类中不存在的属性,触发__getattr__方法并获得属性
10
>>>r.name #调用类中不存在的属性,触发__getattr__方法并抛出异常
AttributeError: This attribute does not exist

这里要注意一个容易产生死循环的问题,比如例子:

>>>class Rectangle:
  def __init__(self,widt = 0,height = 0):
    self.width = width #此处有给属性赋值的操作,所以会自动触发__setattr__
    self.height = height
  def __setattr__(self,name,value):
    if name == 'square':
      self.width = value
      self.height = value
    else:
      self.name = value #而在__setattr__方法中又存在赋值操作,所以产生无限递归
  def getArea(self):
    return self.width * self.height
修改方法:将else分支的语句改为super().__setattr__(name,value),此处直接调用父类的方法,免去赋值操作,就不会再产生递归
>>>r1 = Rectangle(4,5)
>>>r1.getArea()
20
>>>r1.square = 10
>>>r1.__dict__ #以列表的形式显示该对象的所有属性
{'width': 10, 'height': 10}
>>> r1.getArea()
100

Python笔记(二十六)_魔法方法_属性的魔法方法的更多相关文章

  1. python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码

    python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...

  2. 使用Typescript重构axios(二十六)——添加HTTP授权auth属性

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  3. Python笔记(二十四)_魔法方法_运算符的魔法方法

    算数运算方法 .反运算方法 以对象A+对象B为例,都是将A作为self值,而B作为other值传入__add__(self,other)方法: 当用户输入A+B,就会调用重写的add方法: >& ...

  4. [Python笔记]第十六篇:web框架之Tornado

    Tornado是一个基于python的web框架,xxxxx 安装 python -m pip install tornado 第一个Tornado程序 安装完毕我们就可以新建一个app.py文件,放 ...

  5. Java基础学习笔记二十六 JDBC

    什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库,J ...

  6. angular学习笔记(二十八-附1)-$resource中的资源的方法

    通过$resource获取到的资源,或者是通过$resource实例化的资源,资源本身就拥有了一些方法,$save,$delete,$remove,可以直接调用来保存该资源: 比如有一个$resour ...

  7. Python笔记(二十八)_魔法方法_迭代器

    迭代器用于遍历容器中的数据,但它不是容器,它是一个实现了__next__方法的对象 与迭代器相关的内置函数: iter(): 将一个对象转换成一个迭代器 next(): 访问迭代器中的下一个变量,直到 ...

  8. Python笔记(二十二)_魔法方法_基本魔法方法

    __init__(self[,...]) __init__和__new__组成python的构造器,但__init__更多的是负责初始化操作,相当于一个项目中的配置文件,__new__才是真正的构造函 ...

  9. Python笔记(二十五)_魔法方法_描述符

    描述符的属性方法 __get__(self, instance, owner): 用于访问属性,返回属性的值 __set__(self, instance, value): 用于给属性赋值时,返回属性 ...

随机推荐

  1. PAT Basic 1010 一元多项式求导 (25 分)(活用stringstream,昨天学习的)

    设计函数求一元多项式的导数.(注:x​n​​(n为整数)的一阶导数为nx​n−1​​.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 1000 的整数).数字间以空格分隔. ...

  2. GUI学习之十八——QDateTimeEdit学习总结

    在前面两章我们总结了QSpinBox和QDoubleSpinBox的用法,今天来总结一下QDateTimeEdit控件的基本用法 一.描述 1.QDateTimeEdit是一个用来编辑日期和时间的单行 ...

  3. 缓存算法LRU笔记

      LRU原理与分析 LRU是Least Recently Used 的缩写,翻译过来就是“最近最少使用”,也就是说,LRU缓存把最近最少使用的数据移除,让给最新读取的数据.而往往最常读取的,也是读取 ...

  4. SpringMVC最新教程IDEA版

    1.servlet项目结构与识别 Idea里带个蓝点的文件夹为tomcat吃的网站内容,idea会通过“Web Resource Directory”来标注,会被打成一个war包 这个文件夹里,MET ...

  5. 5433. 【NOIP2017提高A组集训10.28】图

    题目描述 Description 有一个n个点A+B条边的无向连通图,有一变量x,每条边的权值都是一个关于x的简单多项式,其中有A条边的权值是k+x,另外B条边的权值是k-x,如果只保留权值形如k+x ...

  6. C# 基础:DataTable操作、发邮件

    本文出自:https://www.cnblogs.com/2186009311CFF/p/6865909.html DataTable操作 据参数删除为0的列:包括遍历.删除.取值 public st ...

  7. mybatis config 快速生成xml DAO

    0.加jar包 1.a.BAT java -jar E:\GZH\Mybaits\mybatis-generator-core-1.3.2\lib\mybatis-generator-core-1.3 ...

  8. jquery ajax实现文件上传

    test5.html <html> <head> <meta http-equiv="Content-Type" content="text ...

  9. OpenCV Sift源码分析

    /*M/////////////////////////////////////////////////////////////////////////////////////////// IMPOR ...

  10. A* 算法求第 K 短路

    一种具有 \(f(n)=g(n)+h(n)\) 策略的启发式算法能成为 A* 算法的充分条件是: 搜索树上存在着从起始点到终了点的最优路径. 问题域是有限的. 所有结点的子结点的搜索代价值 \(> ...