isinstance(obj,cls)判断obj是否是类 cls 的对象
class Foo(object):
pass
obj = Foo()
print(isinstance(obj, Foo)) #检查obj是否是类Foo的对象
--->True
isinstance(x,list)判断x是否是列表list
x=[] print(isinstance(x,list)) --->True
issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo(object):
pass
class Bar(Foo):
pass
print(issubclass(Bar, Foo)) #检查Bar类是否是Foo的派生类
--->True
二 反射
1 反射的概念
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领
域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现自省的函数
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
2.1 hasattr() 判断属性
hasattr(object,name)判断object中有没有一个name字符串对应的方法或属性
class People:
country='China'
def __init__(self,name):
self.name=name
p=People('egon')
print(p.__dict__)
--->{'name': 'egon'}
print(hasattr(p,'name')) #等同于print('name' in p.__dict__),检查对象p是否有“name”属性
--->True
print(hasattr(p,'name1213')) #等同于print('name1213' in p.__dict__),检查对象p是否有“name1213”属性
--->False
print(hasattr(p,'country')) #p.country,相当于查找p下是否有country
--->True
print(People.__dict__)
--->{'__module__': '__main__', 'country': 'China', '__init__': <function People.__init__ at 0x0000000002203A60>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
print(hasattr(People,'country')) #People.country,相当于查找People下是否有country
--->True
print(hasattr(People,'__init__')) #People.__init__,相当于查找People下是否有__init__
--->True
2.2 getattr() 获取属性
getattr(object, name, default=None) 获得对象object的‘name’的内存地址,name对应的方法或属性,结果返回object.name的值
当object.name不存在时,不会报错,自动返回第三个参数
class People:
country='China'
def __init__(self,name):
self.name=name
def walk(self):
print('%s is walking' %self.name)
p=People('egon')
res=getattr(p,'country') #相当于res=p.country
print(res)
--->China
f=getattr(p,'walk') #相当于f=p.walk
print(f)
---><bound method People.walk of <__main__.People object at 0x00000000027CDC50>>
f1=getattr(People,'walk') #相当于f1=People.walk
print(f1)
---><function People.walk at 0x00000000027CF048>
f() #对象的绑定方法运行
--->egon is walking
f1(p) #类的函数运行
--->egon is walking
print(p.xxxxxxx) #输入不存在的数据属性或方法,报错
--->AttributeError: 'People' object has no attribute 'xxxxxxx'
print(getattr(p,'xxxxxxxx'))
--->AttributeError: 'People' object has no attribute 'xxxxxxx'
print(getattr(p,'xxxxxxxx','这个属性确实不存在')) #属性不存在时,getattr自动返回第三个参数
--->这个属性确实不存在
一般hasattr与getattr配合使用
class People:
country='China'
def __init__(self,name):
self.name=name
#def walk(self):
#print('%s is walking' %self.name)
p=People('egon')
if hasattr(p, 'walf'): #避免查找p下的绑定方法walk报错
func = getattr(p,'walk')
func()
2.3 setattr() 设置属性或方法
setattr(object, name, value) 用于新增加或者修改对象object属性(等同与object.name = value)
class People:
country='China'
def __init__(self,name):
self.name=name
p=People('egon')
print(p.__dict__)
--->{'name': 'egon'}
p.sex='male' #新增属性
print(p.sex)
--->male
print(p.__dict__)
--->{'name': 'egon', 'sex': 'male'}
用setattr来实现
class People:
country='China'
def __init__(self,name):
self.name=name
p=People('egon')
print(p.__dict__)
--->{'name': 'egon'}
setattr(p,'age',18) #新增p的属性,p.age=18
print(p.__dict__)
--->{'name': 'egon', 'age': 18}
print(p.age)
--->18
#用getattr来实现
print(getattr(p,'age'))
--->18
2.4 delattr() 删除属性或方法
delattr(x, y) #删除对象属性(等同于del x.y)
class People:
country='China'
def __init__(self,name):
self.name=name
def walk(self):
print('%s is walking' %self.name)
p=People('egon')
print(p.__dict__)
--->{'name': 'egon'}
del p.name
print(p.__dict__)
--->{}
#用delattar
print(p.__dict__)
--->{'name': 'egon'}
delattr(p,'name')
print(p.__dict__)
--->{}
以上反射的四种方法应用
四个方法的使用演示
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') #获取类的'staticField'属性
--->old boy
print getattr(Foo, 'func') #获取类的'func'属性
---><function Foo.func at 0x0000018156FBB950>
print getattr(Foo, 'bar') #获取类的'bar'属性
---><function Foo.bar at 0x00000192D2AFB9D8>
class Foo:
x=1
def __init__(self,name):
self.name=name
def walk(self):
print('walking......')
print(Foo.__dict__)
--->{'__module__': '__main__', 'x': 1, '__init__': <function Foo.__init__ at 0x0000000001E7F048>, 'walk': <function Foo.walk at 0x0000000001E7F2F0>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
print('x' in Foo.__dict__)
--->True
print(hasattr(Foo,'x')) #等同于print('x' in Foo.__dict__)
--->True
print(Foo.__dict__['x'] )
--->1
print(getattr(Foo,'x')) #等同于print(Foo.x)
--->1
print(Foo.x)
--->1
反射当前模块成员
#反射当前模块的属性
import sys
x=1111
class Foo:
pass
def s1():
print('s1')
def s2():
print('s2')
print(__name__)
--->__main__
this_module = sys.modules[__name__]
print(this_module) #this_module = sys.modules[__name__]以上是被调用的模块内容,输出的结果是被调用模块的文件路径
---> <module '__main__' from 'E:/python教学视频/Python fullstack s4 基础篇-day31/day31/test.py'>
print(hasattr(this_module, 's1'))
--->True
print(getattr(this_module, 's2')) #等同于print(this_module.s2)
---><function s2 at 0x00000000027EF048>
print(this_module.s2)
---><function s2 at 0x0000000001E73A60>
print(this_module.s1)
---><function s1 at 0x0000000001D28048>
反射的应用
#普通情况下
def add():
print('add')
def change():
print('change')
def search():
print('search')
def delete():
print('delete')
func_dic={
'add':add,
'change':change,
'search':search,
'delete':delete
}
while True:
cmd=input('>>:').strip()
if not cmd:continue
if cmd in func_dic: #hasattr()
func=func_dic.get(cmd) #func=getattr()
func()
#使用反射
import sys
def add():
print('add')
def change():
print('change')
def search():
print('search')
def delete():
print('delete')
this_module=sys.modules[__name__]
while True:
cmd=input('>>:').strip()
if not cmd:continue
if hasattr(this_module,cmd):
func=getattr(this_module,cmd)
func()
#以上减少了代码func_dic字典的定义,直接可以使用函数add,change,search,delete的功能,减少了代码量,更加简单清晰
导入其他模块,利用反射查找该模块是否存在某个方法
导入test这个模块,在test1.py中查找test是否存在某些方法
1 #反射当前模块的属性 2 import sys 3 4 x=1111 5 class Foo: 6 pass 7 def s1(): 8 print('s1') 9 10 def s2(): 11 print('s2') 12 13 print(__name__) 14 --->__main__ 15 16 this_module = sys.modules[__name__] 17 print(this_module) #this_module = sys.modules[__name__]以上是被调用的模块内容,输出的结果是被调用模块的文件路径 18 ---> <module '__main__' from 'E:/python教学视频/Python fullstack s4 基础篇-day31/day31/test.py'> 19 20 print(hasattr(this_module, 's1')) 21 --->True 22 23 print(getattr(this_module, 's2')) #等同于print(this_module.s2) 24 ---><function s2 at 0x00000000027EF048> 25 26 print(this_module.s2) 27 ---><function s2 at 0x0000000001E73A60> 28 29 print(this_module.s1) 30 ---><function s1 at 0x0000000001D28048>