issubclass/type/isinstance、函数和方法、反射、callable、特殊成员补充
一、issubclass/type/isinstance(***)
1、issubclass(参数1, 参数2):检查第一个参数是否是第二个参数的 子子孙孙类,如下示例:
class Base(object): pass class Foo(Base): pass class Bar(Foo): pass print(issubclass(Bar, Foo)) # True print(issubclass(Bar, Base)) # True
2、type():获取当前对象时由哪个类创建,如下示例:
# #####示例一:判断一个参数是不是某一个指定类的对象 class Foo(object): pass obj = Foo() print(obj,type(obj)) # <__main__.Foo object at 0x0000000002618F60> <class '__main__.Foo'> if type(obj) == Foo: # 判断一个参数是不是某一个指定类的对象 print('obj是Foo类型') # #####示例二:练习题:判断函数的参数分别是哪个类的对象 class Foo(object): pass class Bar(object): pass def func(*args): foo_counter = 0 bar_counter = 0 for item in args: if type(item) == Foo: foo_counter += 1 elif type(item) == Bar: bar_counter += 1 return foo_counter, bar_counter print(func(Foo(), Bar(), Foo())) # (2, 1)
# 补充:示例三:如何判断参数是不是一个类
class Foo(object):
pass
obj = Foo()
print(type(Foo) == type) # True
print(type(obj) == type) # False
3、isinstance(参数1, 参数2):检查第一个参数是否是第二个参数的实例,如下示例:
# #####示例一:判断一个参数是不是某一个指定类或其父类的对象 class Base: pass class Foo(Base): pass class Bar(Foo): pass obj1 = Bar() print(isinstance(obj1, Bar)) # True print(isinstance(obj1, Foo)) # True print(isinstance(obj1, Base)) # True obj2 = Foo() print(isinstance(obj2, Bar)) # False
二、用科学的方式判断是函数和方法(*)
一般我们笼统的称定义在类中的函数为方法,定义在类外的就是函数,其实是不太严谨的,如下示例:
# #####示例一:如何看得出是函数还是方法 def func(): pass class Foo(object): def inner(self): pass @staticmethod def detail(): pass print(func) # <function func at 0x00000000028C99D8> 是函数 obj = Foo() print(obj.inner) # 是方法 # <bound method Foo.inner of <__main__.Foo object at 0x00000000028D1208>> print(Foo.detail) # <function Foo.detail at 0x00000000028F9AE8> 是函数 print(obj.detail) # <function Foo.detail at 0x00000000028F9AE8> 是函数 如何看得出是函数还是方法
其实,在python中,一切皆对象,只要是对象,它就有对应的类,函数是FunctionType创建的,方法是由MethodType创建的,所以,我们可以按照如下示例判断是函数还是方法:
# #####示例二 from types import MethodType,FunctionType def check(arg): """ 检查arg是方法还是函数? """ if isinstance(arg,MethodType): print('arg是一个方法') elif isinstance(arg,FunctionType): print('arg是一个函数') else: print('不知道是什么') check(func) # arg是一个函数 check(obj.inner) # arg是一个方法
# #####示例三:是不是方法跟写在哪里没关系,跟调用有关系 class Foo(object): def f1(self): pass obj = Foo() obj.f1() # 把f1当做方法,python自动传self值 print(obj.f1) # <bound method Foo.f1 of <__main__.Foo object at 0x0000000002724390>> obj = Foo() Foo.f1(obj) # 把f1当做函数,需要自己传参数 print(Foo.f1) # <function Foo.f1 at 0x0000000002791AE8> 是不是方法跟写在哪里没有关系,跟调用有关系
# #####示例四:练习题 class Foo(object): def f1(self): pass def f2(self): pass def f3(self): pass list_display = [f1,f2] def __init__(self): pass for item in Foo.list_display: print(item) item(123) # item是函数,所以要自己传参数 # 结果为: # <function Foo.f1 at 0x00000000029A3B70> # <function Foo.f2 at 0x00000000029A3BF8> 练习题一