一.反射

1.什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问,检测和修改它本身状态或行为的一种能能力(自省)。

2.python中的反射

反射是所有面向对象编程语言都具备的功能

python中通过一下四个函数来实现反射

1 hasattr(object,name)  #判断对象是否拥有某个属性
2 setattr(object,name,value) #为对象增加新的属性
3 getattr(object,name,default) #从对象中获取某个属性
4 delattr(object,name) #从对象中删除某个属性

3.为什么需要反射

一个类在定义的时候,可能一些属性的设计并不是很完美,而后期需要做出修改,或是增加新属性时,使用反射的方式可以不需要修改源代码

  反射的另一个优势(重点):可插拔设计 

    不仅限于修改已有的属性,通过反省能够发现已存在的属性,只要你给我一个对象我就能检查其拥有的属性,从而使用这些属性,而不需要提前了解这些对象,这大大提高了程序的扩展性

案例1:

 1 import plugins
 2 def run(plugin):
 3     while True:
 4         cmd = input('请输入指令:').strip()
 5         if cmd == 'exit':
 6             break
 7         if hasattr(plugin,cmd):
 8             fun = getattr(plugin,cmd)
 9             fun()
10         else:
11             print('该指令不受支持')
12       print(‘已退出’)

1 #plugins
2
3 class Wincmd:
4         def dir(self):
5             print('wincmd列出所有文件。。。')
6         def cd(self):
7             print('wincmd 切换目录。。。')
8         def delete(self):
9             print('wincmd 要不要删除目录。。。 ')

对案例1进行改进,使用动态导入模块

案例2:

  1.首先配置settings

class_path = 'lib.plugins.Wincmd'

  2.主体框架:

 1 import  importlib
 2 from 面向对象 import settings
 3 def run(plugin):
 4     while True:
 5         cmd = input('请输入指令:')
 6         if cmd == 'exit':
 7             break
 8         if hasattr(plugin,cmd):
 9             func = getattr(plugin,cmd)
10             func()
11         else:
12             print('该指令不受支持')
13     print('see you la la')
14
15 path,class_name = settings.class_path.rsplit('.',1)
16 mk = importlib.import_module(path)     #找到模块(文件)
17 cls = getattr(mk,class_name)  #通过反射,模块与类名,得到类
18 obj = cls()  #实例化对象
19 run(obj)  #调用函数  传入对象

二.元类

1.什么是元类?

在Python中,一切皆对象,类也是对象。

验证一下:

1 class Person:
2     pass
3 print(type(Person))
4 #<class 'type'>

由此看来Person类属于type类,是由type类产生的对象。

因此可以推导出:

用于实例化产生类的类称之为元类,就是此时的type类

2.创建类的流程分析:

一个类有三个基本组成部分:

  1.类的名字(字符类型)

  2.类的父类们(是一个元组或列表)

  3.类的名称空间(字典类型)

用另一种方式出创建类

cls_obj = type('dog',(),{})
#同样可以创建类

3.自定义元类,通过自定义原来创建类

创建类是由type完成的type中必然包含了创建了的具体代码,现在需要对这些代码进行修改,两种方式:

  1.修改type源代码不可取

  2.创建新的元类,使用自己的元类来创建类从而实现定制类

一个类没有声明自己的元类,默认他的元类就是type,除了使用内置元类type,我们也可以通过该继承type

来自定义元类,然后使用metaclass关键字参数为一个类指定元类

1 class MyType(type):
2     def __init__(self,clss_name,bases,dict):
3         super().__init__(clss_name,bases,dict)
4
5 class Person(metaclass = MyType):
6     pass

4.在自定义元类中通过覆盖type类中的__init__来控制定义类

下面有个需求,我们高度自定义一个类,需要控制类的名字必须以大驼峰的方式来书写

这是需要在自定义元类中覆盖type类中的__init__方法。

class MyType(type):def __init__(self,cls_name,bases,dict):super().__init__(cls_name,bases,dict)if not cls_name.istitle():raise Exception('类名要大写的驼峰')class Pig(metaclass = MyType):pass

5.元类中call方法(当你想要控制对象的创建过程时)

当你调用类对象时会自动珍惜元类中的__call__方法,并将这个类本身作为第一个参数传入,以及右面的一堆参数,覆盖元类中的call之后,这个类就无法产生对象,必须调用super().__call__来完成对象的创建,并返回其返回值。

案例:实现将对象的所有属性名成转为大写

class MyType(type):def __call__(self,*args,**kwargs):for k,v in kwargs.items():kwargs[k] = v.upper()return super().__call__(*args,**kwargs)class Person(metaclass = MyType):def __init__(self,name,gender):self.name = nameself.gender = gender
p = Person(name = 'jack',gender = 'man')
print(p.name)
print(p.gender)

注意:一旦覆盖了call必须调用父类的call方法来产生对象并返回这个对象

6.单例设计模式

单例:指的是一个类产生一个对象

为什么要使用单例:单例是为了节省资源,当一个类的所有对象属性全部相同时,则没有必要创建多个对象

需求:只生成一个对象

 1 class Single(type):
 2     def __call__(self, *args, **kwargs):
 3         if hasattr(self,"obj"): #判断是否存在已经有的对象
 4             return getattr(self,"obj") # 有就返回
 5         obj = super().__call__(*args,**kwargs) # 没有则创建
 6         self.obj = obj # 并存入类中
 7         return obj
 8
 9 class Person(metaclass=Single):
10     pass
11
12 # 只会创建一个对象
13 Person()
14 Person()
15 #创建再多个对象都是同一个

转载于:https://www.cnblogs.com/s686zhou/p/11271154.html

面向对象之反射,元类相关推荐

  1. python 元类的call_python3 全栈开发 - 内置函数补充, 反射, 元类,__str__,__del__,exec,type,__call__方法...

    python3 全栈开发 - 内置函数补充, 反射, 元类,__str__,__del__,exec,type,__call__方法 一, 内置函数补充 1,isinstance(obj,cls)检查 ...

  2. Python面向对象魔法、元类简介及使用

    文章目录 一.反射实战案例 二.面向对象魔法方法 三.魔法方法笔试题 四.元类简介 五.产生类的两种方式 六.元类基本使用 七.元类进阶 一.反射实战案例 1.获取配置文件中所有大写的配置 小写的直接 ...

  3. day24 反射\元类

    反射 reflect # 什么是反射, 其实是反省,自省的意思,反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力. # 反射就是通过字符串操作属性,涉及的四个函数,这四个函数就是普通的内 ...

  4. python_面向对象进阶之元类

    1:在一个py文件中,创建一个类 在另外一个py文件中,引用这个类 创建一个Person类的实例是在第6行 类是在第4行创建的** from引入模块之后,则动态的创建一个Person类(因为引入时,会 ...

  5. python 元类 type_python Class:面向对象高级编程 元类:type

    type的用法: 1.普通的type用法:检查类型class my(object): def hello(self, name='world'): print('Hello, %s.' % name) ...

  6. java 元类_[译]什么是元类metaclass?

    类即对象 在理解元类之前,需要先掌握Python中的类,Python中类的概念与SmallTalk中类的概念相似. 在大多数语言中,类是用来描述如何创建对象的代码段,这在Python中也是成立的: & ...

  7. Python 第二十六章 面向对象 元类+反射+双下方法

    元类 class A:pass obj = A() print(type('abc')) print(type([1,2,3])) print(type((22,33)))# type 获取对象从属于 ...

  8. python元类、反射及双线方法

    元类 print(type('abc')) print(type(True)) print(type(100)) print(type([1, 2, 3])) print(type({'name': ...

  9. delstr函数python_python3全栈开发-内置函数补充,反射,元类,__str__,__del__,exec,type,__call__方法详解...

    一.内置函数补充 1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象 classFoo(object):passobj=Foo()print(isinstance(obj ...

最新文章

  1. 2019最新进展 | Transformer在深度推荐系统中的应用
  2. [python]逆水行舟不进则退(1)
  3. 年轻人,莫把技术当全部
  4. 基于SignalR的站点有连接数限制问题及解决方案
  5. IT兄弟连 JavaWeb教程 文件下载技术
  6. 揭秘315黑客wifi,如何保障APP数据安全
  7. centos安装守护进程工具supervisor
  8. 利用JavaScript生成随机数字!
  9. vue调用日期_Vue 前端开发——打印功能实现
  10. 苹果cms10整合dplayer播放器
  11. lbp7660cdn设置网络打印,佳能LBP7660Cdn打印机驱动官方版
  12. linux无法更改屏幕亮度调节软件,在Deepin系统中安装闭源显卡驱动后屏幕亮度无法调节的解决...
  13. iphone计算机输入文字,10个鲜为人知的iPhone实用技巧 全知道的算我输!
  14. Lenovo 使用BoMC工具制作微码升级U盘刷新System x
  15. Omap4470 USB驱动分析之注册过程
  16. HDU 2708 Vertical Histogram 【模拟 输出格式】
  17. 大系统观:1.4时间之矢
  18. 【Nav2中文网】五、普通教程(三)用实体Turtlebot3机器人导航
  19. 浅谈SAP FICO—总账科目
  20. 数据结构c语言版二叉树的顺序存储表示,数据结构(十一) -- C语言版 -- 树 - 二叉树基本概念...

热门文章

  1. HTML一条线匀速一定区域运动,通用的匀速运动框架如何打造
  2. 北航os实验lab2笔记
  3. linux下postgresql创表添加数据
  4. 本科数学基础差的感觉 SLAM 很难,如何去提高?
  5. 表格数据横向转纵向并在el-table中渲染
  6. total-vm anon-rss file-rss shmem-rss含义
  7. python容易挂科吗_如何应付大学的python考试而不至于挂科?
  8. 聚乙烯醇(PVA)/壳聚糖(CTS)/氧化石墨烯(GO)水凝胶吸附和解吸实验(供应PNIPA/膨润土复合/聚乙烯醇/魔芋胶复合/HAP纳米纤维/GelMA复合丝素蛋白(SF)复合水凝胶等)
  9. html5怎么修改图片大小,HTML5 javascript修改canvas的大小
  10. 深度解析上海互联网产业为何沉沦