016 方法和函数的区分、子类的判断和反射
1. 子类的判断:
class Base: pass class Father(Base): pass class Son(Father): pass # issubclass 判断第一个参数(类),是否为第二个参数的子类(子子孙孙类) print(issubclass(Son, Father)) # True print(issubclass(Son, Base)) # True # type 检查该对象由哪个类创建 obj = Father() print(type(obj)) # <class '__main__.Father'> print(type(obj) == Father) # True print(type(obj) == Base) # False # isinstance() 判断第一个参数(对象),是否为第二个参数(类及父类)的实例 print(isinstance(obj, Base)) # True print(isinstance(obj, Father)) # True print(isinstance(obj, Son)) # False
2. 方法和函数的区分:
from types import MethodType, FunctionType class Foo(): country = 'China' def __init__(self, name): self.name = name def f1(self): print(self.name) def f2(self): print('hello2') @staticmethod def f3(): print(f1) @classmethod def f4(cls): print('%s f2' % cls.country) obj = Foo('小明') # 实例化 # 通过print查看, 输出中带有 method 的为方法,带有 function 的为函数 print(obj.f1) # 方法 print(obj.f2) # 方法 print(Foo.f3) # 函数 print(Foo.f4) # 方法 # 通过 types 模块的 MethodType 和 FunctionType 判断 def check(arg): if isinstance(arg, MethodType): print('这是方法') elif isinstance(arg, FunctionType): print('这是函数') else: print('即不是方法,也不是函数') check(obj.f1) check(obj.f2) check(Foo.f3) check(Foo.f4)
这是严格判断方法和函数的示例,但我们一般把类中的函数都称为方法。
3. 反射:
根据字符串参数,寻找对象中对应的方法,并进行相应操作。
class Foo(): def f1(self): print('1111') def f2(self): print('2222') def f3(self): print('3333') obj = Foo() # getattr(obj, 'func') 在obj中寻找,与字符串'func'同名的函数,并返回 for i in range(1, 4): v = getattr(obj, 'f%s' % i) v() # hasattr(obj, 'func') 判断obj中是否有,与字符串'func'同名的函数,并返回True/False for i in range(4): print(hasattr(obj, 'f%s' % i)) # setattr(obj, 'name', value) 给obj中设置一个对象,名为'name'(字符串的形式), 值为value # setattr 并不会改写代码,只是在内存中给对象添加,并不会影响到创建他的类 setattr(obj, 'age', 1000) print(obj.age) # delattr(obj, 'name') 把obj中名为'name'的成员删掉,并不会影响到创建他的类 delattr(obj, 'age') print(hasattr(obj, 'age'))
4. 补充:
A. 可迭代对象的判断:
# 把一个类改为可迭代的,只需添加 __iter__方法 class Foo: def __iter__(self): yield 111 yield 222 yield 333 obj = Foo() for i in obj: print(i)

浙公网安备 33010602011771号