# 类相关的内置函数
# 类相关的内置函数# 1.isinstance 用于判断,对象是否是对应类型,返回True或者False 接收两个参数,(实例化的对象,类型) 如果存在继承关系也会返回Trueisinstance(1,int)# 2.issubclass 用于判断类于类之间的继承关系 例:issubclass(B,A)判断B是否继承与A 参数只能传入类class A:passclass B(A):passa = A()b = B()issubclass(A,A)# == 跟 is 的区别 (== 判断值是否相等,is判断内存地址是否相同)
# 反射# 用字符串数据类型的变量名来访问,这个变量的值'''getattr: 使用字符串来访问变量,或者执行方法 # 访问变量 getattr(对象|类|模块,'变量名') # 执行方法 getattr(对象|类|模块,'方法名')(参数) hasattr: 用于判断,该属性或者方法在该对象中是否存在 hasattr(对象|类|模块,'方法名|属性名') setattr: 用于修改对象属性 setattr(对象|类|模块,'属性名','新值')delattr: 用于删除对象属性 delattr(对象|类|模块,'属性名')'''class A: name = '777' def func(self,arg): print(arg)a = A()import sysprint(sys.modules.get('__main__'))
# 反射# 用字符串数据类型的变量名来访问,这个变量的值'''getattr: 使用字符串来访问变量,或者执行方法 # 访问变量 getattr(对象|类|模块,'变量名') # 执行方法 getattr(对象|类|模块,'方法名')(参数) hasattr: 用于判断,该属性或者方法在该对象中是否存在 hasattr(对象|类|模块,'方法名|属性名') setattr: 用于修改对象属性 setattr(对象|类|模块,'属性名','新值')delattr: 用于删除对象属性 delattr(对象|类|模块,'属性名')'''class A: name = '777' def func(self,arg): print(arg)a = A()import sysprint(sys.modules.get('__main__'))
# 类中的内置方法 (特殊方法,双下方法,魔术方法)
# __call__ 实例化对象加() 就会调用 __call__ 方法class A: def __call__(self,*args,**kwargs): print('args:',args) print('kwargs:',kwargs) print('A 的__call__方法被调用了')# 第一种使用方法# a = A()# a()class B: def __init__(self,cls): self.a = cls() self.a()# 第二种使用方法# b = B(A)
# __len__ 在执行内置函数len()的时候回调用这个方法,该方法必须返回一个整数类型,否者会报错# __len__ return 的值就是len()函数计算出的长度class MyObj: def __init__(self,*args): self.args =args def __len__(self): print('MyObj的__len__方法被调用了') return 1 obj = MyObj()print(len(obj))# 练习class MyStr: def __init__(self,args): self.string = args def __len__(self): return len(self.string)s = MyStr('asc')print(len(s))
# __new__ 构造方法,在类名+()的时候调用,然后会开辟一块内存。返回给__init__(初始化方法)中的selfclass A: def __new__(cls,*args,**kwargs): # 由于Python语言无法开辟空间,我们得调用父类(object)的__new__方法来开辟空间(下面两种方法都可以) # obj = object.__new__(cls) obj = super().__new__(cls) print(obj) return obj def __init__(self): print('在初始化方法中',self) A()# 使用场景 单例类class B: __ISINCTANCE = None def __new__(cls,*args,**kwargs): if not cls.__ISINCTANCE: cls.__ISINCTANCE = super().__new__(cls) return cls.__ISINCTANCE def __init__(self,name): print(self) self.name = name a = B(1)b = B(2) c = B(3)print(a,b,c)print(a.name,b.name,c.name)
# __str__ 在执行print|str|'%s'% obj 的时候 调用class A: def __init__(self,name): self.name = name def __str__(self): return self.name a = A('444')print(a)print(str(a))print('字符串格式化:%s'%a)
# __repr__# 内置函数 repr() 原样输出,在打印输出的时候,原样显示\n \t等特殊字符,输出的字符串也会被""包括(但是%s占位符还是可以正常使用)# 如果没有__str__,那么调用 __str__方法的操作会找__repr__方法来取值class A: def __init__(self,name): self.name = name# def __str__(self):# return self.name def __repr__(self): return '\'%s\''%self.nameclass B(A): def __repr__(self): return '\'%s\''%self.name a = B('aaa')print(a) print(repr(a))
# __del__ 析构方法 释放一个空间# 跟构造方法相反 __new__ 构造方法 申请一个空间class A: def __del__(self,*args,**kwargs): ''' 执行 del key 的时候触发 就算这里没有写 del相关语法,照样可以删除元素 ''' print('被删除了...') a = A()import timetime.sleep(10)
# item 系列# __getitem__ 、__setitem__class B: def __getitem__(self,item): ''' b = B() 在执行 b['key'] 的时候调用此方法 item 会接收到key ''' return getattr(self,item) def __setitem__(self,key,value): ''' b = B() 在执行 b['key']=123 的时候调用此方法 key 会接收到key ,value会接收到123 ''' setattr(self,key,value) def __delitem__(self,key): ''' b = B() 在执行 del b['key']的时候调用此方法 key 会接收到key ''' delattr(self,key) b = B()b['a123'] = 666b['a123']del b['a123']b['a123']
# 面试题 __hash__、__eq__'''员工管理系统类 属性 姓名,性别,年龄,部门 存在重复员工信息,但是部门不同(如果存在姓名相同,性别相同。我就认为这是同一个人)有1000的员工对象,筛选出重复的员工'''class Staff: def __init__(self,name,sex,age,department): self.name = name self.sex = sex self.age = age self.department = department def __hash__(self): # 自定义类的hash条件 return hash('%s%s'%(self.name,self.age)) def __eq__(self,other): # 如使用 == 语法的时候,会触发这个方法,用于判断是否相等# 如果hash值相同,会触发这个方法,来判断值是否相同(True相同,False不同) if self.name == other.name and self.sex == other.sex: return Trues1 = Staff('张三','男',28,'运营')s2 = Staff('李四','男',28,'人事')s3 = Staff('王五','男',28,'财务')s4 = Staff('钱六','男',78,'销售')s5 = Staff('王五','男',28,'销售')staff_list =[s1,s2,s3,s4,s5]'''# 使用集合的去重机制 1.计算hash值(调用对象的__hash__方法) 1.1 如果hash值不同,则存入hash对应的内存地址 1.2 如果hash相同:判断值是否相同(调用对象的__eq__方法) 1.2.1 如果值相同 :则存入hash对应的内存地址,替换之前的值 1.2.3 如果值不同 :使用另外hash算法,进行二次寻址最后留下来的就是不相同的 '''staff_set = set(staff_list)print(staff_set)