首先,我们来看两个内置函数,isinstance和issubclass,前者是判断一个对象是不是相应的类型,比如:

obj = 'python'
print(isinstance(obj,str))

判断obj是否为字符串类型,结果返回True

后者issubclass则判断一个类是否为另一个的子类,比如:

class A:pass
class B(A):pass
print(issubclass(B,A))

判断B是否为A的子类,结果返回True

反射:其实它的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

python的四个重要内置函数:getattrhasattrdelattrsetattr较为全面的实现了基于字符串的反射机制。他们都是对内存内的模块进行操作,并不会对源文件进行修改。

import sys
class Commons:@staticmethoddef login():print("登录页面")@staticmethoddef logout():print("退出页面")@staticmethoddef home():print("这是网站主页")
this_moudle = sys.modules[__name__]def run():inp = input("请输入想访问页面的URl:").strip()if hasattr(Commons,inp):func = getattr(Commons,inp,'没有这个页面')func()else:print("404!")
run()

从上面的例子可以看到hasattr及getattr的用法,另外还有delattr和setattr方法类似

那么我们为什么要用反射机制呢?

其好处有:

1、实现可插拔机制(对于代码来说),可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

2、动态导入模块(基于反射当前模块成员)

def run():inp = input("请输入您想访问页面的url: ").strip()modules, func = inp.split("/")obj = __import__(modules)if hasattr(obj, func):func = getattr(obj, func)func()else:print("404")run()

输入形如:请输入您想访问页面的url: commons/home

执行结果为:这是网站主页

在这,顺便说一下,官方建议用下述的方式进行模块的导入

import importlib
importlib.import_module('需要导入的库')

接下来我们看看其他几个python内置的函数__getattr__、__setattr__、__delattr__

class Foo:def __init__(self,name):self.name = namedef __setattr__(self, key, value):
#添加/修改属性会触发它的执行 if isinstance(value,str):self.__dict__[key] = valueprint("__setattr__")else:raise TypeError("必须为字符串")def __getattr__(self, item):
#只有在使用点调用属性且属性不存在的时候才会触发 print("getattr--->%s %s"%(item,type(item)))def __delattr__(self, item):
#删除属性的时候会触发 self.__dict__.pop(item)print("__delattr__")f = Foo('zds')
print(f.name)
f.age = '18'
print(f.age)
del f.age
print(f.__dict__)
print(f.xxxxx)

包装与授权

包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工)

授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

实现授权的关键点就是覆盖__getattr__方法

以下示例作为练习:

基于授权定制自己的列表类型,要求定制的自己的__init__方法,
 定制自己的append:只能向列表加入字符串类型的值
 定制显示列表中间那个值的属性
 其余方法都使用list默认的

class List(list):def __init__(self,obj):super().__init__(obj)def append(self, p_object):if not isinstance(p_object,str): raise TypeError("must be str type")super().append(p_object)@propertydef mid_value(self):return self[(self.__len__())//2]def __getattr__(self, item):if hasattr(List,item):func = getattr(List,item)return self.func()else:print("没有这个方法")l = List([1,2,3,4,5,6])
l.append('7')
print(l)
print(l.mid_value)
l.insert(0,9)
print(l)

运行结果为:

[1, 2, 3, 4, 5, 6, '7']
4
[9, 1, 2, 3, 4, 5, 6, '7']

转载于:https://blog.51cto.com/altboy/1918921

Python面向对象之反射相关推荐

  1. Python面向对象中反射和双下的正确用法

    一.反射 反射:程序可以访问,检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性 python中的一切事物都是对象(都可以使用反射) 四个可 ...

  2. python 面向对象之:反射,双下方法

    函数vs 方法 # 1 通过函数名可以大致判断 # print(func) # <function func at 0x00000000005D1EA0> 函数 # obj = A() # ...

  3. Python - 面向对象编程 - 反射 hasattr、getattr、getattr、delattr

    什么是反射 反射的概念是由 Smith 在 1982 年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) Python 面向对象中的反射 通过字符串的形式操作对象的属性 ...

  4. Python面向对象:反射(hasattr和getattr和setattr和delattr)

    一.反射在类中的使用 反射就是通过字符串来操作类或者对象的属性 反射本质就是在使用内置函数,其中反射有以下四个内置函数: hasattr:判断一个方法是否存在与这个类中 getattr:根据字符串去获 ...

  5. Python面向对象06/反射/双下方法

    目录 day 26 /反射,双下方法 目录 1.元类type 2.反射 3.函数与类的区别 4.特殊的双下方法 day 26 /反射,双下方法 目录 1.元类type type:获取对象从属的类Pyt ...

  6. 【专题】详解Python中的反射机制

    Python面向对象的反射机制 一.反射的概念 二.熟悉面向对象的属性方法 三.面向对象的反射机制 四.实例应用 一.反射的概念 python的反射机制,核心就是利用字符串去已存在的模块中找到指定的属 ...

  7. Python面向对象反射,双下方法

    一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...

  8. 【Python第六篇】Python面向对象(进阶篇)及相关(异常处理、反射)

    本节内容: 类的成员 字段 方法(静态方法.类方法.普通方法) 属性 类成员的修饰符(私有成员.公有成员) 类的特殊成员 异常处理 反射 类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成 ...

  9. python——面向对象篇之异常和反射

    内置函数isinstance和issubclass 1.1 isinstance用法: 1 isinstance(string,str) 判断第一个参数是否是第二个参数的子集,例如: 1 print ...

最新文章

  1. SCI写作常用句式总结,帮你迅速提升paper档次
  2. group_concat
  3. Logparser 分析 Exchange 日志文件
  4. git pull request工作模式
  5. Python的5种传参姿势,两分钟就能了解
  6. anaconda中的python如何进行关联分析_浅析python,PyCharm,Anaconda三者之间的关系
  7. sigterm信号_Golang之信号处理(Signal)
  8. lucene创建索引_Lucene概述第一部分:创建索引
  9. Word 2003中为什么修改一个段落的文章结果整篇文档的格式都变?
  10. 数据中台赋能企业数字化转型的四个关键成功因素
  11. 3-32,3-33Pytorch与autograd中的几个重要概念
  12. 蓝桥杯 ADV-136算法提高 大数加法
  13. python中进制转换函数_Python内置函数进制转换的用法
  14. 2010年中国十大最赚钱职业
  15. vb.net 编写的简易串口调试程序
  16. 服务器怎么用iso文件装系统,u盘使用iso文件安装系统的方法
  17. Tomcat 启动速度慢,一直转圈的原因
  18. 计算机手动配置信息,手动配置 IPv6
  19. 一个疯子的DK马历程(易中天说:悲剧啊)
  20. 应广PMS171B(1)--概述配置端口输出高低电平

热门文章

  1. HEML、CSS、Javascript基础知识总结
  2. Qt维基文档翻译:D-指针,D-Pointer
  3. 相机标定(2)opencv2实现
  4. python设计---空域增强之图片去噪(中值滤波、均值滤波、高斯滤波、双边滤波)
  5. MyBatis日志插件:Mybatis Log Plugin——将控制台输出的mybatis日志转化成可执行的sql语句
  6. Python中functools模块函数解析
  7. 雇佣K个工人的最小费用 Minimum Cost to Hire K Workers
  8. 通过命令在navicat中创建数据库及表结构
  9. virtualbox display size
  10. 【转】DBMS_STATS.GATHER_TABLE_STATS详解