热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[Python]模块、包

1.模块与import语句任何Python源文件都能以模块的形式使用,例如:#spam.pya37deffoo():print(Imfooandais%s%a)defbar(

1. 模块与import语句

任何Python源文件都能以模块的形式使用,例如:

# spam.py
a = 37
def foo():
    print("I'm foo and a is %s" % a)
def bar():
    print("I'm bar and I'm calling foo")
class Spam(object):
    def grok(self):
        print("I'm Spam.grok")

要以模块的形式加载这段代码,可以使用import spam语句。首次使用import加载模块时,它将做3件事:
1) 创建新的命名空间,用作在相应源文件中定义的所有对象的容器。
2) 在新创建的命名空间中执行模块中包含的代码。
3) 在调用函数中创建名称为引用模块命名空间,这个名称与模块的名称相匹配,例如:

import spam
x = spam.a
spam.foo()
s = spam.Spam()
s.grok()

import执行已加载源的文件中的所有语句。要导入多个模块,可以为import提供逗号分隔的模块名称列表,例如:

import socket, os, re

用于引用模块的名称可以使用as限定符进行更改,例如:

import spam as sp
import socket as net
sp.foo()
sp.bar()
net.gethostname()

import语句可以出现在程序中的任何位置,但是每个模块中的代码仅加载和执行一次。
 

2. 从模块导入选定符号

from语句用于将模块中的具体定义加载到当前命名空间中。from语句相当于import,但它不会创建一个名称来引用新创建的模块命名空间,而是将对模块中定义的一个或多个对象的引用放到当前命名空间中。例如:

from spam import foo
foo()
spam.foo() # NameError

from语句还会接受用逗号分隔的对象名称列表,例如:

from spam import(foo, bar, Spam)

另外,as限定符可用于重命名使用from导入的具体对象,例如:

from spam import Spam as Sp
s = Sp()

"*"星号通配符也可用于加载模块中的所有定义,但以下划线开头的定义除外,例如:

from spam import *

form module import 语句只能在模块最顶层使用。通过定义列表__all__,模块可以精确控制from spam import \导入的名称集合,例如:

# spam.py
__all__ = ['bar', 'spam']

使用from导入形式导入定义不会更改定义的作用域规则。函数的全局命名空间始终是定义该函数的模块,而不是将函数导入并调用该函数的命名空间。
 

3. 模块搜索路径

加载模块时,解释器在sys.path路径中搜索字典列表。sys.path中的第一个条目通常是空字符串,表示当前正在使用的字典。sys.path中的其他条目可能包含字典名称、.zip归档文件和.egg文件。各个条目在sys.path中列出的顺序决顺决定了加载模块时的搜索顺序。
可以将一组模块打包为一个文件,设想创建两个模块foo.py和bar.py,并将它们放在一个名为mymodules.zip的zip文件中,就可以以如下方式添加到搜索路径:

import sys
sys.path.append("mymodules.zip")
import foo, bar

zip文件可以与常规路径名称组件混合使用,例如:

sys.path.append("/tmp/modules.zip/lib/python")

从zip中导入需要注意一些限制。首先,只能从归档文件中导入.py、.pyw、.pyc和.pyo文件。而且,从归档文件加载.py文件时,Python不会建.pyc和.pyo文件,这会导致加载模块时的性能下降。
 

4. 模块加载和编译

使用import加载的模块实际上可分为4个通用类别:
1) 使用Python编写的代码
2) 已被编译为共享库或DLL的C或C++扩展
3) 包含一组模块的包
4) 使用C编写并链接到Python解释器的内置模块
查看编块(以foo为例)时,解释器在sys.path下的每个目录中搜索以下文件(按搜索顺序列出):
1) 目录foo,它定义了一个包
2) foo.pyd、foo.so、foomodule.so或foomodule.dll(已编译的扩展)
3) foo.pyo(只适用于使用了-O或-OO选项时)
4) foo.pyc
5) foo.py(Windows上还会查找.pyw文件)
对于.py文件,首次导入模块时,它会被编译为字节码并作为.pyc文件写回磁盘。在后续导入中,解释器将加载这段预编译的字节码,除非.py文件的修改日期要更新一些。.pyc文件与解释器的-O选项结合,文件已删除了行号、断言和其他调试信息的字节码。如果指定-OO选项,还会从文件中删除文档字符串。
只有使用import语句才能将文件自动编译为.pyc和.pyo文件。另外,如果包含模块的.py文件的目录不允许写入,将不会创建这些文件。解释器的-B选项也可以禁止生成这些文件。
如果存在.pyc和.pyo文件,则可以没有相应的.py文件。但即使没有提供源文件,仍然可以检查并找到大量细节。并且,为某个Python版本生成的.pyc文件可能不适用于其他的Python版本。
 

5. 包

包可用于将一组模块分组到一个常见的包名称下,这有助于解决不同应用程序中使用的模块名称之间的命名空间冲突问题。包是通过使用与其相同的名称创建目录,并在该目录中创建文件__init__.py来创建的。可以将如下形式组织一个包:

Graphics/
    __init__.py
    Primitive/
        __init__.py
        lines.py
        fill.py
        text.py
    Graph3d/
        __init__.py
        plot2d.py
    Graph4d/
        __init__.py
        plot3d.py
    png.py
    tiff.py
    jpeg.py

import语句用于通过多种方式从包中加载模块:
1) import Graphics.Primitive.fill
2) from Graphics.Primitive import fill
3) from Graphics.Primitive.fill import floodfill
只要第一次导入包中的任何部分,就会执行__init__.py中的代码。这个文件可以为空。在import语句执行期间,遇到的所有__init__.py文件都会执行。因此,之前示例中的import Graphics.Primitive.fill语句将会首先执行Graphics目录中的__init__.py文件,然后执行Primitive目录中的__init__.py文件。
处理以下这条语句时需注意:

from Graphics.Primitive import *

使用该语句希望将与某个包相关联的所有子模块导入到当前命名空间中,但是该语句只会导入在Primitive目录的__init__.py文件中定义的所有名称。这种行为可以通过定义列表__all__来修改,例如:

# Graphics/Primitive/__init__.py
__all__ = ["lines", "text", "fill"]

如果想要导入同一个包中的其他子模块时,可以使用相对导入,例如:

# fill.py
from . import lines

相对导入也可以加载同一个包的不同目录中包含的子模块,例如:

# plot2d.py
from ..Primitives import lines

相对导入只能命名用from module import symbol形式的导入语句来指定。因此import ..Primitives.lines或import .lines这样的语句在语法上是不对的。
最后,Python导入一个包时,它将定义特殊变量__path__,该变量包含一个目录列表,查找包的子模块时将搜索这个列表。__path__可通过__init__.py文件中包含的代码访问,最初包含的一项具有包的目录包称。如果有必要,包可以向__path__列表提供更多目录,更改查找子模块时使用的搜索路径。


推荐阅读
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 标题: ... [详细]
  • 本文介绍了win7系统休眠功能无法启动和关闭的解决方法,包括在控制面板中启用休眠功能、设置系统休眠的时间、通过命令行定时休眠、手动进入休眠状态等方法。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了一种图片处理应用,通过固定容器来实现缩略图的功能。该方法可以实现等比例缩略、扩容填充和裁剪等操作。详细的实现步骤和代码示例在正文中给出。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
author-avatar
誓言俱乐部
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有