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

  • 相关阅读:
    MySql cmd下的学习笔记 —— 引擎和事务(engine,transaction)
    MySql cmd下的学习笔记 —— 有关视图的操作(algorithm)
    MySql cmd下的学习笔记 —— 有关视图的操作(建立表)
    MySql cmd下的学习笔记 —— 有关常用函数的介绍(数学函数,聚合函数等等)
    MySql cmd下的学习笔记 —— 有关多表查询的操作(多表查询练习题及union操作)
    MySql 在cmd下的学习笔记 —— 有关多表查询的操作(内连接,外连接,交叉连接)
    MySql cmd下的学习笔记 —— 有关子查询的操作(where型,from型,exists型子查询)
    MySql cmd下的学习笔记 —— 有关select的操作(order by,limit)
    剑指Offer--第21题 调整数组顺序使奇数位于偶数前面;
    剑指Offer--和为s的连续正数序列
  • 原文地址:https://www.cnblogs.com/bjlxxbj/p/11508208.html
Copyright © 2020-2023  润新知