文章目录
- help() 函数
- help()详解
- help不是一个函数
- help的导入过程
- object.\_\_call__(self [, args ...]) 函数
- site.py模块 与 -S 选项
help() 函数
通常当我们执行python命令进入交互式命令行界面后,可以使用help()来打印某个对象的帮助信息。例如,
>>> help(open)
Help on built-in function open in module io:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
Open file and return a stream. Raise OSError upon failure.
... (后续输出省略)
help()详解
help不是一个函数
当我们在Python命令行提示符>>>下:
- 检查help的类型时,会发现help其实指向一个类的实例,类名是_sitebuiltins._Helper。
- 打印help对象本身的信息时,会发现打印出了一个字符串
Type help() for interactive help, or help(object) for help about object.,
而不是像其他内置函数一样打印出
<built-in function xxx>。
>>> type(help)
<class '_sitebuiltins._Helper'>
>>> help
Type help() for interactive help, or help(object) for help about object.
>>> open
<built-in function open>
help的导入过程
当执行python命令时,如果没有使用-S 选项(表示不导入site库),python会隐式导入’/usr/local/lib/python3.7/site.py’(目录随Python安装目录和版本变化)文件,site.py导入_sitebuiltins模块后,设置help对象指向 _sitebultins._Helper类的实例(当然也类似地设置了其他的一些对象和函数)。
具体过程参考如下:
# from site.py
# import another module
import _sitebuiltins
# 将_Helper类的实例设置给builtins模块的help对象。
# 任何时候都可以在命令行提示符使用help对象
def setHelper():
builtins.help = _sitebuiltins._Helper()
# main()函数执行setHelper()函数以及其他设置函数
def main():
...
setHelper()
...
# if NO (-S) option,
# will execute main() function
if not sys.flags.no_site:
main()
下面具体看一下_sitebuiltins.py模块中_Helper类的定义,一切都会非常明晰。 这个类定义了__call__函数,使得这个对象变成了可调用对象(callable object),也就支持了help(object)这种格式,help用起来就像是一个函数了。在__call__的定义中,最终使用了pydoc.help()函数来生成对象的帮助信息。
# from _sitebuiltins.py
class _Helper(object):
""" doc string omitted """
# >>>help
# will print out the string below
def __repr__(self):
return "Type help() for interactive help, " \
"or help(object) for help about objects."
def __call__(self, *args, **kwds)
import pydoc
return pydoc.help(*args, **kwds)
object.__call__(self [, args …]) 函数
在定义类的时候,可以定义一个特殊的__call__函数,这样类的实例就可以像函数一个被 “调用” 了。
例如:
>>> class foo:
... def __call__(self, msg):
... print(msg)
... return msg
...
>>>
>>> myfoo = foo()
>>> m = myfoo("Hello Callable Object")
Hello Callable Object
>>> print(m)
Hello Callable Object
有了可调用对象后,如果不使用type(object)来查看对象的实际类型,一般情况很难确定对象是一个函数还是还是一个类实例,因为调用的语法格式都一样。但是初学者,尤其是强类型语言背景的,很容易在这里迷惑。
# help 指向一个类实例
>>> type(help)
<class '_sitebuiltins._Helper'>
# help对象的字符串表示
>>> help
Type help() for interactive help, or help(object) for help about object.
# 等价于执行 help.__call__(help)
>>> help(help)
site.py模块 与 -S 选项
上文中提到 -S 选项表示Python启动时不要加载 site模块。
https://docs.python.org/3/library/site.html site模块会把site-packages目录添加到模块搜索路径中,并且添加一些内置函数,例如quit(),help()等。
# 使用-S选项
[stack@tony-devstack nova]$ python3 -S
Python 3.7.5 (default, Nov 14 2019, 12:57:28)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
# 检查模块搜素路径
>>> import sys
>>> sys.path
['',
'/usr/local/lib/python37.zip',
'/usr/local/lib/python3.7',
'/usr/local/lib/python3.7/lib-dynload']
# 可以导入标准库模块
>>> import io
>>> io
<module 'io' from '/usr/local/lib/python3.7/io.py'>
# 无法导入site-packages目录下的模块
>>> import flake8
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'flake8'
# quit()/exit()/help()函数皆不可用
>>> quit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'quit' is not defined
>>> exit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'exit' is not defined
>>> help()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'help' is not defined
# 不使用 -S 选项
[stack@tony-devstack site-packages]$ python3
Python 3.7.5 (default, Nov 14 2019, 12:57:28)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
# 注意模块搜索路径中包括了site-packages目录
>>> import sys
>>> sys.path
['',
'/usr/local/lib/python37.zip',
'/usr/local/lib/python3.7',
'/usr/local/lib/python3.7/lib-dynload',
'/usr/local/lib/python3.7/site-packages']
# 成功导入了site-packages/目录下的flake模块
>>> import flake8
>>> flake8
<module 'flake8' from '/usr/local/lib/python3.7/site-packages/flake8/__init__.py'>
# exit()/quit()/help()都存在
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>> quit
Use quit() or Ctrl-D (i.e. EOF) to exit
>>> help
Type help() for interactive help, or help(object) for help about object.
# exit和quit都是 _sitebuiltins.Quitter类的实例
>>> type(exit)
<class '_sitebuiltins.Quitter'>
>>> type(quit)
<class '_sitebuiltins.Quitter'>
# help也是一个类实例
>>> type(help)
<class '_sitebuiltins._Helper'>
# exit与quit并不指向同一个实例,尽管作用相同。
>>> exit is quit
False
# 打印出的字符床略有不同。
>>> quit
Use quit() or Ctrl-D (i.e. EOF) to exit
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit