Python开发基础-Day22反射、面向对象进阶
isinstance(obj,cls)和issubclass(sub,super)
isinstance(obj,cls)检查是否obj是否是类 cls 的对象,如果是返回True
class Foo(object):
pass
obj = Foo()
print(isinstance(obj, Foo))
issubclass(sub, super)检查sub类是否是 super 类的派生类,如果是返回True
class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo)
反射
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。而python中的一切事物都是对象,即都可以使用反射。
示例代码:
class Teacher:
school='jialidun'
def __init__(self,name,age):
self.name=name
self.age=age
def teach(self):
print('%s teach' %self.name)
通过字符串的方式判断是否存在一个属性:
t=Teacher('bob',18)
print(hasattr(Teacher,'name')) #False
print(hasattr(Teacher,'school')) #True
print(hasattr(Teacher,'teach')) #True
print(hasattr(t,'name')) #True
print(hasattr(t,'school')) #True
print(hasattr(t,'teach')) #True
通过字符串的方式获取一个属性:
print(getattr(Teacher,'school')) #获取到则返回属性的值
print(getattr(Teacher,'sdfad',None)) #获取不到返回None,如果不指定None那么抛出异常错误
通过字符串的方式设定一个属性:
setattr(Teacher,'sex','male') #设定Teacher类的属性sex='male'
setattr(t,'sex','female') #设定对象t对象的属性sex='female'
print(Teacher.__dict__)
print(t.__dict__)
通过字符串的方式删除一个属性:
delattr(Teacher,'sex')
delattr(t,'sex')
反射应用场景:用户交互
class Cmd:
def __init__(self,name):
self.name=name
def run(self):
while True:
cmd=input('>>>').strip()
if not cmd:continue
if hasattr(self,cmd): #判断这个类包含不包含输入的属性
func=getattr(self,cmd) #如果包含,获取该属性
func() #执行该属性(输入name会抛错提示字符串不能被调用,因为name是一个数据属性,而非函数属性)
else:
print('not valid func')
def ls(self):
print('ls function')
def pwd(self):
print('pwd function')
def cat(self):
print('cat function')
c=Cmd('bob')
c.run()
反射的好处
实现可插拔机制:可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,即可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
动态导入模块:基于反射当前模块成员
__str__方法
改变对象的字符串显示
class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
t=Teacher('bob',18)
print(t)
输出结果
<__main__.Teacher object at 0x0000020FC4DA9278> #########分割线君########### class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '<name:%s age:%s>' % (self.name, self.age)
t=Teacher('bob',18)
print(t) #t.__str__()
输出结果:类中的__str__函数的执行结果
<name:bob age:18>
__del__方法
在程序执行完了之后会自动执行的内容
class Foo:
def __init__(self,x):
self.x=x
def __del__(self):
print('执行__del__')
'''一般用来做一些关于对象执行完了之后剩下的垃圾的清理操作'''
f=Foo(10)
print('执行完了') 输出结果:先执行最后的print,没有代码了执行__del__函数
执行完了
执行__del__
删除对象后立即执行的内容
class Foo:
def __init__(self,x):
self.x=x
def __del__(self):
print('执行__del__')
'''做一些关于对象的清理操作'''
f=Foo(10)
del f #删除的时候也会执行del内容
print('执行完了') 输出结果:删除了f对象后执行了__del__后才执行最后的print
执行__del__
执行完了
item系列
以中括号的方式进行处理类似于:
l=['a','b','c']
dic={'a':1}
print(l[1])
print(dic['a'])
__getitem__、__setitem__、__delitem__
class Teacher:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def __getitem__(self, item): #查询
# return getattr(self,item)
return self.__dict__[item]
def __setitem__(self, key, value): #设置
# setattr(self,key,value)
self.__dict__[key]=value
def __delitem__(self, key): #删除
# delattr(self,key)
self.__dict__.pop(key)
f=Teacher('bob',18,'male')
print(f.name) #f['name']
print(f['name']) #查询
f['name']='bob_nb' #设置
print(f.__dict__)
del f['name'] #删除
print(f.__dict__)
__len__方法
给对象提供len()统计方法
class Teacher:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def __len__(self): #长度设置为10
return 10
f=Teacher('bob',18,'male')
print(len(f)) #输出10
其他方法(补充)
__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): #限制赋值,无法对属性直接赋值,必须要对__dict__进行操作赋值
print('----> from setattr')
# self.key=value #这就无限递归了,任何赋值操作都会调用__setattr__的运行,所以....
# self.__dict__[key]=value #应该使用这种方式,操作字典可以赋值成功
def __delattr__(self, item):
print('----> from delattr')
# del self.item #无限递归了,同__setattr__方法的无限递归
self.__dict__.pop(item)
#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
f1.__setattr__('a',1) #不是直接操作字典,无法赋值
print(f1.__dict__) # 因为重写了__setattr__,凡是赋值操作都会触发它的运行,什么都不写,就是根本没赋值,除非直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)
#__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a #删除的时候如果上面函数是del self.item,会无限递归
print(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]
授权
待补充
Python开发基础-Day22反射、面向对象进阶的更多相关文章
- 还在用Alpine作为你Docker的Python开发基础镜像?其实Ubuntu更好一点
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_173 一般情况下,当你想为你的Python开发环境选择一个基础镜像时,大多数人都会选择Alpine,为什么?因为它太小了,仅仅只有 ...
- python基础-9.1 面向对象进阶 super 类对象成员 类属性 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理
上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...
- Python开发基础-Day17面向对象编程介绍、类和对象
面向对象变成介绍 面向过程编程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西.主要应用在一旦完成很少修改的地方,如linux ...
- python开发基础之语法基础
一.知识点 (一)python介绍 1.Python被设计成一种高可读性的语言,它大量地使用了英语单词作为关键字,不像其他语言使用标点符号构成复杂的语法结构. 2.Pyton是支持面向对象的,支持在对 ...
- Python开发基础-Day31 Event对象、队列和多进程基础
Event对象 用于线程间通信,即程序中的其一个线程需要通过判断某个线程的状态来确定自己下一步的操作,就用到了event对象 event对象默认为假(Flase),即遇到event对象在等待就阻塞线程 ...
- Python开发基础-Day23try异常处理、socket套接字基础1
异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解 ...
- Python全栈day26-27(面向对象进阶)
参考 http://www.cnblogs.com/linhaifeng/articles/6204014.html 1,什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访 ...
- Python学习之路10☞面向对象进阶
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(objec ...
- Python开发基础之Python常用的数据类型
一.Python介绍 Python是一种动态解释型的编程语言.Python它简单易学.功能强大.支持面向对象.函数式编程,可以在Windows.Linux等多种操作系统上使用,同时Python可以在J ...
随机推荐
- PHP网页架站
目前,Windows下已经有集成的PHP网页架站工具,例如:AppServ.WampServer.这些软件将Apache.PHP.MySQL.phpMyAdmin集成到一起,极大地方便了开发者架站.但 ...
- bzoj 1261 区间DP
首先我们知道ans=Σ(h[i]*f[i])=Σ(h[i]*d[i])/s=Σ(k(r[i]+1)+c)*d[i]/s=Σ(k*r[i]+(k+c))*d[i]/s 我们可以发现,除了k*r[i]之外 ...
- Kill windows和linux 进程
Windows
- 计算机网络课设之基于UDP协议的简易聊天机器人
前言:2017年6月份计算机网络的课设任务,在同学的帮助和自学下基本搞懂了,基于UDP协议的基本聊天的实现方法.实现起来很简单,原理也很简单,主要是由于老师必须要求使用C语言来写,所以特别麻烦,而且C ...
- C++转换构造函数和隐式转换函数 ~ 转载
原文地址: C++转换构造函数和隐式转换函数 用转换构造函数可以将一个指定类型的数据转换为类的对象.但是不能反过来将一个类的对象转换为一个其他类型的数据(例如将一个Complex类对象转换成doubl ...
- centos7系统安装配置
下载centos7 iso镜像 电脑里面本来有ubuntu系统,直接在u盘做好启动盘安装即可,选择手动分区(忘了),将原本ubuntu系统分区压缩200G.系统不要选择最小化,选择gnome的图形界面 ...
- ioctl( ) 函数
ioctl( )函数 本函数影响由fd参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void ...
- 64_l6
lightdm-qt5-devel-1.22.0-1.fc26.i686.rpm 19-May-2017 11:11 22854 lightdm-qt5-devel-1.22.0-1.fc26.x86 ...
- Django2.0如何配置urls文件
刚开始学django,创建的第一个工程无法启动,后来发现是由于教程是针对较低版本的Django,我用的是Django2.0和Python3.6,两个都是发文为止的最新版本,urls文件设置方法和旧版本 ...
- C后端设计开发 - 第3章-气功-原子锁线程协程
正文 第3章-气功-原子锁线程协程 后记 如果有错误, 欢迎指正. 有好的补充, 和疑问欢迎交流, 一块提高. 在此谢谢大家了. 童话镇 - http://music.163.com/#/m/song ...