• day28


    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:你找的属性不存在

  • 相关阅读:
    《网络攻防实践》6.0
    《网络攻防实践》5.0
    Docker 本地镜像发布到阿里云(完结篇)
    Vue 实战-9 Vue公共js功能函数的封装和使用
    Vue 实战-8 单独运行测试.js文件
    Docker 常用安装
    DockerFile 解析及案例
    Docker 容器数据卷
    Docker 镜像原理
    多字段模糊匹配 -->搜索功能(mysql原生语句实现)
  • 原文地址:https://www.cnblogs.com/bjlxxbj/p/11508208.html
Copyright © 2020-2023  润新知