isinstance与issubclass

isinstance

在游戏项目中,我们会在每个接口验证客户端传过来的参数类型,如果验证不通过,返回给客户端“参数错误”错误码。

这样做不但便于调试,而且增加健壮性。因为客户端是可以作弊的,不要轻易相信客户端传过来的参数。

验证类型用type函数,非常好用,比如

print(type('foo') == str)
True
print(type(2.3) in (int, float))
True

既然有了type()来判断类型,为什么还有isinstance()呢?

一个明显的区别是在判断子类。

type()不会认为子类是一种父类类型;isinstance()会认为子类是一种父类类型。

千言不如一码。

class Foo(object):
pass class Bar(Foo):
pass print(type(Foo()) == Foo)
True
print(type(Bar()) == Foo)
False
# isinstance参数为对象和类
print(isinstance(Bar(),Foo))
True

需要注意的是,旧式类跟新式类的type()结果是不一样的。旧式类都是<type 'instance'>。

# python2.+
class A:
pass class B:
pass class C(object):
pass print('old style class',type(A())) # old style class <type 'instance'> print('old style class',type(B())) # old style class <type 'instance'> print('new style class',type(C())) # new style class <class '__main__.C'> print(type(A()) == type(B())) # True

注意:不存在说isinstance比type更好。只有哪个更适合需求。

issubclass

class Parent:
pass class Sub(Parent):
pass print(issubclass(Sub, Parent))
True
print(issubclass(Parent, object))
True

反射

定义

反射就是通过字符串来操作类或者对象的属性

  • 反射本质就是在使用内置函数,其中反射有以下四个内置函数:

    1. hasattr:判断一个方法是否存在与这个类中
    2. getattr:根据字符串去获取obj对象里的对应的方法的内存地址,加"()"括号即可执行
    3. setattr:通过setattr将外部的一个函数绑定到实例中
    4. delattr:删除一个实例或者类中的方法

栗子:

class Foo:
def __init__(self,name,sex):
self.name=name
self.sex=sex
def tucao(self,name):
return f'{name}疯狂吐槽'
def bianxing(self,sex):
self.sex=sex
f=Foo('nick','nan')
if hasattr(f,'tucao'):
f.bianxing('nv')
res=getattr(f,'tucao')(f.name)
print(res)
print(getattr(f,'sex'))
else:
print('your mother boom') def gaoji(name):
print(f'{name}疯狂搞基') setattr(f,'age',18)
print(getattr(f,'age'))
setattr(f,'gaojia',gaoji)
getattr(f,'gaojia')(f.name) delattr(f,'sex')
print(getattr(f,'sex'))

nick疯狂吐槽

nv

18

nick疯狂搞基

最后会报错,因为sex属性被删除

反射在模块中的应用

# test.py
def f1():
print('f1') def f2():
print('f2') def f3():
print('f3') def f4():
print('f4') a = 1
import test as ss ss.f1()
ss.f2()
print(ss.a)

我们要导入另外一个模块,可以使用import.现在有这样的需求,我动态输入一个模块名,可以随时访问到导入模块中的方法或者变量,怎么做呢?

imp = input(“请输入你想导入的模块名:”)
CC = __import__(imp) 這种方式就是通过输入字符串导入你所想导入的模块
CC.f1() # 执行模块中的f1方法

上面我们实现了动态输入模块名,从而使我们能够输入模块名并且执行里面的函数。但是上面有一个缺点,那就是执行的函数被固定了。那么,我们能不能改进一下,动态输入函数名,并且来执行呢?

# dynamic.py
imp = input("请输入模块:")
dd = __import__(imp)
# 等价于import imp
inp_func = input("请输入要执行的函数:") f = getattr(dd, inp_func,
None) # 作用:从导入模块中找到你需要调用的函数inp_func,然后返回一个该函数的引用.没有找到就烦会None f() # 执行该函数
请输入模块:time
请输入要执行的函数:time 1560959528.6127071

上面我们就实现了,动态导入一个模块,并且动态输入函数名然后执行相应功能。

当然,上面还存在一点点小问题:那就是我的模块名有可能不是在本级目录中存放着。有可能是如下图存放方式:

|- day24
|- lib
|- common.py

那么这种方式我们该如何搞定呢?看下面代码:

dd = __import__("lib.text.commons")  # 这样仅仅导入了lib模块
dd = __import__("lib.text.commons", fromlist=True) # 改用这种方式就能导入成功
# 等价于import config
inp_func = input("请输入要执行的函数:")
f = getattr(dd, inp_func)
f()

内置方法

class Foo:
x = 1 def __init__(self, y):
self.y = y def __getattr__(self, item):
print('----> from getattr:你找的属性不存在') def __setattr__(self, key, value):
print('----> from setattr')
# self.key = value # 这就无限递归了,你好好想想
# self.__dict__[key] = value # 应该使用它 def __delattr__(self, item):
print('----> from delattr')
# del self.item # 无限递归了
self.__dict__.pop(item) f1 = Foo(10)

一、setattr

  • 添加/修改属性会触发它的执行
print(f1.__dict__
) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z = 3
print(f1.__dict__)

二、delattr

  • 删除属性的时候会触发
f1.__dict__['a'] = 3  # 我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)
----> from delattr
{}

三、 getattr

  • 只有在使用点调用属性且属性不存在的时候才会触发

    f1.xxxxxx

    ----> from getattr:你找的属性不存在

isinstance与issubclass,反射的更多相关文章

  1. python 全栈开发,Day23(复习,isinstance和issubclass,反射)

    一.复习 class A: def func1(self):pass def func2(self): pass def func3(self): pass a = A() b = A() print ...

  2. day17 isinstance type issubclass 反射

    1. issubclass,type,isinstance 1.issubclass 判断xxx是否yyy的子类 例: class Foo: pass class Bar(Foo): pass cla ...

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

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

  4. day23-1 isinstance、issubclass和反射

    目录 isinstance和issubclass 反射(hasattr,getattr,setattr,delattr) isinstance和issubclass isinstance(obj,cl ...

  5. 绑定与非绑定方法及反射,isinstance和issubclass内置函数

    目录 绑定方法与非绑定方法 1.绑定方法 2.非绑定方法(staticmethod) isinstance和issubclass 内置函数 1.isinstance 2.issubclass 反射(面 ...

  6. python全栈开发day23-面向对象高级:反射(getattr、hasattr、setattr、delattr)、__call__、__len__、__str__、__repr__、__hash__、__eq__、isinstance、issubclass

    一.今日内容总结 1.反射 使用字符串数据类型的变量名来操作一个变量的值. #使用反射获取某个命名空间中的值, #需要 #有一个变量指向这个命名空间 #字符串数据类型的名字 #再使用getattr获取 ...

  7. python基础之 反射,md5加密 以及isinstance, type, issubclass内置方法的运用

    内容梗概: 1. isinstance, type, issubclass 2. 区分函数和方法 3. 反射(重点) 4. md5加密 1. isinstance, type, issubclass1 ...

  8. 27 isinstance与issubclass、反射、内置方法

    isinstance与issubclass issubclass:判断子类是否属于父类,是则返回True,否则返回False isinstance:判断对象是否属于类,是则返回True,否则返回Fal ...

  9. isinstance、issubclass、反射

    一.isinstance.issubclass # isinstance(obj, cls) 检查obj是否是cls的对象 class A(object):pass a = A() print(isi ...

随机推荐

  1. 计蒜客T2202 数三角形(提高组2017模拟赛(三)day2T3) LZOJ3878攻略

    今天模拟赛考了一道计蒜客NOIP2017模拟赛(三)day2T3的数三角形,原题链接 https://nanti.jisuanke.com/t/T2202 ,LZOJ3878攻略.场上想了很久都没转化 ...

  2. Android_(游戏)打飞机04:绘画敌机、添加子弹

    (游戏)打飞机01:前言 传送门 (游戏)打飞机02:游戏背景滚动 传送门 (游戏)打飞机03:控制玩家飞机 传送门 (游戏)打飞机04:绘画敌机.添加子弹   传送门 (游戏)打飞机05:处理子弹, ...

  3. dataX调优

    dataX调优 标签(空格分隔): ETL 一,Datax调优方向 DataX调优要分成几个部分(注:此处任务机指运行Datax任务所在的机器). 1,网络本身的带宽等硬件因素造成的影响: 2,Dat ...

  4. 【Spark机器学习速成宝典】模型篇05决策树【Decision Tree】(Python版)

    目录 决策树原理 决策树代码(Spark Python) 决策树原理 详见博文:http://www.cnblogs.com/itmorn/p/7918797.html 返回目录 决策树代码(Spar ...

  5. echart 饼图图例legend支持滑动

    ps: 以下针对option操作 文章目录 图例过多加上滚动条图例形状图例自定义显示图例过多加上滚动条 legend:{ top:'50', bottom:'50', type:'scroll',} ...

  6. java基本算法

    1.链表 链表用来存储数据,由一系列的结点组成.这些结点的物理地址不一定是连续的,即可能连续,也可能不连续,但链表里的结点是有序的.一个结点由数据的值和下一个数据的地址组成.一个链表内的数据类型可以是 ...

  7. 通过Precision/Recall判断分类结果偏差极大时算法的性能

    当我们对某些问题进行分类时,真实结果的分布会有明显偏差. 例如对是否患癌症进行分类,testing set 中可能只有0.5%的人患了癌症. 此时如果直接数误分类数的话,那么一个每次都预测人没有癌症的 ...

  8. bulk_create(lst) 批量创建数据

    # 批量创建数据 # Create your views here. from django.db import models from django.shortcuts import HttpRes ...

  9. nodejs之fs 模块

    1.fs模块函数 * .fs.stat 检测是文件还是目录 * .fs.mkdir 创建目录 * .fs.writeFile 创建写入文件 * .fs.appendFile 追加文件 * .fs.re ...

  10. 阶段3 2.Spring_07.银行转账案例_8 基于接口的动态代理回顾

    创建 Producer 生产者的类 创建标准.这标准就是接口 创建消费者的类 以前的方式,客户直接找生产厂家 代理商出现以后,怎么去联系代理商 动态代理 第一个参数是ClassLoader 第二个参数 ...