issubclass() 以及instance() 用法
issubclass() #判断第一个类是不是第二个类的子类,返回true或者false
class Foo:
pass
class Bar(Foo):
pass
class Tt(Bar):
pass
print(Bar.__bases__)
print(issubclass(Bar,Foo))
print(issubclass(Tt,object))
#
(<class '__main__.Foo'>,)
True
True
isinstance() 判断第一个参数是不是第二个参数的对象,返回true或者false
class Foo:
pass
class Tt():
pass
f=Foo()
print(isinstance(f,Foo))
print(isinstance(f,Tt))
#
True
False
反射
1.反射就是通过字符串操作来操作字符串的相关属性,主要以下四个函数
getattr() # 获取对象中的属性或方法
import os
print(getattr(os,'path'))
<module 'ntpath' from 'F:\python\lib\ntpath.py'>
hasattr() #判断对象中是否有该属性或者方法(属性或方法用字符串表示)
import os
print(hasattr(os,'path')) #判断了模块Os模块中有没有属性·path
# True
delatter() #删除对象中的属性和方法
class AS :
pass
a=AS()
setattr(a,'age','wwb')
print(a.age) # 表示添加成功wwb
print(a.__dict__) #{'age': 'wwb'}
delattr(a,'age')
# print(a.age)
print(hasattr(a,'age')) # False 判断是age
setattr() # 向对象中设置属性和方法
class AS :
pass
a=AS()
setattr(a,'age','wwb')
print(a.age)
print(a.__dict__)
应用:利用反射查找该模块是否存在某个方法
"""
5 程序目录:
6 module_test.py
7 index.py
8
9 当前文件:
10 index.py
11 """
import module_test as obj
#obj.test()
print(hasattr(obj,'test'))
getattr(obj,'test')()
2.反射的好处
可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
# 我以为它写完了
utils.eat() # 这样获取该对象的方法,但是获取不到的话会报错
# 更安全
if hasattr(utils,'eat'):
eat=getattr(utils,'eat')
eat()
else:
print('那个人还没写完呢') # 这样先判断有没有,有了在获取,没有的话输出,这样更保险程序不会报错
内置方法(魔法方法)
1.__str__:如果不重写__str__ print打印会打印出内存地址#如果重写了,会打印出你想要的,也就是程序本来写好这个方法的,当你打印调用的话就会打印出本来写好的,就像内存地址
# 不重写内置方法的情况下
class Foo:
def __init__(self,name):
self.name=name
f=Foo('wwb')
print(f) # 相当于print(f.__str__())
#
# _main__.Foo object at 0x000001E4E51FDA58>
# 重写的情况下
class Foo:
def __init__(self,name):
self.name=name
def __str__(self):
return '['+self.name+']'
f=Foo('wwb')
print(f) # 相当于print(f.__str__())
#
#[nick]
l=[1,2,3]
# #本质也是调用list的__str__方法
print(l)
[1, 2, 3]
2.__repr__ 跟str类似,在交互式命令下直接写变量名,会执行__repr__
3.__setattr__,__delattr__,__getattr__(重要)
**点拦截方法
如果去对象中取属性,一旦取不到,会进入到__getattr__ (如果没有找到)**
class Foo:
def __init__(self,name):
self.name=name
def __getattr__(self, item): #
print('xxxx')
return '你傻逼啊,没有这个字段'
f=Foo('wwb')
print(f.name)
print(f.age)
print(f.__dict__)
#
wwb
xxxx
你傻逼啊,没有这个字段
{'name': 'wwb'}
如果去对象中赋值属性,一旦取不到,会进入到__setattr__
class Foo:
def __init__(self,name):
self.name=name
def __setattr__(self, key, value):
print('yyyyy')
f=Foo('wwb') # 赋值,在这个过程中会触发__setattr__
print(f.__dict__) # 因为没有触发系统的__setattr__,所以没有赋值成功
#
yyyyy
{}
如果删除对象中的属性,会进入__delattr__
class Foo:
def __init__(self,name):
self.name=name
def __delattr__(self, item):
print('zzzzz')
f=Foo('wwb')
del f.name
print(f.__dict__) # 因为没有进入系统的__delattr__,所以没有删除成功
#
zzzzz
{'name': 'wwb'}