1.2 Python 自省机制详解

自省,在我们日常生活中,通常是自我反省的意思。

但在计算机编程中,自省并不是这个意思,它的英文单词是 introspection,表示的是自我检查的行为或能力。

它的内容包括

  1. 告诉别人,我是谁

  2. 告诉别人,我能做什么

(有点面试的感觉了)

Python 是一门动态语言,有了自省,就能让程序在运行时能够获知对象的类型以及该对象下有哪些方法等。

1. 学习 Python 模块的入口

help()

在 console 模式下,输入 help() ,可以看到输出了一段帮助文档,教你如何使用这个 help,当你看到提示符变成了 help> 时,这时候就进入了 help 模式。

image0

此时你可以键入你想要了解的模块、语法等,help 告诉你如何使用。

比如我输入 keywords ,就可以看到 Python 里所有的关键字。再输入 modules 就可以查看 Python 中所有的内置模块。

image1

输入 modules + 指定包名,就可以查看这个包下有哪些模块

image2

如果你想学习某个包要如何使用,可以直接在 help 模式下输入 包名,就像下面这样,我就可以获得一份 json 的帮助文档。

image3

如果你想学习某个关键字的用法,可以在 help 模式下直接键入 关键字 查询用法,比如我直接键入 for

image4

查完后,使用 quit 就可以退出 help 模式了。

image5

如果你觉得进入 help 模式太麻烦,可以在 console 模式下直接查询

>>> help("json")

dir()

dir() 函数可能是 Python 自省机制中最著名的部分了。它返回传递给它的任何对象的属性名称经过排序的列表。如果不指定对象,则 dir() 返回当前作用域中的名称。让我们将 dir() 函数应用于 keyword 模块,并观察它揭示了什么:

image6

__doc__

使用 __doc__ 这个魔法方法,可以查询该模块的文档,它输出的内容和 help() 一样。

image7

2. 应用到实际开发中

type()

type() 函数有助于我们确定对象是字符串还是整数,或是其它类型的对象。它通过返回类型对象来做到这一点,可以将这个类型对象与 types 模块中定义的类型相比较:

>>> type(42)
<class 'int'>
>>> type([])
<class 'list'>

hasattr()

使用 dir() 函数会返回一个对象的属性列表。

但是,有时我们只想测试一个或多个属性是否存在。如果对象具有我们正在考虑的属性,那么通常希望只检索该属性。这个任务可以由 hasattr() 来完成.

>>> import json
>>> hasattr(json, "dumps")
True
>>>

getattr()

使用 hasattr 获知了对象拥有某个属性后,可以搭配 getattr() 函数来获取其属性值。

>>> getattr(json, "__path__")
['/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json']
>>>

使用 getattr 获取函数后,可以很方便地使用这个函数,比如下面这样,可以不再使写 json.dumps 这么字。

>>> dumps = getattr(json, "dumps")
>>> dumps({"name": "MING"})
'{"name": "MING"}'
>>>

# 当然你还有更简单的方法
>>> mydumps = json.dumps
>>> mydumps({"name": "MING"})
'{"name": "MING"}'

id()

id() 函数返回对象的唯一标识符,标识符是一个整数。

>>> a = "hello"
>>> b = "world"
>>>
>>> id(a)
4470767944
>>> id(b)
4499487408
>>>

isinstance()

使用 isinstance() 函数可以确定一个对象是否是某个特定类型或定制类的实例。

>>> isinstance("python", str)
True
>>> isinstance(10, int)
True
>>> isinstance(False, bool)
True

callable()

使用 callable 可以确定一个对象是否是可调用的,比如函数,类这些对象都是可以调用的对象。

>>> callable("hello")
False
>>>
>>> callable(str)
True
>>>

image8