一、反射:用字符串数据类型的变量名来访问这个变量的值
上代码^_^
# class Student: # ROLE = 'STUDENT' # @classmethod # def check_course(cls): # print('查看课程了') # # @staticmethod # def login(): # print('登录')
# # 反射查看属性
# # print(Student.ROLE)#普通方法
# # print(getattr(Student,'ROLE'))
#
# # 反射调用方法
# # getattr(Student,'check_course')() # 使用类中的方法
# # getattr(Student,'login')() # 使用静态方法
用对象来反射
# class A(): # def __init__(self,name): # self.name = name # # def func(self): # print('in func') # # a = A('alex')#实例化一个对象 # print(a.name) # print(getattr(a,'name'))#获得属性值 # getattr(a,'func')()#执行方法
是不是还挺好理解的啊!!
模块角度
好像是不是有xxx.xxx就能用到啊,模块四不四 from xxx import xxx.xxx啊,对就能用。
# import os # 别人写好的python代码的结合 # # os.rename('__init__.py','init')#改文件名的功能 # # getattr(os,'rename')('init','__init__.py') #功能和上面一样后面是参数。 # rename = os.rename # rename2 = getattr(os,'rename') # rename2('__init__.py','init') # os.rename('__init__.py','init') # rename('init','init2') # os.rename('init','init2')
下一个是 反射自己模块中的内容 找到自己当前文件所在的命名空间。这个有点不好理解,不过聪明人会先记住有机会慢慢在理解。
# import sys # print(sys.modules)#查看当前模块,返回的是一个字典 # import 都相当于导入了一个模块 # 模块哪个导入了 哪个没导入 在我的python解释器里应该记录下来 # import sys 是一个模块,这个模块里的所有的方法都是和python解释器相关的 # sys.modules 这个方法 表示所有在当前这个python程序中导入的模块 # '__main__': <module '__main__' from 'D:/sylar/python_workspace/day20/4.反射.py'> # print(sys.modules['__main__']) # my_file = sys.modules['__main__']#这个先记住 # my_file.wahaha() # my_file.qqxing() # # 'qqxing' # # 'wahaha' # getattr(my_file,'wahaha')() # getattr(my_file,'qqxing')()
总结下
# 反射 # hasattr,getattr # 类名.名字 # getattr(类名,'名字') # 对象名.名字 # getattr(对象,'名字') # 模块名.名字 # import 模块 # getattr(模块,'名字') # 自己文件.名字 # import sys # getattr(sys.modules['__main__'],'名字')
下面来个实际应用场景,理解后背下来自己敲一便。
# class Manager: # OPERATE_DIC = [ # ('创造学生账号', 'create_student'), # ('创建课程','create_course'), # ('查看学生信息','check_student_info'), # ] # def __init__(self,name): # self.name = name # def create_student(self): # print('创建学生账号') # def create_course(self): # print('创建课程') # def check_student_info(self): # print('查看学生信息') # # class Student: # OPERATE_DIC = [ # ('查看所有课程', 'check_course'), # ('选择课程', 'choose_course'), # ('查看已选择的课程', 'choosed_course') # ] # def __init__(self,name): # self.name = name # def check_course(self): # print('check_course') # def choose_course(self): # print('choose_course') # def choosed_course(self): # print('查看已选择的课程') # # def login(): # username = input('user : ') # password = input('pwd : ') # with open('userinfo') as f: # for line in f: # user,pwd,ident = line.strip().split('|') # ident = 'Manager' # if user == username and pwd == password: # print('登录成功') # return username,ident # # import sys # def main(): # usr,id = login() # print('user,id :',usr,id) # file = sys.modules['__main__'] # cls = getattr(file,id) #Manager = getattr(当前文件,'Manager'),获得对应的类 # obj = cls(usr) # operate_dic = cls.OPERATE_DIC # while True: # for num,i in enumerate(operate_dic,1): # print(num,i[0]) # choice = int(input('num >>>')) # choice_item = operate_dic[choice-1] # getattr(obj,choice_item[1])() # # # # main()
主要是实现登陆和特定人员的选择和更改。
二、内置方法:有些函数里面带了特定的方法,比如len()里面可能有__len__这个方法
# __名字__
# 类中的特殊方法内置方法
# 双下方法
# 魔术方法 magic_method
# 类中的每一个双下方法都有它自己的特殊意义
1.__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() # self.a() # print('在实例化A之后做一些事情') # a = A() # a() # 对象() == 相当于调用__call__方法 # a.call()#就调用类里面的__call__方法了
# A()() # 类名()() ,相当于先实例化得到一个对象,再对对象(),==>和上面的结果一样,相当于调用__call__方法
# B(A)
2.__len__
# 内置函数和类的内置方法是由奸情的
# class My: # def __init__(self,s): # self.s = s # def __len__(self): # return len(self.s) # my = My('abc') # print(len(my))
3.__new__
# class Single: # def __new__(cls, *args, **kwargs): # obj=object.__new__(cls) # print('在new方法里',obj) # return obj # def __init__(self): # print('在init方法里',self)
#执行顺序
#1.开辟一个空间,属于对象的
#2.把对象的空间传给self,执行init
#3.将这个对象的空间返回给调用者
#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,name,age): self.name=name self.age=age print( self) a=Single('aaa',56) b=Single('sdf',55) print(a.name)
只要前面实例化一个对象,就会开辟一个内存空间。后面的实例化对象不能开辟新的内存空间,后面的对象传进去的参数会覆盖前面对象的参数。