反射:python
用字符串数据类型的变量名来访问这个变量的值程序员
反射的方法:网络
getattr hasattr setattr delattr函数
getattr: 命名空间.方法名或属性 == getattr(命名空间,'方法名或属性') 得到类中变量的值 若变量不存在则报错spa
hasattr: 判断类中指定变量是否存在,返回bool值 能够配合getattr使用操作系统
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')() # 静态方法 num = input('>>>') if hasattr(Student,num): 判断方法名在指定类中是否存在,返回bool值 getattr(Student,num)()
####getattr用途很普遍,基本命名空间.方法名或属性名 这类语句均可以用getattr替代 好比 对象
# import os # # os.rename('__init__.py','init') # # getattr(os,'rename')('init','__init__.py') # == os.rename # rename = os.rename # rename2 = getattr(os,'rename') # rename2('__init__.py','init') # os.rename('__init__.py','init') # rename('init','init2') # os.rename('init','init2')
####反射本身模块中的内容 找到本身当前文件所在的命名空间blog
def wahaha():
print('wahaha')
def qqxing():
print('qqxing')
wahaha() qqxing() import sys print(sys.modules) # import 都至关于导入了一个模块 #模块哪一个导入了 哪一个没导入 在个人python解释器里应该记录下来 import sys #是一个模块,这个模块里的全部的方法都是和python解释器相关的 # sys.modules #这个方法 表示全部在当前这个python程序中导入的模块 # '__main__': <module '__main__' from 'D:/sylar/python_workspace/day20/4.反射.py'> #自身模块在modules中的键值对 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')()
setattr:修更名称内存
delattr:删除指定方法或属性资源
class A: def __init__(self,name): self.name = name a = A('alex') # a.name = 'alex_SB' # getattr(a,'name') setattr(a,'name','alex_SB') #修改对象属性 print(a.name) print(a.__dict__) del a.name print(a.__dict__) delattr(a,'name') #删除对象属性 print(a.__dict__)
__名字__
类中的特殊方法\内置方法
双下方法
魔术方法 magic_method
类中的每个双下方法都有它本身的特殊意义
__call__ 至关于 对象()
__len__ len(obj)
__new__ 开辟内存空间的 类的构造方法
写一个单例类=
__del__ 析构方法,与__new__相对应 垃圾回收机制
全部的魔术方法都是在外部执行内置函数或者特殊语句而自动在内部执行的,不须要在外部额外出发
__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() A()() # 类名()() ,至关于先实例化获得一个对象,再对对象(),==>和上面的结果同样,至关于调用__call__方法 B(A) 将A类当作参数传进B类进行实例化
__len__:
# 内置函数和类的内置方法是有奸情的 # len(dict) # len(tuple) str list set 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() print(len(l)) # len(obj)至关于调用了这个obj的__len__方法 # __len__方法return的值就是len函数的返回值 # 若是一个obj对象没有__len__方法,那么len函数会报错
__new__:
__new__ ==> 构造方法
__init__ ==>初始化方法
class Single: def __new__(cls, *args, **kwargs): # print('在new方法里') obj = object.__new__(cls) print('在new方法里',obj) return obj def __init__(self): print('在init方法里',self) # 1.先执行__new__方法,开辟一个属于对象的空间 # 2.把对象的空间传给self,执行init # 3.将这个对象的空间返回给调用者 obj = Single()
单例类:
class Cls: __COND=None def __new__(cls, *args, **kwargs): if not Cls.__COND : Cls.__COND=object.__new__(Cls) return Cls.__COND def __init__(self,name): self.name=name c1=Cls('alex') c2=Cls('kangkang') print(c1) print(c2) #两次打印的内存地址同样,说明只开辟了一个对象空间 print(c1.name) print(c2.name) #由于只开辟了一个对象空间,因此后续实例化的对象属性会覆盖前面的属性
__del__ 析构方法 垃圾回收机制
#构造方法 申请一个空间 #析构方法 释放一个空间以前执行 #某对象借用了操做系统的资源,还要经过析构方法归还回去 : 文件资源 网络资源 #垃圾回收机制 class A: def __del__(self): # 析构方法 del A的对象 会自动触发这个方法 print('执行我了') a = A() del a # 对象的删除 del print(a) class File(): # 处理文件的 def __init__(self,file_path): self.f = open(file_path) self.name = 'alex' def read(self): self.f.read(1024) def __del__(self): # 是去归还/释放一些在建立对象的时候借用的一些资源 # del 对象的时候 程序员触发 # python解释器的垃圾回收机制 回收这个对象所占得内存的时候 python自动触发的 self.f.close() f = File('文件名') f.read() #无论是主动仍是被动,这个f对象总会被清理掉,被清理掉就触发__del__方法,触发这个方法#就会归还操做系统的文件资源 #python解释器在内部就能搞定的事儿 #申请一起空间 操做系统分配给你的 #在这一起空间以内的全部事儿 归你的python解释器来管理 a = 1 del a 对象 --> 内存 f = open('wenjian') # python --> 操做系统 --> 硬盘里的文件 --> 文件操做符 f.close() # 文件操做符 del f