• python之反射机制与callattr()、issubclass()、isinstance、type()相关


    一、反射机制 *

      反射可以理解为

    • 通过字符串的形式,动态导入模块;
    • 利用字符串的形式,在对象(模块)中操作(查找/获取/删除/添加)成员,是一种基于字符串的事件驱动!

      反射机制的内置函数

     1 # hasattr(object,attr)
     2 # 输入两个参数(对象,字符串类型(方法或属性)),判断一个对象里是否有某个属性或方法,返回布尔值,有为True,否则False
     3 class Foo:
     4     def f1(self):
     5         pass
     6 obj = Foo()
     7 print(hasattr(obj,"f1"))
     8 # 运行结果:True
     9 
    10 
    11 # getattr(object,attr[,default])
    12 # 获取对象的属性或方法,可设置输出默认值,
    13 # 如果获取方法,返回的是内存地址,如果需要运行,后面添加一对括号
    14 class Foo:
    15     def f1(self):
    16         print("获取了f1方法")
    17 obj = Foo()
    18 ret = getattr(obj,"f1")
    19 ret()
    20 print(ret)
    21 # 运行结果:获取了f1方法 
    22 # <bound method Foo.f1 of <__main__.Foo object at 0x0000024FE505E9B0>>
    23 
    24 # setattr(object,attr,values)
    25 # 动态的给对象的属性赋值(内存地址),若属性不存在,则先创建再赋值
    26 class Foo:
    27     def __init__(self,a1):
    28         self.a1 = a1
    29 obj = Foo(1)
    30 print(getattr(obj,"a1"))
    31 #运行结果:1
    32 setattr(obj,"a1",2)   # 将对象中的属性重新赋值
    33 print(getattr(obj,"a1"))
    34 #运行结果:2
    35 setattr(obj,"a2",3)     #在对象中创建一个新的属性a2并赋值
    36 print(getattr(obj,"a2"))
    37 #运行结果:3
    38 
    39 
    40 # delattr(object,attr,values)
    41 # 动态的删除对象的属性(内存地址)
    42 class Foo:
    43     def __init__(self,a1):
    44         self.a1=a1
    45 obj = Foo(1)
    46 print(getattr(obj,"a1"))
    47 # 运行结果: 1
    48 setattr(obj,"a2",2)
    49 print(getattr(obj,"a2"))
    50 # 运行结果: 2
    51 delattr(obj,"a2")
    52 print(getattr(obj,"a2"))        #删除对象中的属性
    53 #运行结果:AttributeError: 'Foo' object has no attribute 'a2'
    反射的内置函数

    二、如何正确的判断方法与函数?

      目前我们印象中的方法就是封装在类内部的函数,实际上这样说不严谨;

      

     1 # 如何判断方法与函数
     2 # tpye
     3 # 判断类型
     4 class Foo:
     5     def f1(self):
     6         pass
     7 obj = Foo()
     8 print(obj,type(obj.f1))  # 当我们用对象调用类中的方法时,我们通过type查看到的是方法
     9 # 运行结果:<__main__.Foo object at 0x0000028E0F10E898> <class 'method'>
    10 print(Foo,type(Foo.f1))     # 当我们用类调用类中的方法时,我们通过type查看到的是函数
    11 # 运行结果:<class '__main__.Foo'> <class 'function'>
    12 # 总结:封装在类中的函数通过对象调用时是真正的方法。

    三、callattr()、issubclass()、isinstance、type()的使用

      callattr()方法是用来判断传入的参数是否可以被调用

     1 callable
     2 判断输入的参数是否可以被调用
     3 class Foo:
     4     def f1(self):
     5         pass
     6     def __call__(self, *args, **kwargs):
     7         pass
     8 def func():
     9     pass
    10 obj = Foo()
    11 print(callable(Foo))  # 类是可以被调用的类型
    12 # 运行结果: True
    13 print(callable(obj.f1))     # 方法是可以被调用的类型
    14 # 运行结果: True
    15 print(callable(func))       #函数是可以被调用的类型
    16 # 运行结果: True
    17 print(callable(obj))        #实例化的对象是可以被调用的类型,注:类的内部要有__call__方法
    18 # 运行结果: True

      issubclass()方法是用判断传入的两个参数,前一个参数是否是后一个参数的派生类

    1 # issubclass
    2 # 判断传入的两个参数,前一个参数是否是后一个参数的子类
    3 class Base:
    4     pass
    5 class Foo(Base):
    6     pass
    7 print(issubclass(Foo,Base))
    8 # 运行结果: True

      isinstance()方法是判断传入两个参数,第一个传入的参数(对象),是否是第二个参数(类)的实例

      

     1 # isinstance
     2 # 判断传入两个参数,第一个传入的参数(对象),是否是第二个参数(类)的实例
     3 class Base:
     4     def f1(self):
     5         pass
     6     def f2(self):
     7         pass
     8 class Foo(Base):
     9     def f1(self):
    10         pass
    11 class Last:
    12     pass
    13 obj = Foo()
    14 print(isinstance(obj,Last))
    15 #运行结果:False
    16 print(isinstance(obj,Foo)) # obj是Foo类的一个实例化对象
    17 #运行结果:True
    18 print(isinstance(obj,Base))# obj也可以是Foo基类的一个实例化对象
    19 #运行结果:True
    20 # 总结:isinstance可以判断对象是否是类或类的基类中的实例

      type()

    1 # type
    2 # 判断传入的参数(对象)是哪个类的实例化对象
    3 class Base:
    4     pass
    5 class Foo(Base):
    6     pass
    7 obj = Foo()
    8 print(obj,type(obj))    # 获取当前对象是由哪个类创建
    9 # 运行结果: <__main__.Foo object at 0x000001567FC9E8D0> <class '__main__.Foo'>
  • 相关阅读:
    为什么整个互联网行业都缺前端工程师?
    css3做的圆特效
    又一个前端的小渣渣诞生了
    返回顶部代码!
    网页动画的十二原则
    JQuery缓冲加载图片插件lazyload.js的使用方法
    关于写手机页面demo的准备工作
    HTML5加载动画
    HTML5加载动画
    正则表达式语法
  • 原文地址:https://www.cnblogs.com/qq631243523/p/9561705.html
Copyright © 2020-2023  润新知