反射
1. isinstance, type, issubclass
一. 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家族体系中的(只能往上判断)
2. 区分函数和方法
def func():
pass
print(func) # <function func at 0x10646ee18>
class Foo:
def chi(self):
print("我是吃")
f = Foo()
print(f.chi) # <bound method Foo.chi of <__main__.Foo object a0x10f688550>>
- 类方法. 不论任何情况, 都是方法.
- 静态方法, 不论任何情况. 都是函数
- 实例方法, 如果是实例访问. 就是方法. 如果是类名访问就是函数.
from types import MethodType, FunctionType
def func():
pass
print(isinstance(func, FunctionType)) # True
print(isinstance(func, MethodType)) # False
class Foo:
def chi(self):
print("我是吃")
@staticmethod
def static_method():
pass
@classmethod
def class_method(cls):
pass
obj = Foo()
print(type(obj.chi)) # method
print(type(Foo.chi)) # function
print(isinstance(obj.chi, MethodType)) # True
print(isinstance(Foo.chi, FunctionType)) # True
print(isinstance(Foo.static_method, FunctionType)) # Tru
print(isinstance(Foo.static_method, MethodType)) # False
print(isinstance(Foo.class_method, FunctionType)) # False
print(isinstance(Foo.class_method, MethodType)) # True
3. 反射
有个大牛, 写了一堆特别厉害的代码. 然后放在了一个py文件里(模块那就需要你把写的每一个函数跑一下. 摘一摘自己想要的内容. 来咱们模拟这样的需求, 首先, 大牛给出一个模块.
def chi():
print("大牛一顿吃100个螃蟹")
def he():
print("大牛一顿喝100瓶可乐")
def la():
print("大牛不用拉")
def shui():
print("大牛一次睡一年")
接下来可以调用了
import master
while 1:
print("""作为大牛, 我帮你写了:
chi
he
la
shui
等功能. 自己看看吧""")
gn = input("请输入你要测试的功能:")
func = getattr(master, gn)
func()
getattr(对象, 字符串): 从对象中获取到xxx功能. 此时xxx是一个字符串. get表示找, attr表示属性(功能)
import master
from types import FunctionType
while 1:
print("""作为小牛, 我帮你写了:
chi
he
la
shui
等功能. 看看吧""")
gn = input("请输入你要测试的功能:")
if hasattr(master, gn): # 如果master里面有你要的功能
# 获取这个功能, ,并执行
attr = getattr(master, gn)
# 判断是否是函数. 只有函数才可以被调用
if isinstance(attr, FunctionType):
attr()
else:
# 如果不是函数, 就打印
print(attr)
hasattr()用来判断xxx中是否包含了xxx功能, 那么我们可以在模块中这样来使用反射.
- hasattr(obj, str) 判断obj中是否包含str成员
- getattr(obj,str) 从obj中获取str成员
- setattr(obj, str, value) 把obj中的str成员设置成value. 注意. 这里的value可以是
值, 也可以是函数或者方法 - delattr(obj, str) 把obj中的str成员删除掉