python基础(面对对象之反射)
一、issubclass 与 type与isinstance
1.1 定义:
isinstance:
格式: isinstance(子类名, 父类名)
功能:判断类与类之间是否有继承关系
type:
格式:type(实例对象, 类)
功能:只承认实例化这个对象的那个类,与所有父类的其他继承类无关
issubclass:
格式:issubclass(类1, 类2)
功能:判断类1是不是类2的子类
1.2 相互关系:
# 示例: class User(object): pass class VIPUser(User): pass alex = VIPUser() # 实例化 ret1 = type(alex) is User ret2 = isinstance(alex, User) print(ret1, ret2) # False True ret1 = type(alex) is VIPUser ret2 = isinstance(alex, VIPUser) print(ret1, ret2) # True True
# 示例: class User(object): pass class VIPUser(User): pass alex = VIPUser() # 实例化 ret = issubclass(VIPUser, User) print(ret) # True
二、 反射getattr
2.1 定义:
用字符串数据类型的变量名 找到这个变量对应的内存地址
2.2 反射用法类型一:
a.b结构结构型:
用对象\类\模块反射,都只有以下场景
a.b中b是属性或者变量值
2.2.1 类的对象使用反射:
obj.属性名
obj.方法名()
# 示例: # 1.使用对象反射 class Manager: # 管理员用户 def __init__(self, name): self.name = name def create_course(self): # 创建课程 print('in Manager create_course') def create_student(self): # 给学生创建账号 print('in Manager create_student') def show_courses(self): # 查看所有课程 print('in Manager show_courses') def show_students(self): # 查看所有学生 print('in Manager show_students') alex = Manager('alex') operate_lst = [('创建课程', 'create_course'), ('创建学生账号', 'create_student'), ('查看所有课程', 'show_courses'), ('查看所有学生', 'show_students')] # 打印标题 for index, opt in enumerate(operate_lst, 1): print(index, opt[0]) num = input('请输入您要做的操作 :') # 类方法的调用 if num.isdigit(): num = int(num) if hasattr(alex, operate_lst[num - 1][1]): # 判断字符串是否是存在被调用的属性与方法中 getattr(alex, operate_lst[num - 1][1])() # 反射
2.2.2 在类中使用反射:
cls.静态变量名
cls.类方法名()
cls.静态方法名()
# 示例: class A: Country = '中国' @classmethod def show(cls): print('国家 : ', cls.Country) # 类属性对比 print(A.Country) print(getattr(A, 'Country')) # print(A.Country) # 类方法对比 A.show() getattr(A, 'show')() # A.show()
2.2.3 在模块使用反射:
模块中的方法名
# 示例: import re # 普通方法: ret = re.findall('\d+', '2985urowhn0857023u9t4') print(ret) # ['2985', '0857023', '9', '4'] # 反射方法: ret = getattr(re, 'findall')('\d+', '2985urowhn0857023u9t4') print(ret) # ['2985', '0857023', '9', '4']
2.3 反射用法类型二:
如果是本文件中的内容,不符合a.b这种结构时,反射的用法:
1、直接调用func()
getattr(sys.modules[__name__],'func')() # sys.modules[__name__] 当前文件
2、直接使用类名 Person()
getattr(sys.modules[__name__],'Person')()
3、直接使用变量名 print(a)
getattr(sys.modules[__name__],'a')
2.3.1 变量名使用反射:
# 示例: from sys import modules a = 1 b = 2 print(a) ret = getattr(modules[__name__], 'a') # print(a) print(ret)
2.3.2 函数名使用反射:
# 示例: from sys import modules def func(a,b): print('in func', a, b) func(1, 2) getattr(modules[__name__], 'func')(1, 2) # func
2.3.3 类名使用反射:
# 示例: from sys import modules class Course: def func(self): print('in func') print(Course) print(getattr(modules[__name__], 'Course')) # Course getattr(modules[__name__], 'Course')() # 实例化的过程
三、sys模块中modules的用法
定义:查看系统所有模块,以字典形式存在,key是模块的名字,value则是模块对应的文件地址
# 示例: from sys import modules print(modules) # dict KEY是模块的名字,value就是这个模块对应的文件地址 # modules应用: import re print(re) # <module 're' from 'D:\\Program Files\\Python36\\lib\\re.py'> print(modules['re']) # <module 're' from 'D:\\Program Files\\Python36\\lib\\re.py'> print(re.findall) # <function findall at 0x0000022D004C7EA0> print(modules['re'].findall) # <function findall at 0x0000022D004C7EA0>
四、hasattr用法
定义:判断字符串变量是否存在类中,存在则为True,否则为False
# 示例: class A: def __init__(self, name): self.name = name def func(self): print('in func') a = A('123') while True: name = input('>>>') if hasattr(a, name): # 判断字符串变量是否存在类中 func_attr = getattr(a, name) if callable(func_attr): # 判断字符串是否可以调用(调用:方法, 不可调用:属性) func_attr() else: print(func_attr)
五、setattr用法
定义:能够通过字符串数据类型的变量名 给一个对象修改或者添加属性\变量,不能用来处理函数或者是其他方法
# 示例: class A: def func(self): print('in func') a = A() a.name = '123' print(a.name) # 123 # 通过setattr给类A增加一个name属性(a.name = 123) setattr(a, 'name', '123') # a.name = 123 print(a.name) # 123
六、delattr用法
定义:只用来删除 属性\变量
# 示例: class A: def __init__(self, name): self.name = name def func(self): print('in func') a = A('123') # del a.b 删除属性 相当于删除了a对象当中的b属性 del a.name delattr(a, 'name') # 删除属性
七、 反射getattr补充
getattr方法后面可以指定参数:
如果变量存在,则获取到变量的值,否则返回指定的参数
class AB(object): count = 10 def test():
#print(getattr(AB, "count", None)) #10 print(getattr(AB, "counter", None)) #None if __name__ == '__main__': test() 打印结果: None