一,isinstance和issubclass
isinstance(obj,cls)检查obj是否是类cls的对象
issubclass(sub,super)检查sub类是否是super类的子类
# class A: # pass # class B(A):pass # a=A() # b=B() # print(issubclass(B,A)) #判断一个类是否为一个类的子类 # print(isinstance(a,A)) #判断对象是否为类的对象 # print(isinstance(b,A))
二,反射
1,什么是反射?
主要是指程序可以访问、检测、和修改它本身状态或行为的一种能力。
2,python面向对象中的反射:通过字符串的形式操作对象相关的属性(就是用字符串类型的名字去操作变量),python中一切事物皆对象(都可以使用反射)
四个实现反射的函数
1,getattr,hasattr(一般一起用)
# class A:pass # class B(A):pass # a = A() # print(isinstance(a,A)) # print(issubclass(B,A)) # print(issubclass(A,B)) # 反射 : 是用字符串类型的名字 去操作 变量 # name = 1 # eval(‘print(name)‘) # 安全隐患 # 反射 就没有安全问题 # 反射 : 是用字符串类型的名字 去操作 变量 # 反射对象中的属性和方法 # hasattr getattr setattr delattr # class A: # def func(self): # print(‘in func‘) # # a = A() # a.name = ‘alex‘ # a.age = 63 # # 反射对象的属性 # ret = getattr(a,‘name‘) # 通过变量名的字符串形式取到的值 # print(ret) # print(a.__dict__) # 变量名 = input(‘>>>‘) # func # print(getattr(a,变量名)) # print(a.__dict__[变量名]) # # # 反射对象的方法 # a.func() # ret = getattr(a,‘func‘) # ret() # # class A: # price = 20 # @classmethod # def func(cls): # print(‘in func‘) # # 反射类的属性 # # A.price # print(getattr(A,‘price‘)) # # # 反射类的方法 :classmethod staticmethod # # A.func() # if hasattr(A,‘func‘): # getattr(A,‘func‘)() #模块 # import my # 反射模块的属性 # print(my.day) # print(getattr(my,‘day‘)) # 反射模块的方法 # getattr(my,‘wahaha‘)() # 内置模块也能用 # time # asctime # import time # print(getattr(time,‘time‘)()) # print(getattr(time,‘asctime‘)()) # def qqxing(): # print(‘qqxing‘) # year = 2018 # import sys # # print(sys.modules[‘__main__‘].year) # # 反射自己模块中的变量 # # print(getattr(sys.modules[‘__main__‘],‘year‘)) # # # 反射自己模块中的函数 # # getattr(sys.modules[‘__main__‘],‘qqxing‘)() # 变量名 = input(‘>>>‘) # print(getattr(sys.modules[__name__],变量名)) # 反射的函数有参数 # print(time.strftime(‘%Y-%m-%d %H:%M:S‘)) # print(getattr(time,‘strftime‘)(‘%Y-%m-%d %H:%M:S‘)) # 一个模块中的类能反射得到 # import my # print(getattr(my,‘C‘)()) # if hasattr(my,‘name‘): # getattr(my,‘name‘)
2,setattr设置修改变量
# class A: # pass # a=A() # setattr(a,"name","nezha") # setattr(A,"name","fg") # print(a.name) # print(A.name)
3,delattr删除
# 删除 delattr # delattr(a,"name") # print(a.name)
三,双下方法
1,__str__和__repr__
# obj.__str__ str(obj) # obj.__repr__ repr(obj) # class Teacher: # def __init__(self,name,salary): # self.name = name # self.salary = salary # def __str__(self): # return "Teacher‘s object :%s"%self.name # def __repr__(self): # return str(self.__dict__) # def func(self): # return ‘wahaha‘ # nezha = Teacher(‘哪吒‘,250) # print(nezha) # 打印一个对象的时候,就是调用a.__str__ # print(repr(nezha)) # print(‘>>> %r‘%nezha) #a.__str__ --> object # object 里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址 # l = [1,2,3,4,5] # 实例化 实例化了一个列表类的对象 # print(l) # %s str() 直接打印 实际上都是走的__str__ # %r repr() 实际上都是走的__repr__ # repr 是str的备胎,但str不能做repr的备胎 # print(obj)/‘%s‘%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串 # 如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__。 # repr(),只会找__repr__,如果没有找父类的
2,__len__
# 内置的方法有很多 # 不一定全都在object中 # class Classes: # def __init__(self,name): # self.name = name # self.student = [] # def __len__(self): # return len(self.student) # def __str__(self): # return ‘classes‘ # py_s9= Classes(‘python全栈9期‘) # py_s9.student.append(‘二哥‘) # py_s9.student.append(‘泰哥‘) # print(len(py_s9)) # print(py_s9)
3,__del__
析构方法,当对象在内存中被释放,自动触发执行。
此方法一般无需定义,因为python是一门高级语言,析构函数的调用是由解释器自动触发。
# class A: # def __del__(self): # print("爸爸执行了") # a=A() # del a # print(">>>>")
4,__call__
对象后面加括号,触发执行。
构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()
class A: def __init__(self, name): self.name = name def __call__(self): ‘‘‘ 打印这个对象中的所有属性 :return: ‘‘‘ for k in self.__dict__: print(k, self.__dict__[k]) b= A(‘alex‘)() #执行__call__ #name alex class A: def __init__(self): print("sd") def __call__(self): print("ahi") a=A() a() A()() #结果 # sd # ahi # sd # ahi
5,item系列
getitem / setitem /delitem # class Foo: # def __init__(self,name,age): # self.name=name # self.age=age # def __getitem__(self, item): # if hasattr(self, item): # return self.__dict__[item] #查 # def __setitem__(self, key, value): # self.__dict__[key]=value #增 改 # def __delitem__(self, key): # del self.__dict__[key] #删 # f=Foo("hi",6) # f["age"]=12 # print(f["age"]) # f["gao"]=1.77 # print(f["gao"]) # del f["gao"] #通过自己实现的(__delitem__方法) # del f.gao #object 原生支持的 # print(f["gao"])
6,__new__(构造方法:创建一个对象)
# class A: # def __init__(self): # self.s=5 # print("2") # def __new__(cls, *args, **kwargs): # print("1") # return object.__new__(A) # a1=A() # a2=A() # print(a1.s)
# class A: # __instance=False # def __init__(self,name,age): # self.name=name # self.age=age # def __new__(cls, *args, **kwargs): # if cls.__instance: # return cls.__instance # cls.__instance=object.__new__(cls) # return cls.__instance # egon=A("egg",45) # egon.cloth="棍子" # egon.hi="df" # print(egon.__dict__) # na=A("gh",23) # print(na.__dict__) # print(egon.__dict__) 只会创建一个对象,新的会覆盖旧的对象
7,__hash__
# class A: # def __init__(self,name,sex): # self.name=name # self.sex=sex # def __hash__(self): # return hash(self.name+self.sex) # a=A("nazha","ni") # b=A("nazha","ni") # print(hash(a)) # print(hash(b)) 有__hash__方法得到的哈希值是参数内容的哈希值。 没有__hash__方法得到的哈希值是对象的哈希值。
8,__eq__
class A: def __init__(self,name): self.name=name def __eq__(self, other): if self.__dict__ == other.__dict__: return True else: return False ob1=A("alex") oa1=A("alex") print(ob1==oa1) __eq__比较内容是否一致
注:默认比较内存地址