博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Python高手之路(第3版)》——第2章 模块和库 2.1 导入系统
阅读量:6101 次
发布时间:2019-06-20

本文共 3859 字,大约阅读时间需要 12 分钟。

本节书摘来自异步社区《Python高手之路(第3版)》一书中的第2章,第2.1节,作者[法]Julien Danjou,王飞龙 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

第2章 模块和库

2.1 导入系统

要使用模块和库,需要先导入。

>>> import this  The Zen of Python, by Tim Peters  Beautiful is better than ugly.  Explicit is better than implicit.  Simple is better than complex.  Complex is better than complicated.  Flat is better than nested.  Sparse is better than dense.  Readability counts.  Special cases aren't special enough to break the rules.  Although practicality beats purity.  Errors should never pass silently.  Unless explicitly silenced.  In the face of ambiguity, refuse the temptation to guess.  There should be one-- and preferably only one --obvious way to do it.  Although that way may not be obvious at first unless you're Dutch.  Now is better than never.  Although never is often better than *right* now.  If the implementation is hard to explain, it's a bad idea.  If the implementation is easy to explain, it may be a good idea.  Namespaces are one honking great idea -- let's do more of those!

导入系统是相当复杂的,不过你可能已经了解了一些基本知识。这里会介绍一些关于这一子系统的内部机理。

sys模块包含许多关于Python导入系统的信息。首先,当前可导入的模块列表可以通过sys.moudle变量获取。它是一个字典,其中键(key)是模块名字,对应的值(value)是模块对象。

>>> sys.modules['os']  

许多模块是内置的,这些内置的模块在sys.builtin_module_names中列出。内置的模块可以根据传入Python构建系统的编译选项的不同而变化。

导入模块时,Python会依赖一个路径列表。这个列表存储在sys.path变量中,并且告诉Python去哪里搜索要加载的模块。可以在代码中修改这个列表,根据需要添加或删除路径,也可以通过编写Python代码直接修改环境变量PYTHONPATH。下面的方法几乎是相等的。

>>> import sys  >>> sys.path.append('/foo/bar')$ PYTHONPATH=/foo/bar python  >>> import sys  >>> '/foo/bar' in sys.path  True

在sys.path中的顺序很重要,因为需要遍历这个列表来寻找请求的模块。

也可以通过自定义的导入器(importer)对导入机制进行扩展。Hy正是利用这种技术告诉Python如何导入其他非标准的.py或者.pyc文件的。

顾名思义,导入钩子机制是由PEP 302() 定义的。它允许扩展标准的导入机制,并对其进行预处理,也可以通过追加一个工厂类到sys.path_hooks来添加自定义的模块查找器(finder)。

模块查找器对象必须有一个返回加载器对象的find_module(fullname, path=None)方法,这个加载器对象必须包含一个负责从源文件中加载模块的load_module(fullname)方法。

为了进一步说明,下面给出了Hy利用自定义的导入器导入.hy而不是.py结尾的源文件的方法,见示例2.1。

示例2.1 Hy模块导入器

class MetaImporter(object):       def find_on_path(self, fullname):            fls = ["%s/__init__.hy", "%s.hy"]            dirpath = "/".join(fullname.split("."))            for pth in sys.path:                 pth = os.path.abspath(pth)                 for fp in fls:                      composed_path = fp % ("%s/%s" % (pth, dirpath))                      if os.path.exists(composed_path):                           return composed_path       def find_module(self, fullname, path=None):            path = self.find_on_path(fullname)            if path:                 return MetaLoader(path)  sys.meta_path.append(MetaImporter())

一旦路径被确定是有效的且指向了一个模块,就会返回一个MetaLoader对象。

Hy模块加载器

class MetaLoader(object):       def __init__(self, path):            self.path = path       def is_package(self, fullname):            dirpath = "/".join(fullname.split("."))            for pth in sys.path:                 pth = os.path.abspath(pth)                 composed_path = "%s/%s/__init__.hy" % (pth, dirpath)                 if os.path.exists(composed_path):                      return True            return False       def load_module(self, fullname):            if fullname in sys.modules:                 return sys.modules[fullname]            if not self.path:                 return            sys.modules[fullname] = None            mod = import_file_to_module(fullname, self.path)  1          ispkg = self.is_package(fullname)            mod.__file__ = self.path            mod.__loader__ = self            mod.__name__ = fullname            if ispkg:                 mod.__path__ = []                 mod.__package__ = fullname            else:                 mod.__package__ = fullname.rpartition('.')[0]            sys.modules[fullname] = mod            return mod

1 import_file_to_module读取一个Hy源文件,将其编译成Python代码,并返回一个Python模块对象。

uprefix模块() 是这个功能起作用的另一个好的例子。Python 3.0到3.2并没有像Python 2中用来表示Unicode字符串的u前缀,这个模块通过在编译前删除字符串的前缀u来确保在2.x和3.x之间的兼容性。

转载地址:http://posza.baihongyu.com/

你可能感兴趣的文章
linux 文件与目录管理
查看>>
Linux学习总结(2)——linux常用命令大全
查看>>
架构师不可不知的十大可扩展架构
查看>>
网页变灰的CSS代码
查看>>
python导入模块时的执行顺序
查看>>
cpu、内存、缓存、硬盘使用率
查看>>
25、性能测试总体流程
查看>>
零长度数组的妙用
查看>>
从零开始写一个发送h264的rtsp服务器(下)
查看>>
CentOS 7.5 ——如何开放80、8080、3306等端口
查看>>
ubuntu (14.04) 卸载 gnome 系统桌面
查看>>
protobuf学习
查看>>
视频:青春期(青春痘1)
查看>>
Android - 通过真实案例学习解内存泄漏问题,最终发现Android原生Bug
查看>>
thinkphp ,laravel,yii2运行环境搭建.
查看>>
LDA进阶(Dynamic Topic Models)
查看>>
centos安装openssl
查看>>
HashSet,TreeSet和LinkedHashSet
查看>>
CentOS下的Autoconf和AutoMake(完善篇) 3
查看>>
jquery attr()方法 添加,修改,获取对象的属性值。
查看>>