文档章节

python入门(九)-- 模块与包

兴趣使然的程序员
 兴趣使然的程序员
发布于 2017/05/15 09:48
字数 2340
阅读 21
收藏 1

1、模块

1.1、模块与模块导入

模块是包括Python定义和声明的文件。文件名就是模块名加上.py后缀。模块的模块名(作为一个字符串)可以由全局变量_name_得到。

相对Java的.java文件,python中的.py文件更类似于C中的头文件:

# 一个只有两个函数的模块,命名为fibo.py
 

def fib(n):
    """打印斐波那契数组"""
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()


def fib2(n):
    """生成斐波那契数组"""
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result
# 在另外的文件中导入模块
import fibo

# 通过模块名直接访问函数
fibo.fib(5)
fib_ = fibo.fib2(5)

# 通过_name_全局属性查看模块名
fibo.__name__
# 还可以直接导入函数
from fibo import fib, fib2

# 就不需要通过模块名就可以直接调用
fib(50)
# 或者一次性导入所有
from fibo import *

注意:

  • 一次性导入所有模块并不是推荐的做法

除此之外需要注意的是:

  • 和Java运行jar文件类似,可以直接在python控制台直接运行.py文件:
python myproject.py <arguments>

         如果想要接收控制台传入的参数的参数的话,需要引入sys模块,例如:

# 导入sys模块
import sys

print("命令行参数如下:")
# 通过sys.argv获取参数列表
for i in sys.argv:
    print(i)

# 通过sys.path[0]获取文件路径
print('\n\nPython 路径为:',sys.path[0],'\n')
E:\pythonTest>python Test.py 1
命令行参数如下:
Test.py
1


Python 路径为: E:\pythonTest
  • 每个import语句只会被执行一次,如果被import的模块中有可执行的代码块(除了函数定义以外的代码块,一般用于初始化全局参数),这些代码块在import之前就会执行。如果不希望一些代码块被执行,可以用__name__(注意这里是两个下划线)进行控制,(当__name__为“main”时表明该模块自身在运行,否则是被引入)。 if __name__ == '__main__': 这条语句,它的作用是,只有在当前模块名为 __main__ 的时候(即作为脚本执行的时候)才会执行此 if 块内的语句。换句话说,当此文件以模块的形式导入到其它文件中时,if 块内的语句并不会执行。:
# 注意,只要当前模块被其他模块import了,下面的代码都会执行。和Java中的静态代码块有点类似。
print("程序在自身中运行,在其他文件中也运行")

# 这些代码只有在自身模块中运行。在其他模块中不运行
if __name__ == "__main__":
    print('程序在自身运行')
  • 除此之外还可以使用dir()函数找到模块内定义的所有名称,以一个字符串列表的形式返回:
import fibo

# 获取指定模块的可访问所有名称(全局变量和函数名)
print(dir(fibo))

# 如果不指定参数的话,dir()会返回当前模块可访问的所有名称
print(dir())

 

1.2、模块的搜索路径

在导入一个叫fibo的模块时,python解释器会先在当前目录中搜索名为fibo.py的文件。

如果没有找到的话,接着回到sys.path变量(如之前所提及,是当前能访问的路径的列表)中查找。sys.path变量的初始值(默认值)来自如下:

  • 输入脚本的目录(当前目录)
  • 环境变量PYTHONPATH表示的目录列表中搜索
  • Python默认安装路径中搜索

1.3、标准模块

Python带有一个标准模块库,这些模块内置于解释器中。和Java中不同,python的这些标准模块库多数依赖于底层平台,是为了给系统调用等操作系统原生访问提供接口。例如winreg模块只在Windows系统上才有。

1.3.1 Linux下的os 模块

os 模块提供了与操作系统相关的功能。你可以使用如下语句导入它:

>>> import os

getuid() 函数返回当前进程的有效用户 id。

>>> os.getuid()
500

getpid() 函数返回当前进程的 id。getppid() 返回父进程的 id。

>>> os.getpid()
16150
>>> os.getppid()
14847

uname() 函数返回识别操作系统的不同信息,在 Linux 中它返回的详细信息可以从 uname -a 命令得到。uname() 返回的对象是一个元组,(sysname, nodename, release, version, machine)

>>> os.uname()
('Linux', 'd80', '2.6.34.7-56.fc13.i686.PAE', '#1 SMP Wed Sep 15 03:27:15 UTC 2010', 'i686')

getcwd() 函数返回当前工作目录。chdir(path) 则是更改当前目录到 path。在例子中我们首先看到当前工作目录是 /home/shiyanlou,然后我们更改当前工作目录到 /Code 并再一次查看当前工作目录。

>>> os.getcwd()
'/home/shiyanlou'
>>> os.chdir('Code')
>>> os.getcwd()
'/home/shiyanlou/Code'

所以现在让我们使用 os 模块提供的另一个函数来创建一个自己的函数,它将列出给定目录下的所有文件和目录。

def view_dir(path='.'):
    """
    这个函数打印给定目录中的所有文件和目录
    :args path: 指定目录,默认为当前目录
    """
    names = os.listdir(path)
    names.sort()
    for name in names:
        print(name, end =' ')
    print()

使用例子中的 view_dir() 函数。

>>> view_dir('/')
.bashrc .dockerenv .profile bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

os 模块还有许多非常有用的函数,你可以在这里阅读相关内容。

1.4、“编译的”Python文件

Python是一种解释型语言,这意味着它和Java、C#等都不同(Java中会先将代码编译为.class文件然后交由JVM解释为机器码执行,C#类似),python文件是在运行的时候将程序翻译成机器语言。

但是为了实现“跨平台”和“加快加载模块的速度”,python会在__pycache__目录下以"module.version.pyc"(例如__pycache__/fibo.cpytion-33.pyc)的形式缓存每个模块编译后的版本

Python会自动通过检查源文件和编译版的修改日期来确定它是否过期并需要重新编译。

其余需要注意的是:

  • 对于直接从命令行加载的模块,Python永远会重新编译而不会从缓存中读取
  • 如果没有源模块(即只有编译版),python不会检查缓存(此时不检查也无所谓)。但是需要注意的是如果要支持没有源模块的发布,编译后的模块必须在源目录下
  • 编译缓存并不会使模块的运行速度变快,但是会使加载的速度变快

2、包

2.1、基本使用

和Java中的包的概念类似,python中的包同样用于更好的管理模块以及避免命名冲突。包的表示也和Java中的类似,例如A.B表示了名为A的包,和名为B的模块。

需要注意的和Java中不同的是,为了让Python把目录当做包目录中必须包含__init__.py文件。一般情况下,只需要一个空的__init__.py文件即可,当然也可以在__init__.py文件中执行包的初始化代码。

引用包和引用模块一样,也有三种方式:

# 每次都导入特定的模块
import package.fibo

# 每次调用的时候都需要些完整路径
package.fibo.fib(5)

# fibo.fin(5)或者fib(5)都会报错
# 导入指定模块
from package import fibo

# 这种方式就无需写包前缀
fibo.fib(5)
# 还可以导入指定的函数、类或变量
from package.fibo import fib

# 这种方式就无需写任何前缀
fib(5)

需要注意的是:

  • 使用import...的时候,import进来的必须是包或者模块
  • 使用from...import...的时候,可以import进来包、模块以及模块中定义的其他命名(函数、类或者变量),推荐使用form...import...。
  • 当import后面跟着的只到包时,并不会自动引入包下的所有模块。需要使用__all__属性指定想要导入的模块。

2.2、import * 与 __all__变量

在python中使用import * 时,如果没有定义 __all__ , from sound.effects import * 语句不会从 sound.effects 包中导入所有的子模块。

无论包中定义多少命名,只能确定的是导入了 sound.effects 包(可能会运行 __init__.py 中的初始化代码)以及包中定义的所有命名会随之导入。

如果希望使用import * 以节省敲打代码的工作量,可以在__init__.py文件中定义__all__变量,指定在使用import * 时导入的模块:

__all__ = ["echo", "surround", "reverse"]

虽然这样可以实现,但是实际工作中还是不推荐这种写法,推荐使用form import。

2.3、包内引用

在一个父包下,引用其他子包下的模块可以使用相对路径:

  • . 表示同一个包下
  • .. 表示上级目录下
  • ..pakage 表示上级目录的pakage包下

3、标准模块和第三方模块查找

Python 吸引人的一点是其有众多的模块可以使用,对于自带模块,可以看看 Python3 的官方文档,对于第三方模块,可以在 PyPI 上找找。很多时候你都能找到合适的包帮你优雅的完成部分工作。比如 argparse 模块帮你非常容易的编写用户友好的命令行接口。

© 著作权归作者所有

共有 人打赏支持
兴趣使然的程序员
粉丝 23
博文 112
码字总数 87412
作品 0
深圳
程序员
私信 提问
Python第二章包入门实战-张明阳-专题视频课程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a2011480169/article/details/83579572 Python第二章包入门实战—496人已学习 课程介绍 本次视频重点介绍了P...

安静的技术控
02/11
0
0
Python基础总结成千行代码,让Python入门更简单!

只要学会这千行代码,不管你是零基础还是弱基础或是没有接触过编程,都可以快速入门Python!当时我就不信邪啊,等我看完之后,即使作为一个Python老鸟了,还是领会到了很多教授他的独特见解!...

糖宝lsh
09/10
0
0
python 入门笔记 (模块)

一、模块基础 1、模块 自我包含,且有组织的代码片段就是模块 模块是Pyhon最高级别的程序组织单元,它将程序代码和数据封装起来以便重用。实际的角度,模块往往对应Python程序文件。 每个文件...

QEfarmer
2015/04/03
0
1
编程语言太难学?只因你还没试过Python!

Python语言可能是第一种即简单又功能强大的编程语言。它不仅适合于初学者,也适合于专业人员使用,更加重要的是,用Python编程是一种愉快的事。本身将帮助你学习这个奇妙的语言,并且向你展示...

极客学院
2015/05/18
2.1K
7
2018Python网络爬虫与文本挖掘技术培训班

各科研院所单位: 随着互联网的发展,网络信息呈现指数式增长,要在短时间内获取大量信息,网络爬虫无疑是一种最适合的方法。通过爬虫获取的海量信息,我们可以对其进行进一步的分析:市场预...

朱苗
06/07
174
0

没有更多内容

加载失败,请刷新页面

加载更多

《碎玉投珠》的读后感想法心得范文3800字

《碎玉投珠》的读后感想法心得范文3800字: 《碎玉投珠》是晋江作者北南2018年的作品,内容主要讲述了其17年的《两小无嫌猜》中副cp师父师叔的爱情故事。 个人并没有看过北南其他的作品,这篇...

原创小博客
26分钟前
0
0
Confluence 6 文档主题合并问答

在 Confluence 官方 前期发布的消息 中,文档主题在 Confluence 6.0 及其后续版本中已经不可用。我们知道你可能对这个有很多好好奇的问题,因此我们在这里设置了一个问答用于帮助你将这个主题...

honeymose
38分钟前
2
0
java框架学习日志-2

上篇文章(java框架学习日志-1)虽然跟着写了例子,也理解为什么这么写,但是有个疑问,为什么叫控制反转?控制的是什么?反转又是什么? 控制其实就是控制对象的创建。 反转与正转对应,正转...

白话
今天
6
0
Integer使用双等号比较会发生什么

话不多说,根据以下程序运行,打印的结果为什么不同? Integer a = 100;Integer b = 100;System.out.println(a == b);//print : trueInteger a = 200;Integer b = 200;System.out.pr...

兜兜毛毛
昨天
11
0
CockroachDB

百度云上的CockroachDB 云数据库 帮助文档 > 产品文档 > CockroachDB 云数据库 > 产品描述 开源NewSQL – CockroachDB在百度内部的应用与实践 嘉宾演讲视频及PPT回顾:http://suo.im/5bnORh ...

miaojiangmin
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部