python基础之反射、面向对象进阶
isinstance(obj,cls)和issubclass(sub,super)
isinstance(obj,cls)检查是否obj是否是类 cls 的对象,如果是返回True
1 class Foo(object):
2 pass
3 obj = Foo()
4 print(isinstance(obj, Foo))
issubclass(sub, super)检查sub类是否是 super 类的派生类,如果是返回True
1 class Foo(object):
2 pass
3 class Bar(Foo):
4 pass
5 issubclass(Bar, Foo)
反射
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。而python中的一切事物都是对象,即都可以使用反射。
示例代码:
1 class Teacher:
2 school='jialidun'
3 def __init__(self,name,age):
4 self.name=name
5 self.age=age
6 def teach(self):
7 print('%s teach' %self.name)
通过字符串的方式判断是否存在一个属性:
1 t=Teacher('bob',18)
2 print(hasattr(Teacher,'name'))  #False
3 print(hasattr(Teacher,'school'))    #True
4 print(hasattr(Teacher,'teach'))     #True
5 print(hasattr(t,'name'))  #True
6 print(hasattr(t,'school'))    #True
7 print(hasattr(t,'teach'))     #True
通过字符串的方式获取一个属性:
1 print(getattr(Teacher,'school')) #获取到则返回属性的值
2 print(getattr(Teacher,'sdfad',None)) #获取不到返回None,如果不指定None那么抛出异常错误
通过字符串的方式设定一个属性:
1 setattr(Teacher,'sex','male') #设定Teacher类的属性sex='male'
2 setattr(t,'sex','female') #设定对象t对象的属性sex='female'
3 print(Teacher.__dict__)
4 print(t.__dict__)
通过字符串的方式删除一个属性:
1 delattr(Teacher,'sex')
2 delattr(t,'sex')
反射应用场景:用户交互
1 class Cmd:
2 def __init__(self,name):
3 self.name=name
4 def run(self):
5 while True:
6 cmd=input('>>>').strip()
7 if not cmd:continue
8 if hasattr(self,cmd): #判断这个类包含不包含输入的属性
9 func=getattr(self,cmd) #如果包含,获取该属性
10 func() #执行该属性(输入name会抛错提示字符串不能被调用,因为name是一个数据属性,而非函数属性)
11 else:
12 print('not valid func')
13 def ls(self):
14 print('ls function')
15 def pwd(self):
16 print('pwd function')
17 def cat(self):
18 print('cat function')
19 c=Cmd('bob')
20 c.run()
反射的好处
实现可插拔机制:可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,即可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
动态导入模块:基于反射当前模块成员
__str__方法
改变对象的字符串显示
1 class Teacher:
2 def __init__(self,name,age):
3 self.name=name
4 self.age=age
5 t=Teacher('bob',18)
6 print(t)
7 输出结果
8 <__main__.Teacher object at 0x0000020FC4DA9278>
9
10 #########分割线君###########
11
12 class Teacher:
13 def __init__(self,name,age):
14 self.name=name
15 self.age=age
16 def __str__(self):
17 return '<name:%s age:%s>' % (self.name, self.age)
18 t=Teacher('bob',18)
19 print(t) #t.__str__()
20 输出结果:类中的__str__函数的执行结果
21 <name:bob age:18>
__del__方法
在程序执行完了之后会自动执行的内容
1 class Foo:
2 def __init__(self,x):
3 self.x=x
4 def __del__(self):
5 print('执行__del__')
6 '''一般用来做一些关于对象执行完了之后剩下的垃圾的清理操作'''
7 f=Foo(10)
8 print('执行完了')
9
10 输出结果:先执行最后的print,没有代码了执行__del__函数
11 执行完了
12 执行__del__
删除对象后立即执行的内容
1 class Foo:
2 def __init__(self,x):
3 self.x=x
4 def __del__(self):
5 print('执行__del__')
6 '''做一些关于对象的清理操作'''
7 f=Foo(10)
8 del f #删除的时候也会执行del内容
9 print('执行完了')
10
11 输出结果:删除了f对象后执行了__del__后才执行最后的print
12 执行__del__
13 执行完了
item系列
以中括号的方式进行处理类似于:
1 l=['a','b','c']
2 dic={'a':1}
3 print(l[1])
4 print(dic['a'])
__getitem__、__setitem__、__delitem__
1 class Teacher:
2 def __init__(self,name,age,sex):
3 self.name=name
4 self.age=age
5 self.sex=sex
6 def __getitem__(self, item): #查询
7 # return getattr(self,item)
8 return self.__dict__[item]
9 def __setitem__(self, key, value): #设置
10 # setattr(self,key,value)
11 self.__dict__[key]=value
12 def __delitem__(self, key): #删除
13 # delattr(self,key)
14 self.__dict__.pop(key)
15 f=Teacher('bob',18,'male')
16 print(f.name) #f['name']
17 print(f['name']) #查询
18 f['name']='bob_nb' #设置
19 print(f.__dict__)
20 del f['name'] #删除
21 print(f.__dict__)
__len__方法
给对象提供len()统计方法
1 class Teacher:
2 def __init__(self,name,age,sex):
3 self.name=name
4 self.age=age
5 self.sex=sex
6 def __len__(self): #长度设置为10
7 return 10
8 f=Teacher('bob',18,'male')
9 print(len(f)) #输出10
其他方法(补充)
__setattr__,__delattr__,__getattr__方法
1 class Foo:
2 x=1
3 def __init__(self,y):
4 self.y=y
5 def __getattr__(self, item):
6 print('----> from getattr:你找的属性不存在')
7 def __setattr__(self, key, value): #限制赋值,无法对属性直接赋值,必须要对__dict__进行操作赋值
8 print('----> from setattr')
9 # self.key=value #这就无限递归了,任何赋值操作都会调用__setattr__的运行,所以....
10 # self.__dict__[key]=value #应该使用这种方式,操作字典可以赋值成功
11 def __delattr__(self, item):
12 print('----> from delattr')
13 # del self.item #无限递归了,同__setattr__方法的无限递归
14 self.__dict__.pop(item)
15 #__setattr__添加/修改属性会触发它的执行
16 f1=Foo(10)
17 f1.__setattr__('a',1) #不是直接操作字典,无法赋值
18 print(f1.__dict__) # 因为重写了__setattr__,凡是赋值操作都会触发它的运行,什么都不写,就是根本没赋值,除非直接操作属性字典,否则永远无法赋值
19 f1.z=3
20 print(f1.__dict__)
21 #__delattr__删除属性的时候会触发
22 f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
23 del f1.a #删除的时候如果上面函数是del self.item,会无限递归
24 print(f1.__dict__)
25
26 #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
27 f1.xxxxxx
包装(对标准数据类型进行方法修改)
通过继承和派生的方式,进行修改源生数据类型的方法
1 class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid
2 def append(self, p_object):
3 '派生自己的append:加上类型检查'
4 if not isinstance(p_object,int):
5 raise TypeError('must be int')
6 super().append(p_object)
7 @property
8 def mid(self):
9 '新增自己的属性'
10 index=len(self)//2
11 return self[index]
python基础之反射、面向对象进阶的更多相关文章
- python基础-9.1 面向对象进阶 super 类对象成员 类属性 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理
		上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ... 
- Python 基础 三 反射
		Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ... 
- python基础-9__import__ 反射和面向对象基础 self 封装 继承(多继承顺序) 多态
		一 反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ... 
- python(24)- 面向对象进阶
		面向对象基础知识: 1.面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用: 2.类是一个模板,模板中包装了多个‘函数’供使用(可以将多函数中公用的变量封装到对象中): 3.对象,根据模板 ... 
- python基础(14)-反射&类的内置函数
		反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ... 
- Python基础之反射
		python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删除成员. ... 
- python基础语法17 面向对象4 多态,抽象类,鸭子类型,绑定方法classmethod与staticmethod,isinstance与issubclass,反射
		多态 1.什么是多态? 多态指的是同一种类型的事物,不同的形态. 2.多态的目的: “多态” 也称之为 “多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字). 多 ... 
- python基础整理4——面向对象装饰器惰性器及高级模块
		面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ... 
- Python基础之面对对象进阶
		阅读目录 isinstance和issubclass 反射 setattr delattr getattr hasattr __str__和__repr__ __del__ item系列 __geti ... 
随机推荐
- ZT onActivityResult在android中的用法
			onActivityResult在android中的用法 举例说我想要做的一个事情是,在一个主界面(主Activity)上能连接往许多不同子功能模块(子Activity上去),当子模块的事情做完之后就 ... 
- std::string::find_last_not_of
			public member function <string> std::string::find_last_not_of C++98 C++11 string (1) size_t fi ... 
- Kubernetes Helm入门指南
			什么是Helm?这可不是暗黑破坏神里装备的名称:头盔,而是Kubernetes的一个包管理工具,用来简化Kubernetes应用的部署和管理.我们Helm和Kubernetes的关系,我们可以理解成y ... 
- IOS CoreData的(增删查改)
			(1).CoreDataa>什么是CoreDatab>CoreData增删改查 "什么时候使用COredata 什么时候使用FMDatabases"CoreData 在 ... 
- react中 props,state与render函数的关系
			我们很明显的能够感受到,react是一门数据驱动的框架,当数据发生变化,页面就会自动发生变化,他背后的原理是怎么样子的呢 比如todolist例子里面,inputValue变了,框里面的内容就会自动变 ... 
- RabbitMQ .NET Client 实战实验
			由于公司业务需求,最近想上RabbitMQ,之前我研究了一段时间微软的MSMQ.开源队列有很多,各有优劣.就先拿RabbitMQ练练手吧.本篇着重代码部分,至于怎么安装,怎么配置不在赘述.而且代码是在 ... 
- PAML学习一
			前言 模式识别起源于工程,而机器学习从计算机科学中产生.然而这两者被看做同一领域的两方面,过去十年里他们获得了极大的发展.特别是,贝叶斯方法已经发展成主流,而图模型已经被融入用于描述和应用概率模型的通 ... 
- Android学习笔记_20_访问应用权限汇总
			<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com. ... 
- HDU 1312  Red and Black(最简单也是最经典的搜索)
			传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1312 Red and Black Time Limit: 2000/1000 MS (Java/Oth ... 
- 用c#语言编写水仙花数
			using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ... 
