赞
踩
一、类的type
class A:pass
print(type(A)) #
print(type(object)) #
print(type(type)) #
① 所有的对象的type都是创造这个对象类
② 所有没有指定metaclass的类的type都是type
③ 指定了metaclass,这个类的type就是指定的metaclass的值
④ 类也是被创造出来的,type是创造类的机制,即元类是创造类的机制
所有的对象的type都是创造这个对象类
class A:passa=A()print(type(a) is A) #True
所有没有指定metaclass的类的type都是type
class A():pass
print(type(A)) #
指定了metaclass,这个类的type就是指定的metaclass的值
from abc importABCMetaclass A(metaclass=ABCMeta):pass
print(type(A)) #
类也是被创造出来的,type是创造类的机制,即元类是创造类的机制
print(type(type) is type(object)) #True,type和object的type都是
print(isinstance(type,object)) #True,type和object都属于
print(isinstance(object,type)) #True,type和object都属于
print(issubclass(type,object)) #True,type是object的子类
print(issubclass(object,type)) #False
二、__new__ 构造方法
__new__ :构造方法,类实例化对象第一步创建了一个对象空间,这个对象空间是由__new__来创建的,继承object的__new__方法
__init__:初始化方法
类实例化对象的时候,先执行的 __new__,再执行__init__。
类实例化对象的内存机制:
实例化对象先执行__new__方法,但是类里没有__new__的方法,到父类object中去找到__new__方法并执行,开辟了属于对象的空间,这时才开始执行__init__方法,把self参数传进去才是刚才创造的空间。
整个过程把类比作模板,创造对象比作捏泥像,__new__方法是捏出来泥像,__init__是给泥像装饰。
classA:def __init__(self): #初始化方法
print('执行初始化方法')def __new__(cls, *args, **kwargs): #构造方法
print('执行构造方法')return object.__new__(cls)
a=A()'''执行构造方法
执行初始化方法'''
三、单例模式
关于设计模式:
常用有23种设计模式,源于Java,为了规范java的开发。
python一种是推崇设计模式,另一种是贬低设计模式。
单例模式:一个类无论实例化多少次,都只有一个对象,只开辟一个空间,这种就是单例模式。
单例模式下,创造的对象的属性是最后一个对象的属性,一直再赋值。
classCity:__initialize = 0 #静态属性
def __init__(self,city):
self.city=citydef __new__(cls, *args, **kwargs):if not cls.__initialize:
cls.__initialize = object.__new__(cls) #把对象空间地址赋值静态属性
return cls.__initializegz= City('广州')
sz= City('深圳')print(gz,sz)print(gz.city,sz.city)'''<__main__.City object at 0x0000022B2DCBC6A0> <__main__.City object at 0x0000022B2DCBC6A0>
深圳 深圳'''
四、__del__ 析构方法
① 析构方法是销毁对象时会调用__del__方法,执行del就会触发__del__的方法
② 在删除这个类创建的对象的时候会先触发这个方法,再删除对象,主要是做清理的工作,需要手动归还资源给操作系统,比如:关闭文件,关闭网络的连接,关闭数据库的连接等。
③ 无论是手动删除对象还是程序结束自动删除对象,本质上都是执行del 对象,只要调用del 对象,就会触发__del__方法
④ 构造方法和析构方法是一对的
classA:def __init__(self,name): #初始化方法
self.name =nameprint(self.name)print('执行初始化方法1')def __new__(cls, *args, **kwargs): #构造方法
print('执行构造方法!')return object.__new__(cls)def __del__(self): #析构方法
print('执行析构方法!')
a= A('苹果')print('-----分割线-----')'''执行构造方法!
苹果
执行初始化方法1
-----分割线-----
执行析构方法!'''
总结:初始化对象先执行__new__方法,再执行__init__方法,然后把self传进去,执行__init__的内容,当整个程序执行完自动删除对象,触发了__del__方法,执行__del__方法的内容。
五、__len__ 方法
① 所有使用len()的数据类型都有__len__的方法,使用len()的数据类型:str,list,dict,tuple,set
② 只要在类中定义__len__方法,并且方法内return整数,就能使用len(对象)
③ 若要统计对象的长度,定义__len__的方法比较好
classFruits:def __init__(self,name):
self.name=name
self.fruit_lis=[]def __len__(self):returnlen(self.fruit_lis)
durian= Fruits('榴莲')
durian.fruit_lis.append('苹果')
durian.fruit_lis.append('番茄')
durian.fruit_lis.append('西瓜')
durian.fruit_lis.append('雪梨')
durian.fruit_lis.append('香蕉')
ret=len(durian)print(ret) #5
六、__eq__ 方法
① __eq__方法判断对象是否相等,但是object类的__eq__方法是通过对象的内存地址判断是否相等
② __eq__方法 有时会配合__hash__方法使用,判断对象里的对象属性是否相等
③ obj.__eq__(obj2) 相当于 obj == obj2
classCity:def __init__(self,city):
self.city=citydef __eq__(self, other):return self.__dict__ == other.__dict__c1= City('广州')
c2= City('广州')print(c1.__eq__(c2)) #调用类的__eq__方法
print(c1 == c2) #调用类的__eq__方法
print(c1,c2) #对象空间的地址
'''True
True
<__main__.C
七、__hash__ 方法
默认的__hash__()继承自对象本身,返回一个基于对象的内部ID值。
相同的hash值:这意味着两个对象可能是相等的。该hash值为我们提供了一个快速检查对象相等的可能性。如果hash值是不同的,两个对象不可能是相等的,他们也不可能是相同的对象。至关重要的是,内部ID和默认__hash__()方法间有一种强联系。
等号比较:这意味着hash值也一定相等。这是==操作符的定义。对象可能是相同的对象。
相同的IDD:这意味着他们是同一个对象。进行了等号比较且有相同的hash值。这是is操作符的定义。
然而,反过来是不正确的。对象可以有相同的hash值但比较是不相等的。在创建集合或字典时导致一些预计的处理开销是正当的。我们不能确切的从更大的数据结构创建不同的64位hash值。将有不相等的对象被简化为一致相等的hash值。
特点:
① 每次执行的哈希值都会变化
② 在一次执行哈希的过程中,对同一个值的hash结果总是不变的
字典寻址快的原因是运用了哈希算法,比二分查找快。
字典在内存中的存储方式:
每存储在内存的数据都有一个内存地址,字典会对键key进行哈希hash(key),把值放在hash的对应地址,所以字典的键是可哈希的
hash算法的特点:
① 对于相同的值在一次程序的运行中是不会变化的
② 对于不同的值在一次程序的运行中总是不同的
set的去重机制:
① 对每一个元素进行hash,计算出一个内存地址
② 到这个内存地址上查看,如果这块内存中没有值,将这个元素存到对应的内存地址上
③ 到这个内存地址上查看,如果这块内存中有值,判断这两个值是否相等。如果相等就舍弃后面的值,如果不相等就二次寻址,再找一个新的空间来存储这个值
自定义__hash__和__eq__方法
classFruits:def __init__(self,name):
self.name=namedef __hash__(self):returnhash(self.name)def __eq__(self, other):return self.__dict__ == other.__dict__fruits_lis= ['apple','orange','banana']
obj_lis=[]for i in range(9):
name= Fruits(fruits_lis[i%3])
obj_lis.append(name)print(obj_lis)print('-'*100)
ret=set(obj_lis)print(ret)'''[<__main__.Fruits object at 0x000001A5EF92C6D8>, <__main__.Fruits object at 0x000001A5EF9373C8>, <__main__.Fruits object at 0x000001A5EF9370F0>, <__main__.Fruits object at 0x000001A5EF937400>, <__main__.Fruits object at 0x000001A5EF937470>, <__main__.Fruits object at 0x000001A5EF937518>, <__main__.Fruits object at 0x000001A5EF937550>, <__main__.Fruits object at 0x000001A5EF937588>, <__main__.Fruits object at 0x000001A5EF9375C0>]
----------------------------------------------------------------------------------------------------
{<__main__.Fruits object at 0x000001A5EF9370F0>, <__main__.Fruits object at 0x000001A5EF92C6D8>, <__main__.Fruits object at 0x000001A5EF9373C8>}'''
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。