本节主要内容:
1. isinstance, type, issubclass
2. 区分函数和方法
3. 反射(重点)
一. isinstance, type, issubclass
首先, 我们先看issubclass() 这个内置函数可以帮我们判断xxx类是否是yyy类型的子类.
class Base:
pass
class Foo(Base):
pass
class Bar(Foo):
pass
print(issubclass(Bar, Foo)) # True
print(issubclass(Foo, Bar)) # False
print(issubclass(Bar, Base)) # True
然后我们来看type. type在前⾯面的学习期间已经使用过了. type(obj) 表示查看obj是由哪个类创建的.
class Foo:
pass obj = Foo()
print(obj, type(obj)) # 查看obj的类
isinstance也可以判断xxx是yyy类型的数据. 但是isinstance没有type那么精准.
class Base:
pass
class Foo(Base):
pass
class Bar(Foo):
pass
print(isinstance(Foo(), Foo)) # True
print(isinstance(Foo(), Base)) # True
print(isinstance(Foo(), Bar)) # False
isinstance可以判断该对象是否是xxx家族体系中的(只能往上判断)
二. 区分函数和方法
仔细观察, 我们能得到以下结论:
1. 类方法. 不论任何情况, 都是方法.
2. 静态⽅方法, 不论任何情况. 都是函数
3. 实例例方法, 如果是实例例访问. 就是方法. 如果是类名访问就是函数.
三. 反射.
首先, 我们看这样⼀一个需求, 说, 有个大牛, 写了一堆特别牛B的代码. 然后放在了一个py 文件⾥(模块), 这时, 你想⽤用这个⼤牛写的东⻄西. 但是呢. 你⾸首先得知道⼤牛写的这些代码都是 ⼲什么⽤用的. 那就需要你把⼤牛写的每⼀一个函数跑⼀下.
getattr(对象, 字符串串): 从对象中获取到xxx功能. 此时xxx是⼀一个字符串串. get表⽰示找, attr 表⽰示属性(功能). 但是这⾥里里有个问题. ⽤用户如果⼿手⼀一抖, 输入错了了. 在⼤大⽜牛的代码⾥里里没有你要找 的内容. 那这个时候就会报错. 所以. 我们在获取attr之前. 要先判断⼀一下. 有没有这个attr
好了了, 这⾥里里我们讲到了了两个函数. ⼀一个是getattr(). ⼀一个是hasattr(). 其中getattr()⽤用来获 取信息. hasattr()⽤用来判断xxx中是否包含了了xxx功能, 那么我们可以在模块中这样来使⽤用反射. 在⾯面向对象中⼀一样可以这样进⾏行行操作. 这个就比较⽜牛B了了. 后期你学习的相关框架内部核⼼心源 码⼏几乎都是这些东⻄西. ⾸首先, 我们先看⼀一些简单的.
总结, getattr可以从模块中获取内容, 也可以从类中获取内容, 也可以从对象中获取内 容. 在python中⼀一切皆为对象. 那可以这样认为. getattr从对象中动态的获取成员
补充:
关于反射, 其实⼀一共有4个函数: 1. hasattr(obj, str) 判断obj中是否包含str成员 2. getattr(obj,str) 从obj中获取str成员 3. setattr(obj, str, value) 把obj中的str成员设置成value. 注意. 这⾥里里的value可以是 值, 也可以是函数或者⽅方法 4. delattr(obj, str) 把obj中的str成员删除掉 注意, 以上操作都是在内存中进⾏行行的. 并不会影响你的源代码