主要内容:
1. isinstance 判断对象所属类型,包括继承关系
class A:pass
class B(A):pass
b = B()
print(isinstance(b,B)) #ture
print(isinstance(b,A)) #o,t
注意:type() 只管本层,不包含继承关系
class mystr(str):pass
ms = mystr('alex')
print(ms)
print(type(ms) is str) # 不包含继承关系,只管一层
print(isinstance('alex',str)) # 包含所有的继承关系
2. issubclass 判断类与类的关系.
class A:pass
class B(A):pass
print(issubclass(B,A)) #ture 判断类与类之间的关系.
3. 反射 : 用字符串类型的变量名来访问这个变量的值.
反射的方法: getattr : 获取属性
hasattr : 检测是否含有某属性
setattr : 设置属性
delattr : 删除属性
1) : getttr 和 hasattr
a : 类名:静态属性,类方法,静态方法
class A:
name = 'alex'
@classmethod
def func(cls):
print('fnc...')
@staticmethod
def fn():
print('fn...')
反射查看属性
print(A.name)
print(getattr(A,'name')) #访问静态属性
反射调用方法
getattr(A,'func')() #访问类方法
getattr(A,'fn')() #访问静态方法
#hasattr : 检测是否含有某属性
print(hasattr(A,'name')) #检测是否含有某属性
print(hasattr(A,'func')) #返回ture
# 反射调用方法更加安全.
num = input('>>>')
if hasattr(A,num):
getattr(A,num)()
b : 对象 : 方法,静态属性
class A:
name = 'alex'
@classmethod
def func(cls):
print('fnc...')
@staticmethod
def fn():
print('fn...')
a = A()
print(getattr(a,'name'))
getattr(a,'func')()
getattr(a,'fn')()
c : 模块名 . 名字
格式 : import 模块
getattr(模块,'名字')
import os
os .rename('lianxi.py','练习1.py')
getattr(os,'rename')('练习1.py','lianxi.py')
d : 自己文件 . 名字
格式 : import sys
getattr (sys.modules[__main__], '名字')
反射自己模块中的内容,找到自己当前文件所在的命名空间
def wahaha():
print('wahaha')
def qqxing():
print('qqxing')
# import importx相当于导入了一个模块,模块导入与否,在pyhon解释器中都会记录下来
import sys #是一个模块,这个模块的所有方法都是和python解释器相关的
print(sys.modules) #这个方法 表示所有在当前这个python程序中导入的模块
# '__main__': <module '__main__' from 'C:/Users/26897/PycharmProjects/untitled/Workspace/day 21 反射/练习.py'>
print(sys.modules['__main__']) #找到自己当前所在的命名空间
myfile = sys.modules['__main__']
myfile.wahaha()
getattr(myfile,'wahaha')()
myfile.qqxing()
getattr(myfile,'qqxing')()
2) setattr 和 delattr
class A:
name = 'alex'
@classmethod
def func(cls):
print('fnc...')
@staticmethod
def fn():
print('fn...')
setattr(A,'name','sb')
print(A.__dict__)
delattr(A,'name')
print(A.__dict__)
补充: 枚举
# 枚举 : 索引 每一项内容,后面的数字是索引从几开始
l = ['a','b','c']
for num,i in enumerate(l,1):
print(num,i)
# 结果
# 1 a
# 2 b
# 3 c
4. __call __ 方法 : 对象()相当于调用__call__方法
class A:
def __call__(self, *args, **kwargs):
print('执行__call方法了')
def call(self):
print('执行call方法了')
a = A()
a() #对象() 相当于执行__call__方法
A()() #相当于先实例化一个对象,然后对象(),相当于调用__call__方法
# 执行__call方法了
class A:
def __call__(self, *args, **kwargs):
print('执行__call方法了')
def call(self):
print('执行call方法了')
class B:
def __init__(self,cls):
print('在实例化A之前做一些事情')
self.a = cls() #对A进行实例化, selfa 相当于一个对象
self.a() #对象() 执行__call__方法
print('在实例化A之后做一些事情')
A()() # 类名()() ,相当于先实例化得到一个对象,再对对象(),==>和上面的结果一样,相当于调用__call__方法
B(A)
5. __len__ :内置函数和内置方法是有关系的. len(obj)相当于调用了__len__方法
class mylist:
def __init__(self):
self.lst = [1,2,3,4,5,6]
self.name = 'alex'
self.age = 83
def __len__(self):
print('执行__len__了')
return len(self.__dict__)
l = mylist() #{'lst': [1, 2, 3, 4, 5, 6], 'name': 'alex', 'age': 83}
print(l.__dict__)
print(len(l))
# len(obj)相当于调用了这个obj的__len__方法
# __len__方法return的值就是len函数的返回值
# 如果一个obj对象没有__len__方法,那么len函数会报错
计算字符串的长度
class Lis:
def __init__(self,s):
self.s = s
def __len__(self):
return len(self.s)
l = Lis('aaaaa')
print(l.__dict__)
print(len(l))
6 . __new__ 构造方法 (__init__初始化方法)
新式类,开始实例化时,__new方法会返回当前类的实例,然后该类的__init方法,接收这个实例self,
class Single:
def __new__(cls, *args, **kwargs):
obj = object.__new__(cls)
print('在new方法里',obj)
return obj
def __init__(self):
print('在init方法里',self)
obj = Single()
single的new,single没有,只能调用object的new方法
new方法在什么时候执行???
在实例化之后,__init__之前先执行new来创建一块空间
单例类:如果一个类,从头到尾只有一个实例,说明从头到尾只开辟了一块属于对象的空间,那么这个类就是单例类.
class Single:
__isinstance = None
def __new__(cls, *args, **kwargs):
if not cls.__isinstance:
cls.__isinstance = object.__new__(cls)
return cls.__isinstance
def __init__(self):pass
s1 = Single()
s2 = Single()
s3 = Single()
print(s1,s2,s3)
7. __str__
print一个对象相当于调用一个对象的__str__方法
str(obj),相当于执行obj.__str__方法
'%s'%obj,相当于执行obj.__str__方法
class Student:
def __str__(self):
return '%s %s %s'%(self.school,self.cls,self.name)
def __init__(self,name,stu_cls):
self.school = 'oldboy'
self.name = name
self.cls = stu_cls
he = Student('hezewei','py14')
print(he)
print(str(he)) # 内置的数据类型,内置的类,相当于执行__str__
print('学生1 : %s'%he)