面向对象进阶

isinstance判断对象的所属类型包括继承 

例:

class A:pass
class B(A):pass
b = B()
print(isinstance(b,B)) ==>True
print(isinstance(b,A)) ==>True

例:

class My(str):pass
me = My("小白")
print(type(me) is str) ==>False #不包含继承,只管一层
print(isinstance("小白",str)) ==>True #包含所有的继承关系

  issubclass判断两个类的关系

例:

class A:pass
class B(A):pass
print(issubclass(B,A)) ==>True
print(issubclass(A,B))  ==>False

反射:

 用字符串数据类型的变量来访问这个变量的值   (getattr,hasattr,setattr,delattr)

1.类:语法:getattr(类名,"变量/方法名")    命名空间.变量/方法名 <==> getattr(命名空间,"变量/方法名")  

(1)反射查看静态属性  

例:

class Student:
ROLE = "student"
print(getattr(Student,"ROLE")) ==>student #第一个参数的命名空间中的变量名为第二个参数的变量的值

(2)反射调用方法

例:

class Student:
@classmethod
def check_course(cls):
print("查看课程")
@staticmethod
def login():
print("登录成功")
getattr(Student,"check_course")() ==>查看课程 #类方法
getattr(Student,"login")() ==>登陆成功 #静态方法
num = input(">>>>")           ==> >>>>login
if hasattr(Student,num):          登录成功
getattr(Student,num)()

2.对象:语法:getattr(对象,"方法名")

例:

class Student:
def __init__(self,name):
self.name = name
def func(self):
print("in func")
s = Student("小白")
getattr(s,"func")() ==>in func

3.模块:语法:getattr(模块名,"模块内部的方法名")   

例:

import os      #别人写好的python代码结合
getattr(os,"rename")("a","a.txt") <==> os.rename("a","a.txt") #将名为a的文件改命名为a.txt

4.自己模块中的内容:

例:

import sys       #导入一个模块,sys模块,这个模块里的所有的方法都是和python解释器相关的
def wahaha():
print("wahaha")
def qqxing():
print("qqxing")
print(sys.modules["__main__"]) #sys.mudules这个方法表示所有在当前这个python程序中导入的模块
file = sys.modules["__main__"]
getattr(file,"wahaha")()
结果:<module '__main__' from 'F:/面向对象/18.07.30/课堂练习.py'>
   wahaha

setattr(对象,属性名,新值)   修改属性值

delattr(对象,"属性名")    删除属性

例:

class A:
def __init__(self,name):
self.name = name
a = A("小白")
setattr(a,"name","小白1")
print(a.name) ==>小白1
delattr(a,"name")
print(a.__dict__) ==>{}

__名字__    (双下方法,魔术方法,类中的特殊方法,内置方法)

类中的每一个双下方法都有自己的特殊意义

面向对象中的双下方法:

 所有的双下方法,没有需要我们在外部直接调用的 总有一些其他的内置函数特殊方法来自动触发这些双下方法

__call__                 对象()  <==>  类名()()

 例:

class A:
def __call__(self, *args, **kwargs):
print("in call")
a = A() <==> A()()
a() ==>in call #调用__call__方法

例:

class A:
def __call__(self, *args, **kwargs):
print("in call")
class B:
def __init__(self,cls):
self.a = cls() #实例化A类 self.a是A的对象
self.a()
B(A) ==>in call

__len__    len(obj)相当于调用这个对象的__len__方法

例:

class My:
def __init__(self):
self.lst = [1,2,3,4,5]
self.name = "小白"
def __len__(self):
return len(self.lst)
l = My()
print(len(l)) ==>5

例:

class My:
def __init__(self):
self.lst = [1,2,3,4,5]
self.name = "小白"
def __len__(self):
return len(self.__dict__) #return的值就是len函数的返回值
l = My()
print(len(l)) ==>2

 如果一个函数没有__len__方法那么len函数会报错

__new__是构造函数 

在实例化之后,执行__init__函数之前,先执行__new__函数来创建一块空间

例:

class Single:
def __new__(cls, *args, **kwargs):
obj = object.__new__(cls)
return obj
def __init__(self):
print("在 init")
a = Single()        ==>在 init

 例:单例类

class Single:
__ISINSTANCE = None
def __new__(cls, *args, **kwargs):
if not cls.__ISINSTANCE: #第一次实例化之后if判断为True 之后再实例化if判断都为False
cls.__ISINSTANCE = object.__new__(cls)
return cls.__ISINSTANCE
def __init__(self,name,age): #self = cls.__ISINSTANCE
self.name = name
self.age = age
s1 = Single("小黑",18)
s2 = Single("小白",20)
print(s1,s2) ==><__main__.Single object at 0x0000018A9E1E00B8> <__main__.Single object at 0x0000018A9E1FF908>

__str__  print(obj),"%s"% obj,str(obj)都会触发__str__方法

例:

class Student:
def __str__(self):
return "%s %s %s" % (self.name,self.sex,self.age)
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
s = Student("小白","男",20)
print(s) ==>小白 男 20       #print一个对象相当于调用一个对象的__str__方法
print(str(s))      ==>小白 男 20        #str(obj)相当于执行__str__方法
print("学生:%s" % s)   ==>学生:小白 男 20     #"%s" % obj 相当于执行obj.__str__方法

__repr__   (repr(对象)和%r触发__repr__方法)

例:

a = "123"
print(a) ==>123
print(repr(a)) ==>"123"

例:

class A:
def __init__(self,name):
self.name = name
def __str__(self):
return "***%s***" % self.name
def __repr__(self):
return self.name
a = A("小白")
print(a,repr(a)) ==>***小白*** 小白
print("%s | %r" % (a,a)) ==>***小白*** | 小白

在子类中的对象要使用__str__方法先找子类的__str__方法,子类中没有就向父类中找__str__只要不是object就执行__str__,但是如果没有除了object之外的父类都没有__str__方法,就执行子类的__repr__方法,如果没有就执行父类中的__repr__方法,一直找不到,再执行object类中的__sr__方法

__del__ 析构方法:释放一个空间   析构函数是去归还(释放)一些在创建对象的时候借用的资源   

del 对象和python解释器的垃圾回收机制回收这个对象所占的内存的时候,python自动触发执行__del__方法,把所有变量都删除了

例:

class A:
def __del__(self):
print("执行了") #在执行del a之前执行了__del__方法
a = A()
del a
print(a) ==>执行了 报错因为a被删了

对象借用了操作系统资源(文件资源,网络资源),还要通过__del__方法(析构方法)归还回去

例:

class File:
def __init__(self,file):
self.f = open(file)
def read(self):
self.f.read(1024)
def __del__(self):
self.f.close()
f = File("选课")
f.read()
del f

不管是被动还是主动这个f对象总会被清理,被清理时触发__del__方法,触发这个方法就会执行"self.f.close()"归还操作系统的文件资源.

item (__getitem__,__setitem__,__delitem__)     对象[]触发函数

例:

class A:
def __getitem__(self, item):
print("in getitem",item)
return "bb"
b = A()
print(b["a"])
==>in getitem a
bb

例:

class A:
def __getitem__(self, item):
return getattr(self,item)
def __setitem__(self, key, value):
return setattr(self,key,value)
    def __delitem__(self, key):
   delattr(self,key)
b = A()
b["k"] = "v" #执行__setitem__函数为b封装一个"k"="v"的属性
print(b["k"]) ==>v #执行__getitem__函数 返回值是调用b的"k"属性
del b["k"]
print(b["k"]) ==>报错因为b的"k"已经删除了

例:

class A:
def __init__(self,lst):
self.lst = lst
def __getitem__(self, item):
return self.lst[item]
def __setitem__(self, key, value):
self.lst[key] = value
def __delitem__(self, key):
self.lst.pop(key)
l1 = ["111","222","555"]
a = A(l1)
print(a[0]) ==>111
a[2] = "333"
print(a[2]) ==>333
del a[2]
print(a.lst) ==>["111","222"]

hash算法  是底层数据结构基于hash值寻址的优化操作

hash函数是一个算法,能把某一个要存放在内存的值,通过一系列的计算,保证不同值的hash结果是不一样的

对同一个值在多次执行python代码时候hash值是不同的

对同一个值在同一次执行python代码时候hash值是永远不变的

set集合去重原理:hash值找到一块内存地址只要这块地址上没有数据就说明之前没有重复的数据,如果这块地址上有数据存在了,再判断这个值和之前存在的值内容是否一样,如果一样覆盖去重,如果不一样二次寻址给这个值换个地方存.

__eq__          ==触发__eq__方法

例:

class A:
def __init__(self,name):
self.name = name
def __eq__(self, other):
if self.name == other.name:
return True
a = A("小白")
b = A("小白")
print(a,b) ==><__main__.A object at 0x000001F599311128> <__main__.A object at 0x000001F599311160> #两个不同的内存地址
print(a==b) ==>True

例: 员工管理系统:公司里小王从运维部转到开发部公司的员工信息中小王即存在运维部又存在开发部写一段代码判断两个部门小王的信息是一个人的信息

class Employee:
def __init__(self,name,sex,age,partment):
self.name = name
self.sex = sex
self.age = age
self.partment = partment
def __hash__(self):
return hash("%s %s" % (self.name,self.sex))
def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:
return True
employee_lst = [Employee("小王","男",20,"运维"),Employee("小王","男",22,"python"),
Employee("小白","男",20,"大数据"),Employee("小白","男",20,"运维")]
employee_set = set(employee_lst) #set去重机制:先调用__hash__函数再调用__eq__,__eq__函数只要hash值相等时才会触发
for person in employee_set:
print(person.__dict__)
结果:
{'name': '小王', 'sex': '男', 'age': 20, 'partment': '运维'}
{'name': '小白', 'sex': '男', 'age': 20, 'partment': '大数据'}
原文地址:https://www.cnblogs.com/gxj742/p/9393132.html