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 ...
随机推荐
- Sass 基本函数
Sass 中的常用函数 一.字符串函数 1. unquote($string): 删除字符串前后的引号,删除一对引号,如果这个字符串没有带有引号,将返回原始的字符串. 示例: .text1 { con ...
- 基本控件文档-UISegment属性----iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...
- 【洛谷 P5110】 块速递推(矩阵加速,分块打表)
题目链接 掌握了分块打表法了.原来以前一直想错了... 块的大小\(size=\sqrt n\),每隔\(size\)个数打一个表,还要在\(0\text{~}size-1\)每个数打一个表. 然后就 ...
- Bower A package manager for the web
Bower can manage components that contain HTML, CSS, JavaScript, fonts or even image files. Bower doe ...
- $.on方法与$.click()的区别
1.$.on("click") 支持动态元素绑定事件,该事件是绑定到document上,只要符合条件的元素即可绑定事件,同时$.on()可以绑定多个事件 on方法 on(event ...
- 【Python项目】使用Face++的人脸识别detect API进行本地图片情绪识别并存入excel
准备工作 首先,需要在Face++的主页注册一个账号,在控制台去获取API Key和API Secret. 然后在本地文件夹准备好要进行情绪识别的图片/相片. 代码 介绍下所使用的第三方库 ——url ...
- HTML综合实例【月福首页】
1. 首页的布局结构 2. 排版的准备工作 网站的素材:与当前网页放在一起. 创建一个html文件,来进行排版. 网页的背景色 确定主页的宽度:778px 3. HTML注释 <!-- 注释内容 ...
- python基础===如何优雅的写代码(转自网络)
本文是Raymond Hettinger在2013年美国PyCon演讲的笔记(视频, 幻灯片). 示例代码和引用的语录都来自Raymond的演讲.这是我按我的理解整理出来的,希望你们理解起来跟我一样顺 ...
- tcp 在调用connect失败后要不要重新socket
tcp 在调用connect失败后要不要重新socket http://blog.csdn.net/occupy8/article/details/48253251
- 使用UpdatePanel时FileUpload失效的问题
出处:http://www.cnblogs.com/caicainiao/archive/2010/12/08/1900377.html 1.使用UpdatePanel后,FileUpload的Has ...