面向对象常用魔法方法集合

python-讲 2020-11-09 13:37:51
面向对象 对象 面向 常用 魔法


最近发现同学们的问题保持了一致,都是在问我一些魔法方法的使用及意义,所以在这里也是专门给大家整理一份魔法方法的详解及使用集合。

众所周知,方法是需要调用执行的,而魔法方法则不一样,他无需你的调用,在特定的时候会自己执行。

__init__方法

__init__方法是类在创建实例的那一瞬间,就会默认调用的方法,而定义在这个方法里的属性,我们称它为初始化属性,多说无益,我们直接上代码。

class Person(object):
    def __init__(self):
        print('大家好,我是渣渣辉')
p1 = Person()
···
执行结果:
大家好,我是渣渣辉

__new__方法

大家刚才看到了这个__init__方法的效果,肯定都会认为这个方法是类中第一个执行的方法,其实并不然,我们的类最开始调用的是__new__方法,它的第一参数是它的类对象,其他的参数则是传递给__init__方法的,,_new__方法可以调用其他的类的方法或者返回别的实例来作为当前类的实例,所以如果__new__方法没有返回实例,那么__init__方法就不会被调用,所以__new__方法决定了__init__方法是否使用,也可以说实例就是__new__方法创建的。__new__方法的主要用途是当你继承了一些不可更改的属性的时候,给你提供一个途径去修改它。

class Person(int):
    def __new__(cls, value):
        return super(Person, cls).__new__(cls, abs(value))
p1 = Person(-1)
print('p1 = ', p1)
执行结果:
p1 =  1

__str__方法

__str__方法是用来显示信息的,通常是用来返回一个字符串,作为这个实例对象的描述信息,它只有一个参数,需要return一个数据,当你在类的外部打印实例对象的时候则会打印这个数据,在使用print(对象)或者str(对象)的时候会触发此方法。

class Person(object):
    def __init__(self):
        self.name = '渣渣辉'
        self.age = 18
    def __str__(self):
        return '我是%s,今年%s,快来砍我' % (self.name, self.age)
p1 = Person()
print(p1)
执行结果:
我是渣渣辉,今年18,快来砍我

在使用print()函数输出对象名称的时候默认的情况会打印对象名引用的内存地址,如果想要打印对象的属性值,可以使用__str__(self)这个方法。

__call__方法

__call__方法可以是类的实例对象能像调用函数那样使用对象。它的作用是简化了对象下方法的使用,模糊了对象和函数调用时的区别。

使用__call__前
class Person(object):
    def demo(self):
        print('p1')
p1 = Person()
p1.demo()
执行结果:
p1
使用__call__后
class Person(object):
    def __call__(self):
        print('p1')
p1 = Person()
p1()
执行结果:
p1

使用__call__方法实现斐波那契数列

class Fibonacci(object):
    def __call__(self, num):
        a, b = 1, 1
        self.lst = []
        if num <= 2:
            self.lst.append(a)
            self.lst.append(b)
        else:
            for i in range(1, num + 1):
                self.lst.append(a)
                a, b = b, a + b
        return self.lst
fibo = Fibonacci()
ret = fibo(10)
print(ret)
执行结果:
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

__dir__方法

熟悉python的人都知道dir()方法可以让我们查看当前环境下有些什么样的方法和属性可以使用,通过dir(object)可以获得一个对象拥有的方法和属性,同样的道理,如果我们自己在类中定义了这个__dir__方法,我们就可以指定一些别人能够被调用的方法,你的协同开发者就可以通过调用dir()方法查看到并使用。

class Person(object):
    def __init__(self):
        self.name = '渣渣辉'
        self.age = 18
        self.gender = '男'
        
    def chuanqi(self):
        print('快来和我一起砍传奇')
        
p1 = Person()
print(dir(p1))
执行结果:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'chuanqi', 'gender', 'name']

__del__方法

在一个实例被销毁时,__del__方法会执行,该方法是解释器自动调用的,一般不需要重写。

class Person(object):
    def __del__(self):
        print("销毁")
        print("自动调用del")
p1 = Person()
执行结果:
销毁
自动调用del

__getattr__方法

当我们访问一个不存在的属性时会调用次方法,如果属性存在则不调用。

如果我们不重写__getattr__方法,当我们访问一个不存在的属性时会抛出AtrributeError的错误。

class Person(object):
    def __init__(self,name):
        self.name = name
    def __getattr__(self, item):
        print("不存在的属性")
        return item
p1 = Person("渣渣辉")
print(p1.name)
print(p1.age)#age属性不存在
执行结果:
渣渣辉
不存在的属性
age

__setattr__方法

所有的属性设置都会调用此方法,并且只有拥有这个魔法方法的对象才可以设置属性,使用这个方法要注意的是不要被循环调用。

class Person(object):
    def __init__(self, name):
        self.name = name
    def __setattr__(self, name, value):
        print("执行__setattr__")
        object.__setattr__(self, name, value)
p1 = Person("渣渣辉")
print(p1.name)
执行结果:
执行__setattr__
渣渣辉

__dict__方法

__dict__方法可以被认为是一个管理系统,它管理着类中存储的各种属性,当我们创建类属性或者实例属性的时候,就会将这些信息保存到__dict__魔法方法内部,我们使用的时候再从它内部取出来。当我们用实例对象点上__dict__的方法时,就可以读取到当前实例对象的属性。

class Person(object):
    def __init__(self):
        self.name = '渣渣辉'
        self.age = 18
        self.gender = '男'
p1 = Person()
print(p1.__dict__)
执行结果:
{'name': '渣渣辉', 'age': 18, 'gender': '男'}

__eq__方法

在做对象比较的时候,我们实际上调用的方法就是__eq__方法,默认比较的是内存地址,如果要改变比较方式,可以重写__eq__方法。

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __eq__(self, other):
        return self.__dict__ == other.__dict__
per1 = Person('lee', 10)
per2 = Person('lee', 10)
print(per1 == per2)
print(per1 is per2)
执行结果:
True
False

这些就是我们经常可能用到的魔法方法,希望大家能够有所得,记得献上你们的小红心哦!!!

版权声明
本文为[python-讲]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000037770940

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云