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'>

 

posted @ 2018-08-30 17:52  sado  阅读(226)  评论(0编辑  收藏  举报