周末看到一个python的库:sh。功能是让你像调用方法那样调用系统中的命令。比方说你想调用系统的ls方法,普通的做法是: import subprocess;subprocess.call("ls") 虽然可用,但总是觉得不是一家人。用sh库的做法是: from sh import ls;ls() 就可以了,毫无违和感。
看到这个库的时候特别好奇是怎么实现的,于是看下源码。发现调用部分写的很巧妙。怎么实现的呢?
直观思维就是在sh的库里一定实现了一个ls的方法,然后绑定到了系统的ls命令上,然后对输出进行重定向。但如果真这么做的话,系统有多少个命令不就要实现多少个函数吗?于是看了下,果然不是这么做的,里面没有任何对应名称的函数。那怎么实现from sh import ls的呢?
带着疑问看了下代码,发现是通过ModuleType来实现的,模拟一下就是:
#coding:utf-8importsysfromtypesimportModuleTypeclassTenv(ModuleType):def__init__(self,self_module):self.self_module=self_moduledef__getattr__(self,name):return'%s to ->test'%nameif__name__=="__main__":passelse:self=sys.modules[__name__]sys.modules[__name__]=Tenv(self)
粘贴这段代码保存为modu.py,然后在同目录下进入python交互模式:
>>>frommoduimportthe5fire>>>printthe5firethe5fireto->test
自己尝试下,是不是有点意思。从这我们知道怎么从一个module中import出不存在的函数或者类了,那么它是怎么把import的函数绑定到系统中呢?
这个问题你可以看下源码,然后思考一下。
sh代码地址:https://github.com/amoffat/sh
- from the5fire.com
----EOF-----
微信公众号:Python程序员杂谈
微信公众号:Python程序员杂谈