【python基础】魔术方法

  魔术方法:就是类中的方法(预定义的方法),在某个特定的时机会被自动的调用。

  1、__del__():销毁对象时,被自动的调用

 1 class Person:
 2     def __init__(self, name):
 3         self.name = name
 4         print(‘%s 被初始化‘ % self.name)
 5
 6     def __del__(self):
 7         print("%s 被删除 " % self.name)
 8
 9
10 p1 = Person("奶茶")
11 p2 = Person("蛋糕")
12
13 print(‘xixi‘)
14 del p1
15 print(‘haha‘)
16
17 # 奶茶 被初始化
18 # 蛋糕 被初始化
19 # xixi
20 # 奶茶 被删除
21 # haha
22 # 蛋糕 被删除

  2、__call__():

    功能:让类的实例具有类似有函数(方法)的功能。让对象可以被调用, 调用时执行的就是__call__中的函数体

    触发时机:调用对象的时候——对象()

 1 class Person:
 2     def __init__(self, name, sex, age, sister=None, brother=None):
 3         self.name = name
 4         self.sex = sex
 5         self.age = age
 6         self.sister = sister
 7         self.brother = brother
 8
 9     def __call__(self):  # 获取....
10         if self.sex == "boy":
11             print(self.sister)
12         else:
13             print(self.brother)
14
15     def get_age(self):
16         print(self.age)
17
18
19 p1 = Person("xixi", "boy", 18, "haha")
20 print(p1.name)  # xixi
21 p1.get_age()  # 18
22 p1()  # haha

  3、__repr__():print(对象) 打印对象时会被调用

    __str__():print(对象) 打印对象时会被调用
   

    print(对象)默认情况下打印结果是,对象的内存地址
    重写__str__()方法,返回什么,print(对象)打印的结果就是什么

    区别与联系:

      1、TypeError:__repr__ returned non-string (type NoneType)
        以上两个函数都必须有返回值,且返回值类型为str类型;

      2、打印对象时, 如果使用%s占位符, 默认调用的是__str__()方法
        如果使用%r占位符, 默认调用的是__repr__()方法

      3、有repr, 没有str时,%s、%r 都可调用repr方法;
         没有repr, 有str时, %s 调用的是str的方法,%r 打印的是对象的地址(默认的)

      4、print(repr(对象)) 默认调用__repr__()方法
         print(str(对象)) 默认调用__str__()方法

 1 class Person:
 2     def __init__(self, name):
 3         self.name = name
 4
 5     def __str__(self):
 6         return "我是str"
 7
 8     def __repr__(self):
 9         return "我是repr"
10
11
12 p1 = Person("xixi")
13 # repr&str方法都没有
14 # print(p1)  # <__main__.Person object at 0x000000000214D198>
15
16 # repr&str方法都有
17 # print("%s" % p1)  # 我是str
18 # print("%r" % p1)  # 我是repr
19
20 # 只有repr方法:
21 # print("%s" % p1)  # 我是repr
22 # print("%r" % p1)  # 我是repr
23
24 # 只有str方法
25 # print("%s" % p1)  # 我是str
26 # print("%r" % p1)  # <__main__.Person object at 0x00000000026BD198>
27
28 print(repr(p1))
29 print(str(p1))

  4、__new__(cls):类方法

    功能:实例化一个对象

    触发时机:当实例化对象的时候,会被自动调用

    返回值:实例化的那个对象;

    __new__(cls)方法将实例化的对象传递给__init__(self)方法的第一个参数;

    __new__()是object类底层的实现——单例

 1 class Person:
 2     def __new__(cls, *args, **kwargs):  # 必须有返回值: 创建好的对象,类的实例
 3         print("我是new")
 4         return super().__new__(cls)
 5
 6     def __init__(self):
 7         print("我是init")
 8
 9
10 p = Person()  # 创建对象
11 # 我是new
12 # 我是init
13 print(p)  # <__main__.Person object at 0x0000000001EA8358>

  5、__eq__:   

    只要俩对象的属性值都相等, 我们就认为这俩对象相等
    通过__eq__()方法去实现,必须有返回值bool用来代表是否相等
    使用__eq__()方法定义比较的规则,对象进行比较时需要使用 == 关系运算符进行比较

    对象.__dict__ 获取当前对象的属性, 包括私有(字典{"属性名": "属性值", ...})

    (1)基础数据类型的对象
      is : 比较的是对象的地址
      == : 比较的是对象的内容

      cmd 对于小整数 [-5, 256] 之间的数字进行了缓存,所以可以在缓存中重复使用
      pycharm做了优化,他把不可变数据类型中的很大范围的数据都做了缓存,所以在缓存中可以重复使用
      在pycharm中对某些即使很大的整数进行地址的比较 is 都是相等的

    (2)自定义类的对象
      is 和 == 比较的都是对象的地址

 1 a = "12345"
 2 b = "12345"
 3
 4 print(a == b)  # True
 5 print(a is b)  # True
 6 print(id(a))  # 4772224
 7 print(id(b))  # 4772224
 8
 9
10 list1 = [1, 2, 3, 4]
11 list2 = [1, 2, 3, 4]
12 print(list1 == list2)  # True
13 print(list1 is list2)  # False
14 print(id(list1))  # 63488968
15 print(id(list2))  # 63184328
16
17
18 class Person:
19     def __init__(self, name, age):
20         self.name = name
21         self.age = age
22
23     def __eq__(self, other):  # other, 另外一个要进行比较的对象
24         if self.__dict__ == other.__dict__:  # 如果当前对象和被比较对象的所有属性值相等, 我们就认为这俩对象相等
25             return True
26         else:
27             return False
28
29
30 p1 = Person(‘xixi‘, 6)
31 p2 = Person(‘xixi‘, 6)
32 print(p1 == p2)  # True
33 print(p1 is p2)  # False
34 print(id(p1))  # 43097840
35 print(id(p2))  # 43101544

  6、__hash__() : 当获取对象的哈希值时,调用该魔术方法

    hash(对象)

    set, list, dict 没有__hash__()方法, hash(列表对象):报错,不可被哈希
    列表对象.__hash__ ——> None

    如果只定义了__eq__()方法, 而没有定义__hash__(), 默认会将__hash__方法设置为None

 1 # 设计二维坐标类Point判断2个坐标是否相等,
 2 # 并能根据hash函数计算坐标的哈希值;
 3
 4 class Point:
 5     def __init__(self, x, y):
 6         self.x = x
 7         self.y = y
 8
 9     def __eq__(self, other):
10         if self.x == other.x and self.y == other.y:
11             return True
12         else:
13             return False
14
15     def __hash__(self):
16         return hash((self.x, self.y))
17
18 point1 = Point(3, 4)
19 point2 = Point(3, 4)
20
21 print(point1 == point2)  # True
22
23 print(hash(point1))  # 3713083796997400956
24 print(hash(point2))  # 3713083796997400956

原文地址:https://www.cnblogs.com/Tree0108/p/12112896.html

时间: 2024-11-05 20:43:20

【python基础】魔术方法的相关文章

python的魔术方法大全

在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”(魔术方法),例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中有相应描述,这边给大家把所有的魔术方法汇总了起来进行说明,希望对大家的学习有所帮助. python的魔术方法大全 魔法方法 含义 基本的魔法方法 __new__(cls[, ...]) 1. __new__ 是在一个对象实例化的时候所调用的第一个方法 __init__(self[, ...]) 构造器,当一个实例

python常用魔术方法概览

构造和初始化 __init__(self, args) 构造函数 __new__(cls) 传入的是类实例 __del__(self) 析构函数,调用 del cls 时会被调用 属性访问控制 __getattr__(self, name) 如果属性已经定义了那么不会再执行__getattr__()了,而是直接通过访问实例字典返回结果,__getattr__()只在访问未定义的属性时被触发 __setattr__(self, name, value) 直接给属性赋值 cls.name = val

Python的魔术方法总结

魔术方法:再不需要程序员定义,本身就存在类中的方法就是魔术方法. 魔术方法通常都长这样:__名字__. 1.__str__和__repr__ 为了方便记忆看如下列子 class Course: def __init__(self,name,period,price,teacher): self.name= name self.period = period self.price = price self.teacher = teacher def __str__(self): return 's

python面向对象魔术方法补充

一.描述符 在 面向对象 编程中 定义一个(没有定义方法)类:class person , 在这个类里面,有name,age, heigth, weight,等等属性, 这个类就可以看作一个对 person 的描述符,而具体的实例则是具体的“被描述物”. 而在python中,描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议. __get__():调用一个属性时,触发 __set__():为一个属性赋

Python基础之方法

class woman:    passwangdama=woman()lidama=woman()#查看实例的属性#print wangdama.__dict__'''{}''' #为实例添加属性wangdama.toufa='yellow'#print wangdama.__dict__ '''{'toufa': 'yellow'}'''#查看实例所属类的属性print wangdama.__class__.__dict__#实例所属类添加属性wangdama.__class__.xiezi

python基础--列表方法

列表: 中括号括起来 ,  分割每一个元素 列表中的元素可以是任意元素,甚至列表 方法: 1.取值 li = [4,3,1,["as",[3,4]]] print(li[3][1]) 2.列表转化为字符串 只有字符串的,直接使用join函数 对于既有数字又有字符串的:需要写一个for循环一个一个处理: li = ['a',11,45,'bug'] s = "" for i in li: s = s +str(i) print(s) 3.append(),在原来值后面

Python 类的魔术方法

Python中类的魔术方法 在Python中以两个下划线开头的方法,__init__.__str__.__doc__.__new__等,被称为"魔术方法"(Magic methods).魔术方法在类或对象的某些事件出发后会自动执行,如果希望根据自己的程序定制自己特殊功能的类,那么就需要对这些方法进行重写. 注意:Python 将所有以 __(两个下划线)开头的类方法保留为魔术方法.所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀. Python提供的魔术方法 魔术方法这里

[学习记录]python魔术方法与抽象方法like型反思

之前一直没搞懂python的魔术方法是怎么回事,今天看到一篇讲的很好的文章,这里先把链接贴出来 总的来说魔术方法就是定义成用两条下划线包围方法名前后的一种方法,例如__init__,__del__等等 换句话说,当你在python中使用dir()时,看到的那么一大堆__方法__都是魔术方法,如下图 test类只定义了一个hello方法,但是dir展示了大量的魔术方法.这些魔术方法都是内置的,但是允许我们对它们进行重写. 对比一下会感觉有点像定义的接口类的抽象方法,定义出来作为模板,然后由子类对其

python中单例模式的实现-通过闭包函数和魔术方法__new__实现单例模式

1.通过闭包函数实现单例模式: # 使用闭包函数实现单例 def single(cls, *args, **kwargs): instance = {} def get_instance(): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls] return get_instance @single class Apple: pass a = Apple() b = Apple() p