前言

前面我们总结过了python的关键字、运算符、内置函数、语法糖等与python魔法方法之间的关系,现在我们更细一点,看看python的面向对象编程有哪些常用的魔法属性和魔法方法。

魔法属性

对于一个类,python定义了许多可用的魔法属性,有些每个类都默认存在,有些需要用户手动定义。

__dict__

__dict__属性可以说是一个类最常用的属性之一了,它又分为类的__dict__属性和实例的__dict__属性。

class Person(object):
eye = 2
hand = 2
def __init__(self, name):
self.name = name def run(self):
print('run') @classmethod
def eat(cls):
print('eat') if __name__ == "__main__":
person = Person('cai')
print(Person.__dict__)
print(person.__dict__)
  1. 类的__dict__属性存储了类定义的所有类属性、类方法等组成的键值对,但不包括继承而来的属性和方法

  2. 实例的__dict__属性存储了所有的实例属性的键值对,如果没有就为空;__init__方法其实就是对__dict__属性的初始化赋值;

__doc__

该属性记录了类的说明文档,用类和实例引用指向的都是类的__doc__属性,如果没有默认为None。

class Person(object):
"""person"""
pass per = Person()
print(per.__doc__) # person

__module__

该属性记录类定义的位置,如果定义的位置正好是主程序,那么该值为"_main_",否则是类属于的模块的名字;

class Person(object):
"""person"""
pass per = Person()
print(per.__module__) # __main__

__class__

该属性指向该实例的类,即实例指向类对象,类对象指向元类;

class Person(object):
"""person"""
pass per = Person()
print(per.__class__) # <class '__main__.Person'>
print(per.__class__()) # 创建了一个新的实例
print(Person.__class__) # <class 'type'> # 在一个类的内部直接使用__class__指代类本身。

__slots__

该属性起到限制动态绑定属性和方法的作用,该属性是一个元组,默认是不存在的,需要手动定义并且只对当前的类起作用,只有添加到元组中的名字才能被动态添加属性,否则报错!

class Person(object):
__slots__ = ('name','age','run') def __init__(self):
self.height = 100 # 报错 def run(self):
print('run') if __name__ == "__main__":
from types import MethodType
person = Person()
person.name = 'cai'
person.run = MethodType(run,person)
person.run()
  1. __slots__属性定义好后,限制了一个类的实例的属性以及可以动态添加的属性和方法;

  2. __slots__属性定义好后,不得在类中定义元组中已有的同名的方法;

魔法方法

__new__

该方法是类创建实例调用的第一个方法,返回一个实例;这是一个实例从无到有必须调用的方法,在单例模式中常用,其他不常用。

class Person(object):
def __new__(cls, *args, **kwargs):
print(args)
return object.__new__(cls) if __name__ == "__main__":
person = Person('cai')

创建实例时会将参数传入new方法,但new方法中无法更改参数。

__init__

该方法可以说是类最常用的方法了,python在调用new方法后会紧接着调用init方法,我们将实例的一些初始化操作放在该方法中,即对__dict__属性进行操作;

class Person(object):

    def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
print(key,value)
super().__setattr__(key,value)
if __name__ == "__main__":
person = Person('cai')
print(person.__dict__) # {'name': 'cai'}
  • 所有的“self.name = name”这种语法糖,python会先调用setattr魔法方法,该魔法方法对__dict__属性中添加键值对;

  • self一定是__new__方法的返回值,如果返回的是1,那么self就是1.

__del__

该方法在实例对象引用计数变为0或del关键字调用的时候触发执行。

__repr__

该方法在print()调用或repr()调用时执行,用来定义对类的信息的描述,每个类都应该定义这个方法。

总结

  1. 类的常用魔法属性有__dict__,__doc__,__mould__,__slots__,其中slots属性需要自定义,其他属性默认存在;

  2. 构造类常用init,new,del方法,它们在类创造、初始化、销毁时触发;

参考

python进阶之类常用魔法方法和魔法属性的更多相关文章

  1. python进阶06 常用问题库(2)datetime模块 base64

    python进阶06 常用问题库(2)datetime模块 base64 一.datetime模块(时间) 1.datetime.time() t=datetime.time(20,43,30,1) ...

  2. Python进阶学习之特殊方法实例详析

    Python进阶学习之特殊方法实例详析 最近在学习python,学习到了一个之前没接触过的--特殊方法. 什么是特殊方法?当我们在设计一个类的时候,python中有一个用于初始化的方法$__init_ ...

  3. python_魔法方法(四):属性访问

    通常可以通过点(.)操作符的形式去访问对象的属性,也可以通过BIF适当地去访问属性,看个例子吧 >>> class A(): def __init__(self): self.x = ...

  4. python进阶05 常用问题库(1)json os os.path模块

    python进阶05 常用问题库(1)json os os.path模块 一.json模块(数据交互) web开发和爬虫开发都离不开数据交互,web开发是做网站后台的,要跟网站前端进行数据交互 1.什 ...

  5. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  6. python进阶之关键字和运算符触发魔法方法

    前言 python有众多的魔法方法,它们会在满足某种条件下触发执行,掌握好魔法方法的使用,可以加快程序的运行效率,同时减少逻辑调用. 关键字与魔法方法 python的一些魔法方法是关键字触发的,即py ...

  7. Python学习之==>常用字符串方法

    1.常用字符串方法 a = '\n 字 符 串 \n\n' b = a.strip() # 默认去掉字符串两边的空格和换行符 c = a.lstrip() # 默认去掉字符串左边的空格和换行符 d = ...

  8. Python学习day07 - Python进阶(1) 内置方法

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  9. Windows下python库的常用安装方法

    目录:       1.pip安装(需要pip)       2.通过下载whl文件安装(需要pip)       3.在pythn官网下载安装包安装(不需要pip)   方法一:pip安装. 这是最 ...

随机推荐

  1. SD/MMC相关寄存器的介绍

    1.SD卡内部架构 在熟悉SD/MMC相关寄存器之前,我们先来看看SD卡的内部架构是怎么样的,如下图所示: 2.SD/MMC相关寄存器的介绍 从上图中总结出:SD卡内部有7个寄存器. 一.OCR,CI ...

  2. [cdqzds] Challenge4

    描述 给一个长为N的数列,有M次操作,每次操作时以下三种之一: (1)修改数列中的一个数 (2)求数列中某连续一段所有数的两两乘积的和 mod 1000000007 (3)求数列中某连续一段所有相邻两 ...

  3. 删除XML文件中的空格

    应要求需要删除xml文件中的空格,制表符等字符.要求双引号和xml的text属性中包含的空格不删除. bool delSpace(QFile &file, QString path) //删除 ...

  4. 如何将SLIC集成到ESXi中

    如何将SLIC集成到ESXi中 参考 http://forums.mydigitallife.info/threads/12982-ESX-ESXi-Bios-Tools/page34?p=72183 ...

  5. oracle 月份中日的值必须介于 1 和当月最后一日之间

    解决方法: 1.用时间字段去关联字符串字段导致此错误.. 如果1.解决不了就看 2.把date'2017-01-01'  换成 to_date('2017-01-01','yyyy-mm-dd')

  6. Subsets II - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Subsets II - LeetCode 注意点 有重复的数字 数组可能是无序的,要先排序 解法 解法一:递归,只需要在Subsets中递归写法的基础上 ...

  7. 我的shell脚本

    问题:在ip.lt文件中有600个IP,有3个文档模版,三个文档的名称结构都是“ip+一系列字符串”,要求:1.将600个IP分成3分,以三个模版为基础创建600个文档,名字结构与模版相同:2修改60 ...

  8. CF1009F Dominant Indices 解题报告

    CF1009F Dominant Indices 题意简述 给出一颗以\(1\)为跟的有根树,定义\(d_{i,j}\)为以\(i\)为根节点的子树中到\(i\)的距离恰好为\(j\)的点的个数,对每 ...

  9. vmware中centos7设置静态IP

    1.vmware—>Edit—>Virtual Network Editor,选中vmnet8-Nat设置,查看网关IP 2.在centos中设置: vi /etc/sysconfig/n ...

  10. SystemV-IPC

    这里记录的三种SystemV-IPC包括(消息队列,信号量以及共享内存) 1:标识符和键值 键值(key_t) : IPC结构的外部名(所谓外部名就是各用户进程可获得并操作的,通过它使用XXXget获 ...