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基础之反射、面向对象进阶的更多相关文章

  1. python基础-9.1 面向对象进阶 super 类对象成员 类属性 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

    上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...

  2. Python 基础 三 反射

    Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ...

  3. python基础-9__import__ 反射和面向对象基础 self 封装 继承(多继承顺序) 多态

    一 反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...

  4. python(24)- 面向对象进阶

    面向对象基础知识: 1.面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用: 2.类是一个模板,模板中包装了多个‘函数’供使用(可以将多函数中公用的变量封装到对象中): 3.对象,根据模板 ...

  5. python基础(14)-反射&类的内置函数

    反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...

  6. Python基础之反射

    python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删除成员. ...

  7. python基础语法17 面向对象4 多态,抽象类,鸭子类型,绑定方法classmethod与staticmethod,isinstance与issubclass,反射

    多态 1.什么是多态? 多态指的是同一种类型的事物,不同的形态. 2.多态的目的: “多态” 也称之为 “多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字). 多 ...

  8. python基础整理4——面向对象装饰器惰性器及高级模块

    面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...

  9. Python基础之面对对象进阶

    阅读目录 isinstance和issubclass 反射 setattr delattr getattr hasattr __str__和__repr__ __del__ item系列 __geti ...

随机推荐

  1. June 15th 2017 Week 24th Thursday

    Whatever is worth doing is worth doing well. 任何值得做的,就把它做好. Whatever is worth doing is worth doing we ...

  2. Kubernetes API server工作原理

    作为Kubernetes的使用者,每天用得最多的命令就是kubectl XXX了. kubectl其实就是一个控制台,主要提供的功能: 1. 提供Kubernetes集群管理的REST API接口,包 ...

  3. PHP Swoole 基于纯真IP库根据IP匹配城市

    把纯真IP库读到内存,纯真IP库本来就是有序的,然后每次请求二分查找就行,44WIP查找十几次就搞定了 dispatch_mode最好写3,不然做服务的时候,会导致进程任务分配不均匀. max_req ...

  4. userdel

    功能说明:用于删除指定的用户及该用户相关的文件. 参数选项:-f 强制删除用户,即使用户当前已登录.-r 删除用户的同时,删除与用户相关的所有文件. 说明:尽量不要用userdel删除用户,而是采用在 ...

  5. Android(java)学习笔记27:TextView属性大全

    TextView属性大全: android:autoLink       设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web/email/ph ...

  6. Hive创建外部表以及分区

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/sheismylife/article/details/27874943 创建带分区的外部表 创建外部 ...

  7. POJ Widget Factory 【求解模线性方程】

    传送门:http://poj.org/problem?id=2947 Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Su ...

  8. Codeforces Round #515 (Div. 3) B. Heaters【 贪心 区间合并细节 】

    任意门:http://codeforces.com/contest/1066/problem/B B. Heaters time limit per test 1 second memory limi ...

  9. 去掉video视频播放器下的下载按钮

    去掉video视频播放器下的下载按钮: video::-internal-media-controls-download-button { display:none; } video::-webkit ...

  10. 1..net转java背景介绍

    注册博客2年了.从注册就开始接触.net.以前也有想过转java.只是没想过会这么快. .net语法这么优美好用.可惜了生态环境. .net还没有学成大神.就要离开了. 公司有个项目要用java.在加 ...