python模块讲解_python模块详解

使用python时,常常会涉及到库的调用,这就需要掌握模块的基本知识。

本文分为如下几个部分概念说明

模块的简单调用

包的导入

特殊的__init__.py文件

导入模块的搜索路径

__all__

绝对引用与相对引用

import运行本质

if __name__ == '__main__'

概念说明

这里厘清python中模块、库、包之间的概念差异模块(module)其实就是py文件,里面定义了一些函数、类、变量等

包(package)是多个模块的聚合体形成的文件夹,里面可以是多个py文件,也可以嵌套文件夹

库是参考其他编程语言的说法,是指完成一定功能的代码集合,在python中的形式就是模块和包

模块的简单调用

比如我们有一个trymodule的文件夹,里面有一个first.py文件,文件中的内容如下

a = 1

def myfun(s):

print(s + 1)

在trymodule的文件夹下打开命令行窗口(按住shift单击鼠标右键,选择“在此处打开命令窗口”),输入python进入命令行交互模式

>>> import first

>>> a

Traceback (most recent call last):

File "", line 1, in

NameError: name 'a' is not defined

>>> first.a

1

>>> first.myfun(2)

3

所以说first.py文件就是一个模块,可以用import导入,里面变量都要用first.前缀来引用,如果想不使用这个前缀可以这样

>>> from first import a

>>> a

1

其他用法如下

# 重命名

>>> from first import myfun as addone

>>> addone(4)

5

# 导入模块中全部变量

>>> from first import *

>>> myfun(2)

3

# 一次导入多个变量

>>> from first import a, myfun

>>> a

1

包的导入

在trymodule文件夹中新建folder1文件夹,我们想让folder1文件夹成为一个包。文件夹里新建abcd.py文件,文件中内容如下

b = 2

class Myclass:

def __init__(self, name, age):

self.name = name

self.age = age

def get_info(self):

print('my name is{name}and age is{age}'.format(name = self.name, age = self.age))

此时在folder1文件夹中新建一个__init__.py文件,否则程序会将这个文件夹当成普通文件夹来处理而不是一个包。这个__init__.py文件中可以什么都不填。

注:python3.3+已经可以省略掉空白的__init__.py 文件。

此时文件结构如下

trymodule

│ first.py

├───folder1

│ │ abcd.py

│ │ __init__.py

我们还是在trymodule文件夹下打开命令行,进入python交互模式

我们来看一下下面几种导入方式

>>> import folder1

>>> folder1.abcd.b

Traceback (most recent call last):

File "", line 1, in

AttributeError: module 'folder1' has no attribute 'abcd'

>>> from folder1 import abcd

>>> bob = abcd.Myclass(name = 'Bob', age = 20)

>>> bob.name

'Bob'

>>> bob.get_info()

my name is Bob and age is 20

>>> from folder1.abcd import b

>>> b

2

>>> import folder1.abcd

>>> abcd.b

Traceback (most recent call last):

File "", line 1, in

NameError: name 'abcd' is not defined

>>> folder1.abcd.b

2

>>> import folder1.abcd as aa

>>> aa.b

2

注意:只是导入包不能随便使用其中的模块,要导入到具体模块或者变量的层次

文件夹与文件之间可以用.也可以用from import格式,而文件与里面的变量之间只能用from import格式,即不能import folder1.abcd.b

特殊的__init__.py文件

__init__.py文件其实是一个特殊的文件,它相当于名为folder1模块,即如果使用import folder1则可以调用在__init__.py文件文件中定义的变量。

将__init__.py文件编写如下

from folder1.abcd import b

c = 3

在trymodule文件夹下打开命令行,进入python交互模式

>>> import folder1

>>> folder1.c

3

>>> folder1.b

2

>>> from folder1 import b

>>> b

2

对比之前的from folder1.abcd import b,使用__init__.py文件可以将常用的一些变量、函数、甚至模块导入以方便调用。

导入模块的搜索路径

用import hello时,python会搜寻hello.py文件,搜索顺序如下首先搜寻内置模块是否有hello(所以我们定义的模块名不要和内置模块相同)

如果内置模块没有,则看下面这些目录里有没有

>>> import sys

>>> sys.path

['', 'C:\\Program Files\\Anaconda3\\python35.zip', 'C:\\Program Files\\Anaconda3\\DLLs', 'C:\\Program Files\\Anaconda3\\lib', 'C:\\Program Files\\Anaconda3', 'C:\\Program Files\\Anaconda3\\lib\\site-packages', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\Sphinx-1.4.6-py3.5.egg', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\snownlp-0.12.3-py3.5.egg', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\setuptools-27.2.0-py3.5.egg']

其中第一个''表示当前的工作路径,我们可以看出安装的第三方包所在路径('C:\\Program Files\\Anaconda3\\lib\\site-packages')也在这个列表之中,所以无论工作路径在哪里,都能搜寻到这些包。

如果想添加搜索路径,可以参考这篇文章

__all__

首先要明确,import *的方式无法导入以下划线开头的变量名

__init__.py文件内容更改如下

from folder1.abcd import b

c = 3

_e = 4

python交互模式下

>>> from folder1 import *

>>> c

3

>>> _e

Traceback (most recent call last):

File "", line 1, in

NameError: name '_e' is not defined

而如果指定导入是可以的

>>> from folder1 import c

>>> c

3

>>> from folder1 import _e

>>> _e

4

如果定义了__all__,则import *就可以导入下划线开头的变量

__init__.py文件内容更改如下

from folder1.abcd import b

__all__ = ['c', '_e']

c = b + 1

_e = 4

python交互模式下

>>> from folder1 import *

>>> b

Traceback (most recent call last):

File "", line 1, in

NameError: name 'b' is not defined

>>> c

3

>>> _e

4

可见import *只会导入__all__中指定的变量,无论是否以下划线开头。这样限制可以防止import *命令导入太多变量污染命名空间,过滤掉一些中间变量如b

绝对引用与相对引用

python中的import分为绝对引用和相对引用两种。它们之间的差异在于,引用模块时 定位被引用模块位置 的方式不同绝对引用是通过.的连接,指定出最高级文件(夹),到目标文件的绝对路径。我们上面的所有用法都属于绝对引用。

而相对引用是 指定待引用模块与当前文件的相对位置,.表示上一级文件

绝对引用类似这样from folder.abcd import myclass

相对引用类似这样from .abcd import myclass

在实际使用中,无论是绝对导入还是相对导入都要注意,如何导入与被调用位置有关。

以下面的文件结构为例

folder1

│ first1.py

│ first2.py

└─folder2

| second1.py

| second2.py

└─folder3

| third1.py

| third2.py

下面分为两种情况

1.folder1是一个项目,运行这个项目需要在folder1文件夹中打开cmd,运行python first1.py

# first1.py

from first2 import sth # OK

from folder1.first2 import sth # ERROR

from .first2 import sth # ERROR

from folder2.second1 import sth # OK

# second1.py

from folder2.second2 import sth # OK

from .second2 import sth # OK

from second2 import sth # ERROR

(注意first1引用first2 与 second1引用second2 的区别)

2.folder1是一个包,一般使用时,是在外面的文件夹中import这个包

# first1.py

from folder1.first2 import sth # OK

from .first2 import sth # OK

from first2 import sth # ERROR

from . import first2 # OK

import .first2 # ERROR

from folder1.folder2 import second1 # OK

from .folder2 import second1 # OK

# second1.py

from folder1.folder2 import second2 # OK

from . import second2 # OK

from .. import first1 # OK

from ..folder3 import third1 # OK

规律绝对引用就是从包的位置一直往下,写到目标文件位置

相对引用,用.代替当前文件所在目录,用..代替再上一级目录,用点来回溯,之后往下写到目标文件位置。

.只能放在from后,不能放import后。

相对引用的好处在于,代码中不需要出现folder1这个名称,因此当包的名称改变时,里面代码不需要做任何改变;或者有的用户要装两个版本的包,把其中一个版本的包重命名了,此时使用相对引用也不会出问题。

另外,以second1.py为例,如果其中有一些相对引用的代码,在folder1的上一层文件夹调用

python folder1/folder2/second1.py

这时相当于在folder2文件夹中调用second1.py文件,会报错。但如果像下面这样就可以正常运行

python -m folder1.folder2.second1

import运行本质

使用import语句,要明确两件事

(1)执行导入模块命令时,会首先检查待导入的模块是否在当前已有模块之中,如果有则跳过import。因此模块之间相互引用不会导致无限循环。

查看当前已导入模块使用下面方法

import sys

sys.modules

得到结果是一个字典,键是模块名,值是文件所在路径

(2)import语句与文件执行

在这样的文件结构下

trymodule

│ first.py

├───folder1

│ │ abcd.py

│ │ __init__.py

folder1是一个package,abcd是一个moduleimport folder1 只是导入package,相当于执行__init__.py文件

from folder import abcd则执行了__init__.py文件文件与abcd.py文件

from folder1.abcd import b其实也执行了__init__.py文件文件与abcd.py文件

(要知道执行了什么,可以在这些文件之中添加print语句,看是否打印出结果)

知道这个执行原理,可以更好理解前面得到的一些结论首先是在__init__.py文件中什么都没有的情况下,import folder1无法调用abcd模块中的变量,是因为相当与运行了一个空文件,没有将整个包导入工作空间

abcd模块中定义了print语句后,import两次,只有第一次会print出值,说明第二次检查出模块已在导入之列,忽略了这条import命令

一个例子import numpy as np,之后可以这样调用np.random.normal()

但import skimage,不可以调用skimage.io.imread(),要import skimage.io才可以

这是因为numpy文件夹中的_init_.py文件中有一句from . import random;而skimage没有

更多运行细节可以参考这篇文章

if __name__ == '__main__'

我们经常会在别人的代码中发现if __name__ == '__main__',为了理解它的作用,我们来看下面的例子

在folder1文件夹下新建new.py文件,里面内容为

print(__name__)

在folder1文件夹下打开命令行,输入

python new.py

返回结果是__main__

在trymodule文件夹下打开命令行,进入python交互模式

>>> from folder1 import new

folder1.new

>>> print(__name__)

__main__

>>> print(new.__name__)

folder1.new

上面测试结果说明直接运行文件和import文件是有差异的,差异在于二者的__name__变量不同。__name__变量是一个特殊的变量,每个py文件运行时都会对应一个__name__变量,即使在交互模式下也可以查看这个变量值。

所以if __name__ == '__main__'的作用就很好理解了,即import时不执行下面的代码,只有在直接执行这个文件时才运行之后的代码。这算是一种约定俗成的写法,如果不怕文件被import,可以不用这个。

专栏信息

专栏目录:目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT常用问题

Int 装QString QString::number(changInt, 10) QString 转 QByteArray QByteArray macValueui->lineEdit->text().mid(4,8).toLatin1(); 把QByteArray转成QString QString s; s.prepend(postData); ui->textBrowser->append(s); 获取系统时间 QDateTime time QD…

用Python语言对任意图像进行m*n的均匀分块(思路非常清晰,步骤简单)

主要用途:处理图片数据集 1 对单个图片进行分块 import numpy as np import matplotlib.pyplot as plt import cv2def divide_method1(img,m,n):#分割成m行n列print(img.shape)h, w img.shape[0],img.shape[1]gx np.round(h).astype(np.int)gy np.round(w).asty…

17.3.12---urlparse模块的URL下载

1---urlparse模块是一个解析与泛解析Web网址URL字符串的一个工具 urlparse模块会将一个普通的url解析为6个部分,返回的数据类型都是元祖,同时,他还可以将已经分解后的url在组合成url地址 返回六个部分,分别是:scheme&a…

C语言变量和函数命名规范

C 语言变量和函数命名规范: 关于C语言变量和函数命名规范 据考察,没有一种命名规则可以让所有的程序员赞同,程序设计教科书一般都不指定命名规则。命名规则对软件产品而言并不是“成败悠关”的事,我们不要化太多 精力试图发明世界上最好的命据…

python爬虫用什么软件写_python爬虫怎么写

如今很多有编程能力的小伙伴已经不满足手动搜索内容了,都希望通过编写爬虫软件来快速获取需要的内容,那么如何使用python制作爬虫呢?下面小编给大家讲解一下思路 工具/原料 python 方法/步骤 1 首先我们需要确定要爬取的目标页面内容&#xf…

花书《深度学习》代码实现:01 线性代数:基本概念+代码实现基本运算

1 标量、向量、矩阵和张量 2 矩阵和向量相乘 3 单位矩阵和逆矩阵 3.0 单位矩阵 a np.identity(3) # 三行三列单位矩阵 3.1 矩阵的逆 A [[1.0,2.0],[3.0,4.0]] A_inv np.linalg.inv(A) print("A 的逆矩阵", A_inv) 3.1 转置 A np.array([[1.0,2.0],[1.0,0…

【Pytorch神经网络理论篇】 38 Transformers:安装说明+应用结构+AutoModel类

同学你好!本文章于2021年末编写,获得广泛的好评! 故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现, Pytorch深度学习理论篇(2023版)目录地址…

python微信自动发消息_如何利用python3实现微信定时自动发消息和图片?

python代码: import itchat import time itchat.auto_login(hotReloadTrue) AutoList ["",""]#需要发送消息的好友,可以不止一个 message ""#需要发送的消息 path ""#需要发送图片的位置 while True: time_now time.st…

C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它...

C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它 网上的代码都比较复杂,还是这个简单 见代码, 简易解决办法: 主窗体代码 using System; using System.Collections.Generic; using System.ComponentModel;…

AttributeError: module ‘torch.utils‘ has no attribute ‘data‘

一、解决问题 AttributeError: module torch.utils has no attribute data 二、解决思路 属性错误:模块的torch.utils没有属性data 三、解决方法 只需在顶行添加此代码即可! import torch.utils.data # 新添加代码

nordic 协议栈区别

S110 指的是从设备的协议栈 S120 指的是主设备的协议栈 S130 SoftDevice是符合蓝牙4.1规范的协议堆栈,包含了所有蓝牙智能协议层直至包含GATT/GAP。它支持多链路中心、周边、观察器和播送器任务、GATT服务器和客户机,以及由事件驱动、异步和线程安全的G…

clone是深拷贝还是浅拷贝_Python中的浅拷贝和深拷贝

本文翻译自copy in Python (Deep Copy and Shallow Copy),讲述了在Python语言中浅拷贝与深拷贝的不同用法。全文系作者原创,仅供学习参考使用,转载授权请私信联系,否则将视为侵权行为。码字不易,感谢支持。以下为全文内…

在mybatis中resultMap与resultType的区别

MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMapresultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用但是resultType跟resultMap不能同时存在。在MyBatis进行查询映射的时候,其实查询出来…

【Pytorch神经网络实战案例】32 使用Transformers库的管道方式实现:加载指定模型+文本分类+掩码语言建模+摘要生成+特征提取+阅读理解+实体词识别

管道方式是Transformers库中高度集成的极简使用方式。使用这种方式来处理NLP任务,只需要编写几行代码就能实现。通过本例的练习可以使读者对Transformers库的使用快速上手。 1 在管道方式中指定NLP任务 Transfomers库的管道方式使用起来非常简单,核心步…

QT创建文件夹

最近在做项目的时候,需要创建一个新的文件夹保存临时文件,但是很长时间都没有解决这个问题,今天终于解决了,拿出来和网友分享一下Qt中创建文件夹的方法。如下代码是在单击按钮后,先判断文件夹是否存在,若不…

jqprint获取打印页数_如何将每张打印多页PPT的PDF变成常规课件

在工作和学习中,经常会收到各种 PDF 文件,尤其是老师的课件。为了防止学生大量上传到各种文库网站赚积分,或者为了方便学生打印出来预习复习。通常,会在每页 PDF 里面,打印多张 PPT 内容。一般是 6 张或 9 张&#xff…

Pycharm报错:Process finished with exit code -1066598274 (0xC06D007E)

【问题描述】pycharm运行到np.linalg.slogdet()时报错Process finished with exit code -1066598274 (0xC06D007E),检查发现该函数输入shape就会报错 【解决方法】将python3.8换成python3.6,问题解决!(还是老老实实用3.6吧 -- &am…

rtt 打印 float

/*rtt print float*/float float_value;float_value 3.1415;char float_str[80];sprintf(float_str, "Float value is %f\n", float_value); NRF_LOG_PRINTF(float_str);

Hibernate学习笔记③

数据库关系 多对多:通过第三张表来建立关系 第三张表至少包含两个字段作为外键且字段是其他两张表的主键 Hibernate一对多的操作 (1)一对多映射配置 步骤: 首先创建两个存在一对多关系的实体类两个实体类需要建立一对多的关系:在多…

vba 判断文本框内容是否为空_【VBA】 数据输入 Inputbox 基本语法

在使用Excel 的过程中,如果需要用户输入简单的数据,作为“已知数”,那么可以使用inputbox 函数显示一个对话框,供用户在对话框中输入数据。 Inputbox 函数语法在一对话框来中显示提示,等待用户输入正文或按下按钮&…