在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么、它知道什么以及它能做什么。自省向程序员提供了极大的灵活性和控制力。
下面开始介绍日常coding中最常用的自省方法:
访问对象的属性
当你想要对某个对象的属性(包括方法)进行操作但是记不清它的名字、甚至都不确定它是否存在的时候,python提供的自省功能就派上用场了。
#实现一个简单的类
class MyClass:
def __init__(self, name):
self.name = name
def instance_method(self):
print(self,'调用了实例方法~')
#开始测试
obj = MyClass('trophy') # 创建一个实例对象obj
if hasattr(obj, 'name'): # 检查实例obj是否有name属性
setattr(obj, 'name', 'jack') # 相当于obj.name = 'jack'
print(getattr(obj, 'name')) # jack
print(obj.name) # jack
if hasattr(obj, 'instance_method'): # 检查实例obj是否有instance_method属性
getattr(obj, 'instance_method')() # <__main__.MyClass object at 0x000000CA0833B668> 调用了实例方法~
obj.instance_method() #<__main__.MyClass object at 0x000000CA0833B668> 调用了实例方法~
print(dir(obj))
'''
dir(obj):
['__class__', '__delattr__', '__dict__', '__dir__',
......
'__subclasshook__', '__weakref__',
'instance_method', 'name'] #注意这一行哦~
'''
在上面的例子中使用了以下几个方法:
- hasattr(obj, attr):
这个方法用于检查obj是否有一个名为attr的属性,返回一个布尔值。 - getattr(obj, attr):
调用这个方法将返回obj中名为attr的属性的值。当attr为简单的属性名,getattr(obj, attr)相当于obj.attr。而当attr是个方法名的时候,getattr(obj, attr)()就相当于obj.attr()啦。 - setattr(obj, attr, val):
调用这个方法将给obj的名为attr的属性赋值为val。例如如果attr为’name’,则相当于obj.name= val。 - dir([obj]):
调用这个方法将返回参数obj的属性和方法列表,obj的默认值是当前的模块对象。我们自定义的属性和方法一般是排在返回列表的末尾(如上例中dir(obj)的最后一行)。
在python中一切皆对象,你可以对所有的对象使用上面的方法,我们再拿List类对象来试试:
#测试List类的clear和append方法
a = [1,2,3,4,5]
print(a) # [1, 2, 3, 4, 5]
if hasattr(a, 'clear'): # 检查实例a是否有clear属性
getattr(a, 'clear')() # 相当于a.clear()
print(a) # []
getattr(a, 'append')(88) # 相当于a.append(88)
print(a) # [88]
print(dir(a))
'''
['__add__', '__class__', '__contains__', '__delattr__',
......
'append', 'clear', 'copy', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
'''
确认对象的类型
有两种方式可以确认对象的类型
1. 使用type()函数,返回对象的类型
print(type(111)) #<class 'int'>
print(type('hello')) #<class 'str'>
print(type([1,2,3])) #<class 'list'>
print(type({'num':10})) #<class 'dict'>
print(type(lambda x : x+1)) #<class 'function'>
2. 使用isinstance()函数,判断一个对象是否是一个已知的类型
用法:isinstance(obj, classinfo),其中obj为实例对象,即要检查的对象。classinfo -可以是直接或间接类名、基本类型或者由它们组成的元组。
classinfo基本类型有:int,float,bool,complex,str,list,dict,set,tuple
print(isinstance (1,int)) #True
print(isinstance ('hello',str)) #True
print(isinstance ('[1,2,3]',list)) #False
print(isinstance ({'num':10},dict)) #True
print(isinstance ('[1,2]',(str,int,list))) #True 匹配了元组中的str
快速查看帮助信息
python内置的help() 函数可以用于查看函数或模块用途的详细说明。
使用方法:help([obj]),obj为你想要查询的对象,当不传入参数时会进入help交互式环境。
下面来看看使用示例:
help('math') #查看math模块的帮助信息
help(str) #查看str类型的帮助信息
help(int) #查看int类型的帮助信息
help([]) #查看list类型的帮助信息
a = [1,2]
help(a.append) #查看列表append方法的帮助信息
想了解更多?快去看看大神写的指南:Python自省(反射)指南