python 面向对象编程 之 反射
1 什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
四个方法的使用演示class BlackMedium: feature='Ugly' def __init__(self,name,addr): self.name=name self.addr=addr def sell_house(self): print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name) def rent_house(self): print('%s 黑中介租房子啦,傻逼才租呢' %self.name) b1=BlackMedium('万成置地','回龙观天露园') #检测是否含有某属性 print(hasattr(b1,'name')) print(hasattr(b1,'sell_house')) #获取属性 n=getattr(b1,'name') print(n) func=getattr(b1,'rent_house') func() # getattr(b1,'aaaaaaaa') #报错 print(getattr(b1,'aaaaaaaa','不存在啊')) #设置属性 setattr(b1,'sb',True) setattr(b1,'show_name',lambda self:self.name+'sb') print(b1.__dict__) print(b1.show_name(b1)) #删除属性 delattr(b1,'addr') delattr(b1,'show_name') delattr(b1,'show_name111')#不存在,则报错 print(b1.__dict__)
#类也是对象
class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print getattr(Foo, 'staticField') print getattr(Foo, 'func') print getattr(Foo, 'bar')print getattr(Foo,'bar')()#注意有什么不同
#反射当前 模块成员import sys def s1(): print 's1' def s2(): print 's2' this_module = sys.modules[__name__] hasattr(this_module, 's1') getattr(this_module, 's2')
new_method_s2=getattr(this_module,'s2')#相当于给函数起了个别名new_method_s2()s2()#输出结果相同 导入其他模块,利用反射查找该模块是否存在某个方法
#!/usr/bin/env python # -*- coding:utf-8 -*- def test(): print('from the test')
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
程序目录:
module_test.py
index.py
当前文件:
index.py
"""
import module_test as obj
#obj.test()
print(hasattr(obj,'test'))
getattr(obj,'test')()
反射的好处: 1.实现可插播机制 2.动态导入模块#--------------------------------
__setattr__,__delattr__,__getattr__
class Foo: x = 1 def __init__(self, y): self.y = y def __getattr__(self, item): print('----> from getattr:你找的属性不存在') def __setattr__(self, key, value): print('----> from setattr') # self.key=value #这就无限递归了,你好好想想 # self.__dict__[key]=value #应该使用它 def __delattr__(self, item): print('----> from delattr') # del self.item #无限递归了 self.__dict__.pop(item) # __setattr__添加/修改属性会触发它的执行f1 = Foo(10)print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值f1.z = 3print(f1.__dict__) # __delattr__删除属性的时候会触发f1.__dict__['a'] = 3 # 我们可以直接修改属性字典,来完成添加/修改属性的操作del f1.aprint(f1.__dict__) # __getattr__只有在使用点调用属性且属性不存在的时候才会触发f1.xxxxxx
class List(list): # 继承list所有的属性,也可以派生出自己新的,比如append和mid def append(self, p_object): ' 派生自己的append:加上类型检查' if not isinstance(p_object, int): raise TypeError('must be int') super().append(p_object) @property def mid(self): '新增自己的属性' index = len(self) // 2 return self[index] l = List([1, 2, 3, 4])print(l)l.append(5)print(l)# l.append('1111111') #报错,必须为int类型 print(l.mid) # 其余的方法都继承list的l.insert(0, -123)print(l)l.clear()print(l)
class List(list): def __init__(self, item, tag=False): super().__init__(item) self.tag = tag def append(self, p_object): if not isinstance(p_object, str): raise TypeError super().append(p_object) def clear(self): if not self.tag: raise PermissionError super().clear() l = List([1, 2, 3], False)print(l)print(l.tag) l.append('saf')print(l) # l.clear() #异常 l.tag = Truel.clear() # 练习(clear加权限限制)
python 面向对象编程 之 反射的更多相关文章
- python面向对象编程进阶
python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- python 面向对象编程(一)
一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...
- Python面向对象编程指南
Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...
- Python面向对象编程(下)
本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...
- Python 面向对象编程——访问限制
<无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...
- Python 面向对象编程 继承 和多态
Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...
- Python 面向对象编程基础
Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...
- python面向对象编程学习
python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...
随机推荐
- cap文件的格式说明
前面24个字节是.cap文件的文件头. 头信息对应的结构体为:struct pcap_file_header { bpf_u_int32 magic; u_short version_major; ...
- Idea使用Maven异常 --- Maven网络代理设置
在conf/setting.xml和m2/repository/setting.xml中加入: <proxies> <!-- proxy | Specification for on ...
- ArcGIS案例学习笔记2_2_txtexcel空间可视化和空间插值
ArcGIS案例学习笔记2_2_txt/excel空间可视化和空间插值 计划时间:第二天下午 教程:pdf page=337 数据:chapter8/ex4 方法: 1.加载xy.txt和gdp.tx ...
- python 如何注释
一.单行注释 单行注释以#开头,例如: print 6 #输出6 二.多行注释 (Python的注释只有针对于单行的注释(用#),这是一种变通的方法) 多行注释用三引号' ...
- Android Debug Bridge命令介绍[转]
Android Debug Bridge命令介绍 Android Debug Bridge的一些基本命令.这个工具直译过来就是Android调试桥的意思.它提供了强大的特性,例如复制文件到设备或从设备 ...
- ceph部署手册
CentOS7.2部署Luminous版Ceph-12.2.0 在CentOS7.2上安装部署Luminous版Ceph-12.2.0.由于ceph的Luminous版本默认使用bluestore作为 ...
- python进行爬虫
使用python进行网络爬虫 非结构画数据 转为 结构化数据.需要借助ETL(数据抽取,转换,存储)进行. 非结构化数据蕴含着丰富的价值.需要借助ETL进行转换成结构化数据,才能变成有价值的数据.比如 ...
- Matlab练习——rpy2tr函数与自己实现的ZYX欧拉角的结果不同的问题
问题背景:在根据<机器人导论>这本书的Z-Y-X欧拉角原理用Matlab实现旋转矩阵求解时,发现与直接调用机器人工具箱中的rpy2tr()函数得出的结果并不相同. 首先:先检查自己写的函数 ...
- JAVA第五周 动手动脑
public class Example { int x = 3;//类的实例变量,初始化值为3 static int y = 4;//类的静态变量,初始化值为4 public static void ...
- mui-当使用addeleventlisener()方法绑定事件时选择器无法绑定事件
在mui中绑定事件不能用jQuery或mui(“#XX”)的形式选取某个元素,而是document.getelementbyid()的形式 mui(“#XX”)可以使用on方法绑定事件