魔术方法:就是类中的方法(预定义的方法),在某个特定的时机会被自动的调用。
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