元类+内置方法+反射
内容概要
- 元类
- 内置方法
- 反射
内容详细
-
元类
# 一、什么是元类: # 元类就是用来实例化产生类的类 # 元类-->实例化-->类(People)-->实例化-->对象(obj) class People: def __init__(self,name,age): self.name = name self.age = age def say(self): print('%s:%s'%(self.name,self.age)) # 如何得到对象 # obj = 调用类() # obj = People('ycc',18) # print(type(obj)) # <class '__main__.People'> # 如果说类也是对象 # Peopel = 调用类() # People= People() # 查看内置的元类: # type是内置的元类 # 我们用class关键字定义的所有的类以及内置的类都是元类type实例化产生 # print(type(People)) # <class 'type'> # print(type(int)) # <class 'type'> # 二:class关键字创造People的步骤 # 肯定有一步调了内置的元类加括号,然后传了一系列参数,实例化对象,赋值给People # People = type(...) # 类有三大特征: # 1、类名 class_name = 'People' # 2、类的基类 class_bases = (object,) # 3、执行类体代码拿到类的名称空间(对应的就是类的字典) class_dic = {} # 要做一件事:把下面字符串中的代码运行一下,然后把运行过程中产生的名字都能丢到上面的字典里去 class_body= ''' def __init__(self,name,age): self.name = name self.age = age def say(self): print('%s:%s'%(self.name,self.age)) ''' # 如何做这件事: exec(class_body,{},class_dic) # 4.调用元类 People = type(class_name,class_bases,class_dic) print(People) # <class '__main__.People'> # 三、如何自定义元类来控制类的产生 class Mymeta(type): # 只有继承了type类的类才是元类 def __init__(self,class_name,class_bases,class_dic): print('run...') print(class_name) print(class_bases) print(class_dic) if not class_name.istitle(): raise NameError('类名的首字母必须大写啊!!!') # 造空对象 # cls: 当前所在的类 *args, **kwargs:调用类时所传入的参数 def __new__(cls, *args, **kwargs): # 早于__init__ # 造Mymeta对象 # print('run33333333') # print(cls,args,kwargs) return type.__new__(cls,*args,**kwargs) # People = Mymeta('People',(object),{...}) # mymeta调的时候会将 'People',(object),{...} 这三个参数先传给new,new基于cls做一个造空对象的操作 # 然后将cls传给上面的self,将*args,**kwargs传给class_name,class_bases,class_dic # 调用Mymeta发生三件事 # 1、先造一个空对象=>People,调用类内的__new__方法 # 2、调用Mymeta这个类内的__init__方法,完成初始化对象的操作 # 3、返回初始化好的对象 class People(metaclass=Mymeta): def __init__(self,name,age): self.name = name self.age = age def say(self): print('%s %s'%(self.name,self.age)) # 强调 # 只要是调用类,那么会依次调用 # 1、类内的__new__ # 2、类内的__init__ -
内置方法
# 1、什么是内置方法 # 定义在类内部,以__开头并以__结尾的方法 # 特点:会在某种情况下自动出发执行 # 2、为何要用内置方法 # 为了定制化我们的类or对象 # 3、如何用内置方法 # __str__:在打印对象时会自动触发,然后将返回值(必须是字符串类型)当作本次打印的结果输出 # class People: # def __init__(self,name,age): # self.name = name # self.age = age # # def __str__(self): # return '%s %s'%(self.name,self.age) # obj = People('ycc',18) # print(obj) # ycc 18 # __del__:在清理对象时触发,会先执行该方法 class People: def __init__(self,name,age): self.name = name self.age = age # self.x = 占据的是操作系统资源 # self.x = open('a.txt','w') def __del__(self): print('run...') # self.x.close() # 发起系统调用,告诉操作系统回收相关的系统资源 # 一: # obj = People('ycc',18) # print('====>') # 运行结果 ''' ====> run... ''' # 程序在执行结束后,释放空间,清理垃圾, # 因此,这里时先运行print('====>'),然后程序结束,释放空间,清理对象,触发__del__,打印run... # 二 obj = People('ycc',18) del obj print('====>') # 运行结果 ''' run... ====> ''' # 这是在程序运行结束前就做了del obj的操作,因此先触发了run... 然后执行了print('====>') # 二次加工标准类型,描述符等晚点再学习 https://www.cnblogs.com/linhaifeng/articles/6204014.html # 判断'abc'是不是字符串 print(isinstance('abc',str)) class Foo: pass # 判断Foo是不是object的子类 print(issubclass(Foo,object)) -
反射
# python是一门开源的强类型的动态的语言 # x = 18 # 一直到这个程序开始执行的时候,才发现其数据类型,则称为动态 # 在程序运行前就规定好其数据类型,则称为静态 # 什么是反射 # 指的是在程序运行过程中可以'动态'获取对象的信息(数据属性+功能属性) # 为何要用反射 # # 如何实现反射 # class People: # def __init__(self,name,age): # self.name = name # self.age = age # # def say(self): # print('%s:%s'%(self.name,self.age)) # # obj = People('ycc',18) # print(obj.__dict__) # # # 实现反射机制的步骤 # # 1.先通过dir:查看出某一个对象下可以.出来那些属性 # print(dir(obj)) # # # 2.可以通过字符串反射到真正的属性上,得到属性值 # print(obj.__dict__[dir(obj)[-2]]) # ycc # # # 四个内置函数的使用 # # 1、hasattr() # 判断对象是否存在 # print(hasattr(obj,'name')) # True # print(hasattr(obj,'x')) # False # # # 2、getattr() # 获取对象属性 # print(getattr(obj,'name')) # ycc 相当于在做obj.name # print(obj.name) # ycc # # # 3、setattr() # 赋值对象属性 # setattr(obj,'name','YCC') # print(obj.name) # YCC # # # 4、delattr() # 删除对象属性 # delattr(obj,'name') # print(obj.__dict__) # {'age': 18} # # # res1 = getattr(obj,'say') # # <bound method People.say of <__main__.People object at 0x000001B7AC4EDFD0>> # res2 = getattr(People,'say') # # <function People.say at 0x000001B7AC3CB550> # print(res1) # print(res2) # obj = 10 # if hasattr(obj,'x'): # print(getattr(obj,'x')) # else: # print('属性值不存在') # # print(getattr(obj,'x',None)) # 有的话获取'x'的属性值,没有的话返回默认值None class Ftp: def put(self): print('正在上传功能') def get(self): print('正在下载功能') def interactive(self): method = input('==>: ').strip() if hasattr(self,method): getattr(self,method)() else: print("没有此功能") obj = Ftp() obj.interactive()

浙公网安备 33010602011771号