[PYTHON] 核心编程笔记(12.Python模块)

简介:

12.1 什么是模块

当代码量变得很大,我们把代码分成若干有组织的代码段(模块),利用python调入已有模块,实现代码重用


12.2 模块和文件

模块名.py


12.2.1 模块名称空间

一个名称空间就是一个从名称到对象的关系映射集合


例如:string模块中的atoi()函数就是string.atoi()


如果我自己的模块mymodule里创建了一个atoi()函数,那么他的名字应该是mymodule.atoi()


12.2.2 搜索路径和路径搜索:


>>> import xxx

Traceback (most recent call last):

 File "<stdin>", line 1, in <module>

ImportError: No module named xxx


发送这种错误,解释器会告诉你它无法访问请求的模块,可能原因是模块不在搜索路径例,从而导致了路径搜索失败


默认搜索路径是在编译或是安装时指定的

一个是启动Python的shell或命令行的PYTHON环境变量


显示加载的默认搜索路径

>>> import sys

>>> sys.path

['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']


例子:

-------------------------------------

>>> import sys

>>> import mymodule

Traceback (most recent call last):

 File "<stdin>", line 1, in <module>

ImportError: No module named mymodule

>>> sys.path

['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']

>>> sys.path.append("/home/root/python")

>>> sys.path

['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/home/root/python']

-------------------------------------


使用sys.modules可以找到当前导入了哪些模块以及他们来自什么地方,和sys.path不同,sys.modules是一个字典,使用模块名作为键(key),对应物理地址作为值(value)


>>> sys.modules

{'copy_reg': <module 'copy_reg' from '/usr/lib/python2.7/copy_reg.pyc'>, 'sre_compile': <module 'sre_compile' from '/usr/lib/python2.7/sre_compile.pyc'>, '_sre': <module '_sre' (built-in)>, 'encodings': <module 'encodings' from '/usr/lib/python2.7/encodings/__init__.pyc'>, 'site': <module 'site' from '/usr/lib/python2.7/site.pyc'>, '__builtin__': <module '__builtin__' (built-in)>, 'sysconfig': <module 'sysconfig' from '/usr/lib/python2.7/sysconfig.pyc'>, '__main__': <module '__main__' (built-in)>, 'encodings.encodings': None, 'abc': <module 'abc' from '/usr/lib/python2.7/abc.pyc'>, 'posixpath': <module 'posixpath' from '/usr/lib/python2.7/posixpath.pyc'>, '_weakrefset': <module '_weakrefset' from '/usr/lib/python2.7/_weakrefset.pyc'>, 'errno': <module 'errno' (built-in)>, 'encodings.codecs': None, 'sre_constants': <module 'sre_constants' from '/usr/lib/python2.7/sre_constants.pyc'>, 're': <module 're' from '/usr/lib/python2.7/re.pyc'>, '_abcoll': <module '_abcoll' from '/usr/lib/python2.7/_abcoll.pyc'>, 'types': <module 'types' from '/usr/lib/python2.7/types.pyc'>, '_codecs': <module '_codecs' (built-in)>, 'encodings.__builtin__': None, '_warnings': <module '_warnings' (built-in)>, 'genericpath': <module 'genericpath' from '/usr/lib/python2.7/genericpath.pyc'>, 'stat': <module 'stat' from '/usr/lib/python2.7/stat.pyc'>, 'zipimport': <module 'zipimport' (built-in)>, '_sysconfigdata': <module '_sysconfigdata' from '/usr/lib/python2.7/_sysconfigdata.pyc'>, 'warnings': <module 'warnings' from '/usr/lib/python2.7/warnings.pyc'>, 'UserDict': <module 'UserDict' from '/usr/lib/python2.7/UserDict.pyc'>, 'encodings.utf_8': <module 'encodings.utf_8' from '/usr/lib/python2.7/encodings/utf_8.pyc'>, 'sys': <module 'sys' (built-in)>, 'codecs': <module 'codecs' from '/usr/lib/python2.7/codecs.pyc'>, 'readline': <module 'readline' from '/usr/lib/python2.7/lib-dynload/readline.so'>, '_sysconfigdata_nd': <module '_sysconfigdata_nd' from '/usr/lib/python2.7/_sysconfigdata_nd.pyc'>, 'os.path': <module 'posixpath' from '/usr/lib/python2.7/posixpath.pyc'>, 'sitecustomize': <module 'sitecustomize' from '/usr/lib/python2.7/sitecustomize.pyc'>, 'signal': <module 'signal' (built-in)>, 'traceback': <module 'traceback' from '/usr/lib/python2.7/traceback.pyc'>, 'linecache': <module 'linecache' from '/usr/lib/python2.7/linecache.pyc'>, 'posix': <module 'posix' (built-in)>, 'encodings.aliases': <module 'encodings.aliases' from '/usr/lib/python2.7/encodings/aliases.pyc'>, 'exceptions': <module 'exceptions' (built-in)>, 'sre_parse': <module 'sre_parse' from '/usr/lib/python2.7/sre_parse.pyc'>, 'os': <module 'os' from '/usr/lib/python2.7/os.pyc'>, '_weakref': <module '_weakref' (built-in)>}


12.3 名称空间


12.3.1 名称空间与变量作用域比较


12.3.2 名称查找,确定作用域,覆盖


访问一个属性时,解释器必须在三个名称空间中找

1.名称空间 2.全局名称空间 3.内建名称空间


例:


>>> def foo():

...     print "\ncalling foo()..."

...     bar = 200

...     print "in foo(), bar is ", bar

...

>>> bar = 100

>>> print "in __main__, bar is", bar

in __main__, bar is 100

>>> foo()


calling foo()...

in foo(), bar is  200


foo()函数局部名称空间里的bar变量覆盖了全局的bar变量.


12.3.3 无限制的名称空间


Python的一个特性在于你可以在任何需要放置数据的地方获得一个名称空间.


>>> def foo():

...     pass

...

>>> foo.__doc__ = "Oops,forgot to add doc str above!"

>>> foo.version = 0.2


12.4 导入模块

12.4.1 语句


使用import 语句导入模块,它的语法如下所示:


import module1


import module2[

.

.

import moduleN


也可以在一行导入多个模块


import module1[, module2[,... moduleN]]


12.4.2 from-import 语句:


在模块里导入指定的模块属性,也就是把指定名称导入到当前作用域

from module import name1[, name2[,... nameN]]


12.4.3 多行导入


从一个模块导入许多属性时,import行会越来越长,直到自动换行,而且只需一个 \


from Tkiner import Tk, Frame, Button, Entry, Canvas, \

Text,LEFT,DISABLED,NORMAL,RIDGE,END


12.4.4 扩展的import语句(as)


有时候你导入的模块或是模块属性名称已经在你程序中使用,或你不想使用导入的名字,或太长不便输入,所以普遍解决方案是把模块赋值给一个变量:


import longmodulename

short = longmodulename

del longmodulename


上边的例子,我们没有使用longmodulename.attribute,而使用short.attibute来访问相同的对象

更好的方法是可以使用扩展的import,你就可以在导入的同时制定局部绑定名字


import Tkinter

替换成:

import Tkinter as tk


from cgi import FieldStorage

替换成:

from cgi import FieldStorage as form


12.5 模块导入的特性


12.5.1 载入时执行模块



12.5.2  导入(import)和加载(load)

一个模块只被加载依次,无论它被导入多少次,所以加载只在第一次导入时发生


12.5.3 导入到当前名称空间的名称


调用from-import 可以把名字导入当前名称空间去,从而不需要使用属性/句点属性标示来访问模块的标识符


例如:你需要访问模块module中的var名字:

from module import var


使用单个var就可以访问它自身,把var导入到名称空间后就再没必要引用模块了

当然你也可以把指定模块的所有名称导入到当前名称空间里:

from module import *


12.5.4 被导入到导入者作用域的名字:


# vi imptee.py

-------------------

foo = 'abc'

def show():

print 'foo from imptee:',foo

-------------------


# vi impter.py

-------------------

from imptee import foo,show

show()

foo = 123

print 'foo from impter:',foo

show()

-------------------


# python impter.py

------------------------

foo from imptee: abc

foo from impter: 123

foo from imptee: abc

-------------------------


运行导入者,foo变量没有改变


解决办法:使用import和完整的标识符名称(句点属性标示)


# impter_new.py

-------------------

import imptee

imptee.show()

imptee.foo = 123

print 'foo from impter:',imptee.foo

imptee.show()

-------------------


# python impter_new.py

foo from imptee: abc

foo from impter: 123

foo from imptee: 123


12.5.5 关于__future__


使用from-import语句"导入"新特性,用户可以尝试一下新特性,以便在特性固定下来时修改程序,语法:

from __future__ import new_feature


12.5.6 警告框架


12.5.7 从ZIP文件中导入模块


12.5.8 "新的"导入钩子


12.6 模块内建函数


12.6.1 __import__()


它作为实际上导入模块的函数,意味着import语句调用__import__()函数完成它的工作,提供这个函数式为了让有需要的用户覆盖它,实现自定义的导入算法


__import__(module_name[, globals[, locals[, fromlist]]])


调用import sys语句可以使用下边的语法完成:

>>> sys = __import__('sys')


12.6.2 globals()和locals()


这两个内建函数分别返回调用者全局和局部名称空间的字典,在一个函数内部,局部名称空间代表在函数执行时候定义的所有名字,locals()函数返回的就是包含这些名字的字典,globals()会返回函数可访问的全局名字


>>> def foo():

...     print '\ncalling foo()...'

...     aString = 'bar'

...     anInt = 42

...     print "foo()'s globals:", globals().keys()

...     print "foo()'s locals:",locals().keys()

...

>>> print "__main__'s globals:", globals().keys()

__main__'s globals: ['__builtins__', '__package__', 'sys', '__name__', 'foo', '__doc__']


>>> print "__main__'s locals:", locals().keys()

__main__'s locals: ['__builtins__', '__package__', 'sys', '__name__', 'foo', '__doc__']

>>> foo()


calling foo()...

foo()'s globals: ['__builtins__', '__package__', 'sys', '__name__', 'foo', '__doc__']

foo()'s locals: ['anInt', 'aString']


12.6.3 reload()


reload()内建函数可以重新导入一个可以导入的模块,语法如下

reload(module)


12.7 包


包是一个有层次的文件目录结构,它定义了一个由模块和子包组成的Python应用程序执行环境

1.为平台的名称空间加入有层次的组织结构

2.允许程序员把有联系的模块组合到一起

3.允许分发者使用目录结构而不是一大堆混乱的文件

4.帮助解决有冲突的模块名称


与类和模块相同,包夜使用句点属性标示来访问他们的元素,使用标准的import和from-import语句导入包中的模块


12.7.1 目录结构:

Phone/

__init__.py

common_util.py

Voicedta/

__init__.py

Pots.py

Isdn.py

Fax/

   __init__.py

   G3.py

Mobile/

   __init__.py

   Analog.py

   igital.py

Pager/

   __init__.py

   Numeric.py


Phone是最顶层的包,Voicedta等是他的子包,我们可以这样导入子包:

import Phone.Mobile.Analog

Phone.Mobile.Analog.dial()


可使用from-import 实现不同需求的导入:


第一种方法是只导入顶层的子包,然后使用属性/点操作符乡下引用子包树:

from Phone import Moble

Moble.Analog.dial("555-1212")


此外,我们可以还引用更多的子包:

from Phone.Mobile import Analog

Analog.dial("555-1212")


事实上,你可以移植沿子包的树状结构导入:

from Phone.Mobile.Analog import dial

dial('555-1212')


12.7.2 使用from-import导入包


包同样支持from-import all语句:

from package.module import *


12.7.3 绝对导入


12.7.4 相对导入

绝对导入特性限制了模块作者的一些特权,失去了import语句的自由,必须有新的特性来满足程序员的需求,所以用import语句表示绝对导入,from-import语句表示相对导入


旧版本写法:

import Analog

from Analog import dial


新版本写法:

from Phone Mobile Analog import dial

from .Analog import dial

from ..common_util import setup

from ..Fax import G3.dial


12.8 模块的其他特性:


12.8.1 自动载入模块

sys.modules变量包含一个由当前载入到解释器的模块组成的字典,模块作为键,位置作为值


>>> import sys      

>>> sys.modules.keys()

['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings', 'abc', 'posixpath', '_weakrefset', 'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 'encodings.__builtin__', '_warnings', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', 'codecs', 'readline', '_sysconfigdata_nd', 'os.path', 'sitecustomize', 'signal', 'traceback', 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']


12.8.2 阻止属性导入


如果你不想让某个模块属性被"from module import *" 导入,那么你可以给你不想导入的属性名称加上一个下划线(_).不过如果你导入了整个模块或是你显式的导入某个属性(例如 import foo._bar),这个隐藏数据的方法就不起作用了


12.8.3 不区分大小的导入


12.8.4 原代码编译

一个UTP-8编码的文件可以这么显式:

#!/usr/bin/env python

#-*- coding: UTP_8 -*-


如果你执行或导入了包含非ASCII的Unicode字符串而没有在文件头部说明,那么你会在Python2.3得到一个DeprecationWarning 2.5会报语法错误


12.8.5 导入循环


# omh4cli.py

-------------------------

from cli4vof import cli4vof

# command line interface utility function

def cli_util():

pass


# overly massive handlers for the command line interface

def omh4cli():

  .

  .

     cli4vof()

  .

  .

   omh4cli()

---------------------------

在我们的例子中,如果加入一个"新功能",我们将创建一个新的cli4vof.py,而不是把新内容集成到omh4cli.py里:

---------------------

import omh4cli

# command-line interface for a very outstanding feature

def cli4vof():

omh4cli.cli_util()

---------------------


我们解决方法只是把import语句移到cli4vof()函数内部:

def cli4vof():

import omh4cli

omh4cli.cli_util()


这样,从omh4cli()导入cli4vof()模块会顺利完成,在omh4cli()被调用前它会被正确导入,只有在执行到cli4vof.cli4vof()时候才会导入omh4cli模块


12.8.5 模块执行

有很多方法可以执行一个Python模块:通过命令行shell,execfile(),模块导入,解释器的 -m选项


12.9 相关模块

....



     本文转自 showerlee 51CTO博客,原文链接:http://blog.51cto.com/showerlee/1335950,如需转载请自行联系原作者


相关文章
|
3天前
|
数据采集 机器学习/深度学习 数据挖掘
探索Python编程之美:从基础到进阶
【9月更文挑战第4天】在数字时代的浪潮中,编程已成为一种新兴的“超能力”。Python,作为一门易于上手且功能强大的编程语言,正吸引着越来越多的学习者。本文将带领读者走进Python的世界,从零基础出发,逐步深入,探索这门语言的独特魅力和广泛应用。通过具体代码示例,我们将一起解锁编程的乐趣,并理解如何利用Python解决实际问题。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你打开一扇通往高效编程的大门。
|
3天前
|
存储 开发者 Python
探索Python编程之美
【9月更文挑战第5天】在这篇文章中,我们将一起踏上一场Python编程的奇妙之旅。从基础语法到高级特性,我们将一步步揭开Python语言的神秘面纱。你将学习如何编写清晰、高效的代码,掌握函数、类和模块的使用,以及理解面向对象编程的核心概念。此外,我们还将探讨异常处理、文件操作等实用技能。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供宝贵的知识和技巧,让你在编程的道路上更加从容自信。
|
23小时前
|
安全 开发者 Python
揭秘Python IPC:进程间的秘密对话,让你的系统编程更上一层楼
【9月更文挑战第8天】在系统编程中,进程间通信(IPC)是实现多进程协作的关键技术。IPC机制如管道、队列、共享内存和套接字,使进程能在独立内存空间中共享信息,提升系统并发性和灵活性。Python提供了丰富的IPC工具,如`multiprocessing.Pipe()`和`multiprocessing.Queue()`,简化了进程间通信的实现。本文将从理论到实践,详细介绍各种IPC机制的特点和应用场景,帮助开发者构建高效、可靠的多进程应用。掌握Python IPC,让系统编程更加得心应手。
11 4
|
1天前
|
数据采集 机器学习/深度学习 存储
Python编程入门:从基础到实战
【9月更文挑战第6天】本文将引导你走进Python的世界,从零基础开始,逐步掌握Python的基础语法和常用库。我们将通过实例讲解,让你在轻松愉快的氛围中学习Python编程。最后,我们还将分享一些实用的技巧和资源,帮助你在学习过程中不断进步。让我们一起开启Python编程之旅吧!
20 4
|
1天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的编程实践:从Python到深度学习的探索之旅
【9月更文挑战第6天】 在人工智能的黄金时代,编程不仅仅是一种技术操作,它成为了连接人类思维与机器智能的桥梁。本文将通过一次从Python基础入门到构建深度学习模型的实践之旅,揭示编程在AI领域的魅力和重要性。我们将探索如何通过代码示例简化复杂概念,以及如何利用编程技能解决实际问题。这不仅是一次技术的学习过程,更是对人工智能未来趋势的思考和预见。
|
23小时前
|
Linux iOS开发 MacOS
从入门到精通:Python 系统编程中的跨平台兼容性攻略
【9月更文挑战第8天】在编程领域,Python 因其简洁强大而广受青睐。本文深入探讨 Python 系统编程中的跨平台兼容性策略,帮助开发者应对不同操作系统(如 Windows、Linux 和 macOS)间的差异。通过使用 `os` 和 `subprocess` 模块,文章详细讲解了如何处理文件路径、进程管理和环境变量等跨平台问题,使代码能够在多种平台上无缝运行。实践这些方法将助力开发者编写出更加稳健和兼容的 Python 程序。
6 2
|
2天前
|
存储 数据采集 人工智能
Python编程入门:从零基础到精通
【9月更文挑战第5天】本文将带你进入Python编程的世界,无论你是编程新手还是有一定基础的开发者,都可以通过本文快速掌握Python编程的基础知识和技能。我们将从Python的基本语法开始,逐步深入到面向对象编程、文件操作、网络编程等高级主题,最后还将介绍一些实用的Python库和框架,帮助你在实际项目中应用Python编程。通过阅读本文,你将能够编写出高效、简洁的Python代码,解决实际问题。
|
1天前
|
存储 开发者 Python
探索Python编程:从基础到高级应用
【9月更文挑战第6天】本文旨在引导读者从零开始学习Python编程,通过深入浅出的方式,介绍Python的基础语法、数据结构、面向对象编程以及高级特性。我们将通过实际代码示例,展示如何将理论知识应用于解决实际问题,帮助初学者建立扎实的编程基础,并激发进阶学习的兴趣。
|
3天前
|
Linux iOS开发 MacOS
Python系统编程高手进阶:跨平台兼容性?小菜一碟💪
【9月更文挑战第6天】当我们探讨Python系统编程时,跨平台兼容性至关重要。Python凭借其解释型语言特性和多平台解释器,确保了代码能够在Windows、Linux、macOS等多种环境中顺畅运行。本文将介绍Python跨平台运行的基本原理,以及如何处理文件路径差异和系统调用等问题,助你轻松应对跨平台挑战。
11 1
|
21小时前
|
存储 JSON API
Python编程:解析HTTP请求返回的JSON数据
使用Python处理HTTP请求和解析JSON数据既直接又高效。`requests`库的简洁性和强大功能使得发送请求、接收和解析响应变得异常简单。以上步骤和示例提供了一个基础的框架,可以根据你的具体需求进行调整和扩展。通过合适的异常处理,你的代码将更加健壮和可靠,为用户提供更加流畅的体验。
7 0