Python强大的自省机制详解

目录
  • 何为自省
  • dir()函数
  • type()函数和id()函数
  • inspect模块
    • getmembers(object, predicate=None)函数
    • signature(obj, *, follow_wrapped=True)函数
    • getmodule(object)函数
    • getsource(object)函数
    • getsourcelines(object)函数
    • ismodule()、isclass()、ismethod()、isfunction()、isgenerator()函数等等
  • hasattr()函数和getattr()函数
  • 总结

何为自省

在计算机编程领域里,自省是一种能力,是通过一定机制在程序运行时获知对象的类型及对象的内部结构,Python的自省能力还是很强大的,因为Python中一切皆对象,我们不仅可以获取对象的类型,还可以获取对象内部的属性。下面就来介绍一下Python中一些提供强大自省能力的方法。

dir()函数

它是用于自省的最重要的函数之一。它以列表的形式返回一个对象所拥有的全部属性和方法,如果dir()不传任何参数,默认是查找当前命名空间有什么对象。

user = {"nickname": "tigeriaf", "level": 2}
print(dir(user))

执行结果为:

上面的dir()自省输出了一个字典对象的所有方法的名字。当我们记不太清某个对象的某个方法的名字时,使用这个是非常有帮助的。

type()函数和id()函数

type()函数返回一个对象的类型。例如:

print(type('tigeriaf'))
# 结果输出为 <class 'str'>
print(type(2))
# 结果输出为 <class 'int'>
print(type([1, 2, 3]))
# 结果输出为 <class 'list'>

id()函数返回对象的唯一标识符,是一个整数,在CPython中id()函数用于获取对象的内存地址。例如:

print(id('tigeriaf'))

# 结果输出为 51064768

inspect模块

inspect是Python的标准库,提供了更加强大的自省能力,提供了很多函数帮助获取对象的信息,例如模块、类、方法、函数、回溯、帧对象以及代码对象。
该模块提供了4种主要的功能:类型检查、获取源代码、检查类与函数、检查解释器的调用堆栈。下面介绍一下其中的几个常用的方法:

getmembers(object, predicate=None)函数

是基于dir()实现的,返回一个包含对象的所有成员的(name, value)列表。返回的内容比对象的__dict__包含的内容多。predicate是可选的参数,被此函数判断为True的成员才被返回。

例如:

import inspect
print(inspect.getmembers(list))

signature(obj, *, follow_wrapped=True)函数

将返回一个inspect.Signature类型的对象,值为这个函数的所有参数。

getmodule(object)函数

返回定义对象的模块。

getsource(object)函数

返回对象的源代码。

getsourcelines(object)函数

返回一个元组,元组第一项为对象源代码行的列表,第二项是第一行源代码的行号。 例如:

import inspect
def test(a: int):
    print(a)
print(inspect.signature(test))
print(inspect.getmodule(test))
print(inspect.getsource(test))
print(inspect.getsourcelines(test))

执行结果如下:

ismodule()、isclass()、ismethod()、isfunction()、isgenerator()函数等等

一系列判断对象类型的方法,大都是封装了isinstance(object, types.FunctionType)之类语句的函数。

如果平时的开发中对模块、类的操作比较多,那么inspect模块一定要学习一下。

hasattr()函数和getattr()函数

dir()函数会返回某个对象所有属性的列表,但是如果只想测试一个或多个属性是否存在,就需要hasattr()函数和 getattr()函数来完成了,它们的功能分别为判断对象是否有某个属性、获得某个属性值。 例如:

class MyObj:
    def __init__(self):
        self.name = 'my_obj'
        self.a = 1
        self.b = [1, 2, 3]
myobj = MyObj()
print(getattr(myobj, "name"))
print(getattr(myobj, "b"))
print(hasattr(myobj, "a"))
print(hasattr(myobj, "c"))

执行结果为:

总结

其实Python对自省有着很大的支持,Python中还有很多这里没提到的其他方法也能有助于自省,有兴趣的话,你会慢慢发现它们的。

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

时间: 2021-11-23

Python自省及反射原理实例详解

Python中的自省与反射 由于Python是一门强类型的动态解释型语言,故我们在某些时候并不会知道(特别是与别人对接开发工作的时候)对象中具有的属性与方法. 这个时候我们并不能直接通过 .或者查看底层的 __dict__ 方法来获得该对象下的属性与方法,我们需要使用一种更文明的方式来获取该对象下的属性与方法,故这种文明的方式被称之为反射. 自省和反射是两个比较专业化的术语,首先自省是获取对象的能力,而反射是操纵对象的能力. Python中使用delattr()和setattr()实现反射,而其

Python面向对象之反射/自省机制实例分析

本文实例讲述了Python面向对象之反射/自省机制.分享给大家供大家参考,具体如下: 反射:程序可以访问,检测和修改它本身状态或行为的一种能力(自省) 下面就介绍四种实现自省的函数,适用于类和对象 1. 判断object中有没有一个name字符串对应的属性或者方法 hasattr(object,name) 2. 获取object中name字符串对应的属性值或者方法地址,其中default参数的作用是,在找不到属性的时候,给予调用者的提示信息. getattr(object,name,defaul

什么是python的自省

什么是自省? 在日常生活中,自省(introspection)是一种自我检查行为. 在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么.它知道什么以及它能做什么.自省向程序员提供了极大的灵活性和控制力. 说的更简单直白一点:自省就是面向对象的语言所写的程序在运行时,能够知道对象的类型.简单一句就是,运行时能够获知对象的类型. 例如python, buby, object-C, c++都有自省的能力,这里面的c++的自省的能力最弱,只能够知道是什么类型,而像python可以知道是什么类型

python和ruby,我选谁?

最近在考虑学习一门后端语言,在ruby和python直接犹豫,然后自己做了一些对比,希望能帮到有同样问题的你. 一.异同对比选择 1.Python和ruby的相同点: •都强调语法简单,都具有更一般的表达方式.python是缩进,ruby是类basic的表达.都大量减少了符号. •都是动态数据类型.都是有丰富的数据结构. •都具有C语言扩展能力,都具有可移植性,比perl的可移植性更好.也都可以作为嵌入语言. •都是面向对象的语言,都可以作为大项目的开发工具. •都有丰富的库支持. •也有最宽松

用Python创建声明性迷你语言的教程

大多数程序员考虑编程时,他们都要设想用于编写应用程序的 命令式样式和技术.最受欢迎的通用编程语言(包括 Python 和其它面向对象的语言)在样式上绝大多数都是命令式的.另一方面,也有许多编程语言是 声明性样式,包括函数语言和逻辑语言,还包括通用语言和专用语言. 让我们列出几个属于各个种类的语言.许多读者已经使用过这些工具中的许多工具,但不见得考虑过它们之间的种类差别.Python.C.C++.Java.Perl.Ruby.Smalltalk.Fortran.Basic 和 xBase 都是简单

Python中的自省(反射)详解

首先通过一个例子来看一下本文中可能用到的对象和相关概念. 复制代码 代码如下: #coding:  UTF-8 import sys #  模块,sys指向这个模块对象 import inspect def foo(): pass #  函数,foo指向这个函数对象   class Cat(object): #  类,Cat指向这个类对象     def __init__(self,  name='kitty'):         self.name = name     def sayHi(s

结合Python的SimpleHTTPServer源码来解析socket通信

何谓socket 计算机,顾名思义即是用来做计算.因而也需要输入和输出,输入需要计算的条件,输出计算结果.这些输入输出可以抽象为I/O(input output). Unix的计算机处理IO是通过文件的抽象.计算机不同的进程之间也有输入输出,也就是通信.因此这这个通信也是通过文件的抽象文件描述符来进行. 在同一台计算机,进程之间可以这样通信,如果是不同的计算机呢?网络上不同的计算机,也可以通信,那么就得使用网络套接字(socket).socket就是在不同计算机之间进行通信的一个抽象.他工作于T

浅析Python中的getattr(),setattr(),delattr(),hasattr()

getattr()函数是Python自省的核心函数,具体使用大体如下: 获取对象引用getattr Getattr用于返回一个对象属性,或者方法 class A: def __init__(self): self.name = 'zhangjing' #self.age='' def method(self): print"method print" Instance = A() print getattr(Instance , 'name, 'not find') #如果Instan

python编码最佳实践之总结

相信用python的同学不少,本人也一直对python情有独钟,毫无疑问python作为一门解释性动态语言没有那些编译型语言高效,但是python简洁.易读以及可扩展性等特性使得它大受青睐. 工作中很多同事都在用python,但往往很少有人关注它的性能和惯用法,一般都是现学现用,毕竟python不是我们的主要语言,我们一般只是使用它来做一些系统管理的工作.但是我们为什么不做的更好呢?python zen中有这样一句:There should be one-- and preferably onl

跟老齐学Python之Python文档

文档很重要.独孤九剑的剑诀.易筋经的心法.写着辟邪剑谱的袈裟,这些都是文档.连那些大牛人都要这些文档,更何况我们呢?所以,文档是很重要的. 文档,说白了就是用word(这个最多了)等(注意这里的等,把不常用的工具都等掉了,包括我编辑文本时用的vim工具)文本编写工具写成的包含文本内容但不限于文字的文件.有点啰嗦,啰嗦的目的是为了严谨,呵呵.最好还是来一个更让人信服的定义,当然是来自维基百科. 复制代码 代码如下: 软件文档或者源代码文档是指与软件系统及其软件工程过程有关联的文本实体.文档的类型包