isinstance(obj,Foo) javascript
x = [] print(isinstance(x,list))
结果:
Truecss
class Foo:
pass
class Bar(Foo):
pass
print(issubclass(Bar,Foo))
结果:
Truehtml
经过下面的方式也能够查看
print(Bar.__bases__) java
反射是Smi首次提出的,主要指程序能够访问、检测和修改它自己状态行为的一种能力,也能够叫作自省node
面向对象中的反射,是经过字符串形式操做对象的属性,Python中一切都是对象,均可以使用对象python
Python中经过hasattr、getattr、setattr、deltattr实现自省的函数,适用于类和对象(一切都是对象)git
反射就是把字符串反射成相应的命令github
查看类和对象中是否有name,用字符串表示,实例在找的时候首先从自身找,自身没有从类找。web
class Foo:
name = 'aaa'
f1 =Foo()
print(hasattr(Foo,'name'))
print(hasattr(f1,'name'))
结果:
True
Trueajax
setattr是设置属性,setattr(x,y,z)
class Foo:
name = 'aaa'
f1 =Foo()
setattr(Foo,'age',18)
print(Foo,'age')
print(f1,'age')
print(Foo.__dict__)
delattr(Foo,'name')
print(Foo.__dict__)
print(hasattr(f1,'name'))
结果:
False
经过打印类的名称空间能够查看到name已经没有了
getattr是查找那个属性,并把命名它的值得到,实际的原理是经过得到字典中的key,而后得到value
class People:
country = 'china'
def __init__(self,name):
self.name=name
p = People('aaa')
print(hasattr(p,'name'))
print('name' in p.__dict__) # 执行的效果是同样的e
print(hasattr(p,'country'))
print(hasattr(People,'country'))
print(getattr(p,'country'))
print(getattr(p,'__init__'))
print(getattr(People,'country'))
Python中一切皆对象,模块文件等都是对象
import sys
def s1():
pass
def s2():
pass
this_module = sys.modules[__name__]
print(hasattr(this_module,'s1'))
print(getattr(this_module,'s1'))
function s1 at 0x00000000005F3E18
能够事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这实际上是一种‘后期绑定’,什么意思?即你能够事先把主要的逻辑写好(只定义接口),而后后期再去实现接口的功能
# 第一我的负责的代码 class FtpClient: def __init__(self,addr): print("正在链接服务器%s" % addr) self.addr = addr # 第二我的引用的代码 f1 = FtpClient("192.168.0.1") if hasattr(f1, 'get'): func = getattr(f1, 'get') func() else: print("不存在此方法") print("处理其余逻辑")
第一我的的代码只提供了接口,并无写完,可是第二我的要用第一我的的代码中,经过自省进行判断,后面的人就能够直接拿来用了
动态导入模块(基于反射当前模块成员)
getattr只有在调用的属性不存在的时候才会触发
class Foo:
def __init__(self,name):
self.name = name
def __getattr__(self, item):
print("getattr--%s %s"%(item,type(item)))
f = Foo('aaa')
print(f.xxx)
setattr添加/修改属性会触发它的执行
class Foo:
def __init__(self,x):
self.name=x
def __setattr__(self, key, value): # 与上面的对应关系是self--self,name--key,x--value
self.__dict__[key]=value # 真正修改的是__dict__中的内容
f1 = Foo('aaa')
f1.x='bbb' # 修改属性
f1.age=18 # 增长属性
print(f1.__dict__) # 在名称对象的名称空间中能够显示
只有删除属性的时候才会触发deltatr的执行
class Foo:
def __init__(self,x):
self.name=x
def __setattr__(self, key, value): # 与上面的对应关系是self--self,name--key,x--value
self.__dict__[key]=value # 真正修改的是__dict__中的内容
def __delattr__(self, item):
self.__dict__.pop(item)
f1=Foo('aaa')
print(f1.__dict__)
del f1.name
print(f1.__dict__)
结果:
{‘name’: ‘aaa’}
{}
#客户端
class FtpClient:
def __init__(self,addr):
print('正在链接服务器[%s]'%addr)
self.addr = addr
def get(self):
print('get')
def test(self):
print('test')
#服务端,须要使用客户端的内容
import ftpclient # 导入test模块(这里是文件)
# f1 = FtpClient('192.168.1.1') # wrong
f1=ftpclient.FtpClient('192.168.1.1') #这里的对象是文件,即ftpclient,对这个对象进行实例化
if hasattr(f1,'get'): # 首先看是否有这个功能
func_get=getattr(f1,'get') # getattr是得到相应的内存地址
func_get()
else: # else预语言中是真正的逻辑
print('其余逻辑')
m = input("输入你要导入的模块")
m1 = __import__(m)
print(m1)
import importlib
t = importlib.import_module('time')
print(t.time)
Python内部已经有了标准的数据类型和内置方法,可是在不少的状况下,咱们须要对数据类型进行本身定制,这几用到了继承和派生的知识
对append添加限制,只能添加数字类型的
class List(list): # List 继承了列表list
def append(self, p_object): # 仅仅对append进行修改
if not isinstance(p_object,int): # 限制数据类型
raise TypeError('must be int')
super().append(p_object) # 真正的修改,super是对父类进行修改
l = list([1,2,3])
print(l)
l.append(4) # 这里是对属性进行修改,实际是对类进行修改
print(l)
结果:
[1, 2, 3]
[1, 2, 3, 4]
上面的状况仅仅是对append进行了修改并添加了限制,list的其余的属性如insert是没有限制的
受权是包装的一个特性,上面的状况是经过继承来实现的,可是函数是不能继承的
受权的过程是全部更新的功能都是由新类的某部分来处理,已经存在的就受权给对象的默认属性
实现受权的关键点就是覆盖getattr方法
import time
class Open:
def __init__(self,filepath,mode='r',encoding='utf-8'):
self.x = open(filepath,mode=mode,encoding=encoding) # self.x是文件句柄 拿到文件中的内容
self.filepath=filepath
self.mode=mode
self.encoding=encoding
def write(self,line): # 在类中新建write功能
t=time.strftime('%Y-%m-%d %X')
self.x.write("%s %s" %(t,line)) # self.x存放的是文件句柄
def __getattr__(self, item): # 经过getattr实现的叫作受权
# print('---->',item,type(item)) # 测试查看类型
return getattr(self.x,item) # 从一个文件对象得到 字符串 如今得到的是self.x 相应方法的地址
f=Open('b.txt','w') #实例化一个对象 传入相应的参数
f.write('123\n') #Open没有实际的writearttribute
f.write('123\n')
f.write('123\n')
f.write('123\n')
f.write('123\n')
f.write('123\n')
f.write('123\n')
这样就能在文件中添加了带有时间的内容
对文件进行读操做:
f=Open('b.txt','r') # 从新实例化
res = f.read()# f.read实际是self.x 的方法
print(res)
f.seek(0) #此时光标位于文件的最后
print(f.read()) #这样就能够从新读文件