isinstance() 与 issubclass():
isinstance():用于判断一个对象是否为一个类的实例
python中说一切皆对象,那么我们判断一个变量是否为某个数据类型的时候,就可以使用isinstance()
L = [1,2,3] print(isinstance(l,list)) #True #注:L是list这个类的一个实例对象,L=[1,2,3]的本质是L = list([1,2,3])
那么为什么使用isinstance(),而不是最容易想到的type()呢?
1.type() 与isinstance()的判断区别:
type()不会认为子类是一种父类类型,isinstance()会认为子类是一种父类类型。
class Mylist(list): def __init__(self, l): super().__init__() self.l = l L = Mylist([1, 2, 3, 4]) print(type(L) is list) print(isinstance(L, list)) #False #True #我们对内置类型(类)进行了扩展,Mylist实例化得到的对象应该也是list类型(它拥有list类产生对象的所有绑#定方法,但是用type()得到的结果却是False)
此外,新式类与经典类的type(),返回结果不同
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> class A:pass ... >>> class B:pass ... >>> print type(A()) <type 'instance'> >>> print type(B()) <type 'instance'>
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> class A:pass ... >>> class B:pass ... >>> print(type(A())) <class '__main__.A'> >>> print(type(B())) <class '__main__.B'>
2.python作为动态语言,在使用的时候不需要声明变量类型,使用type检测特定的类型对象,会破坏代码的灵活性....
issubclass():用于判断一个类是不是另一个类的子类
class People: pass class P(People): pass print(issubclass(P, People)) #True
反射:
概念:反射是指程序拥有访问,检测和修改自身状态和行为的一种能力
在python中的反射是指:可以通过字符串去操作对象的相关属性(类本身也是对象)
通过四个函数实现内省:hasattr(),getattr(),delattr(),setattr()
class People: country = 'china' def __init__(self, name, age): self.name = name self.age = age def func(self): print('1') p = People('bob', 23) print(People.country) #底层原理实际上是People.__dict__['country'] print(hasattr(p,'name')) #判断类或对象中有无某个属性(会按照继承查找顺序) print(getattr(p,'name')) #第三个参数不指定的情况下,属性不存在会报错 print(getattr(p,'a',None)) #不存在返回None
此外,用户可以通过input()输入字符串,来反射类内的属性(数据属性与函数属性),从而达到操作对象属性的效果
在模拟FTP传输中,我们可以根据用户的指令来反射server类中的方法
#settings配置文件 server_address = ('127.0.0.1',8080) #server端核心层伪代码 import struct import json import socketserver from conf import settings class MyServer(socketserver.BaseRequestHandler): def handle(self): while True: try: header_len = self.request.recv(4) # 接收报头的长度 if header_len == 0: break # 针对linux,客户端单方面退出后发空数据的场景 header = self.request.recv(struct.unpack('i', header_len)[0]) #接收包含指令信息的报头 header_dic = json.loads(header.decode('utf-8')) if hasattr(self, header_dic['cmd']): func = getattr(self, header_dic['cmd']) func(header_dic) except ConnectionResetError: break def upload(self,header_dic): pass def down(self,header_dic): pass def makdir(self,header_dic): pass def remove(self,header_dic): pass if __name__ == '__main__': obj = socketserver.ThreadingTCPServer \ (settings.server_address, MyServer, bind_and_activate=True) # 第三个参数可省略 obj.serve_forever() # 相当于建立连接循环