python好用的模块和包_Python模块和包详细讲解与实例分析

一丶模块

我们经常说模块模块的,究竟什么是模块呢?

一个模块就是包含了Python定义和声明的文件,文件名就是模块名字加上.py的后缀

但其实import加载的模块分为四个通用类别:

1.使用Python编写的代码(.py文件)

2.已被编译为共享库或DLL的C或C++扩展

3.包好一组模块的包

4.使用C编写并链接到Python解释器的内置模块

import

from import导入的过程中发生了什么事儿?

1.找到要被导入的模块

2.判断这个模块是否被导入过

3.如果这个模块没被导入

创建一个属于这个模块的命名空间

执行这个文件

找到你要导入的变量

给你要导入的变量创建一个引用,指向你要导入的变量

自定义模块:my_module.py,文件名my_module.py,模块名 my_module

importsysprint(sys.modules) #导入的模块会写在这里面

sys.path.append(my_module) #将my_module模块写入里面

import my_module #导入my_module模块

print(my_module.name) #调用my_module中的name

为模块起别名

#给模块起别名

importmy_moudle as m

m.read1#给模块起别名,起了别名之后,使用这个模块就都使用别名引用变量了

导入多个模块

#导入多个模块

importos,timeimportos as o,time as t#规范建议:先导入内置模块,再导入扩展(第三方)模块,再导入自定义模块

from..import

from my_module importread1defread1():print('in my read1')from my_module importread2

read1()

需要特别强调的一点是:python中的变量赋值不是一种存储操作,而只是一种绑定关系,如下:

from my_module importmoney,read1

money=100 #将当前位置的名字money绑定到了100

print(money) #打印当前的名字

read1() #读取my_module.py中的名字money,仍然为1000

'''from the my_module.py

my_module->read1->money 1000'''

from my_module import *

from my_module import * #将模块my_module中所有的名字都导入到当前名称空间

print(money)print(read1)print(read2)print(change)'''执行结果:

from the my_module.py

'''

__all__能约束*导入的变量的内容

__all__ = ['name','read1','read2']from my_module import *

print(name)

read1()

read2()

把模块当做脚本执行

当一个py文件

当做一个脚本的时候:能够独立的提供一个功能,能自主完成交互

当成一个模块的时候,能够被导入这个调用这个功能,不能自主交互

我们可以通过模块的全局变量__name__来查看模块名:

当做脚本运行:

__name__等于'__main__'

当做模块导入:

__name__=模块名

作用:用来控制.py文件在不同的应用场景下执行不同的逻辑

if__name__=='__main__'

deffib(n):

a, b= 0, 1

while b

a, b= b, a+bprint()if __name__ == "__main__":print(__name__)

num= input('num :')

fib(int(num))

模块搜索路径

Python解释器在启动时会自动加载一些模块,可以使用sys.modules查看

在第一次导入某个模块时(比如my_module),会先检查该模块是否已经被加载到内存中,如果有则直接引用,如果没有,解释器则会查找同名的内建模块,如果还没有找到就送sys.path给出的目录列表中依次寻找my_module.py文件

所以总结模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块

importsysimportcalculateprint(sys.path)

path= r'D:Learnday21模块的循环引用'sys.path.append(path)

编译Python文件

1.如果是在命令中被直接导入模块,则按照这种方式,每次导入都会重新编译,并且不会存储编译后的结果

2.如果源文件不存在,那么缓存的结果也不会被使用,如果想在没有源文件的情况下来使用编译后的结果,则编译后的结果必须在源目录下

dir()函数

内建函数dir是用来查找模块中定义的名字,返回一个有序字符串列表.如果没有参数,dir()列举出当前定义的名字

importmy_module

dir(my_module)

二丶包

1.无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法

2.包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)

3.import导入文件时,产生名称空间中的名字来源于文件,import包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包的本质就是在导入该文件

强调:

1.在Python3中,即使包下没有__init__.py文件,import包仍然不会报错,而在Python2中,包下一定要有该文件,否则import包报错

2.创建包的目的不是为了运行,而是被导入使用,记住,包只是模式的一种形式而已,包即模块

importos

os.makedirs('glance/api')

os.makedirs('glance/cmd')

os.makedirs('glance/db')

l=[]

l.append(open('glance/__init__.py','w'))

l.append(open('glance/api/__init__.py','w'))

l.append(open('glance/api/policy.py','w'))

l.append(open('glance/api/versions.py','w'))

l.append(open('glance/cmd/__init__.py','w'))

l.append(open('glance/cmd/manage.py','w'))

l.append(open('glance/db/models.py','w'))

map(lambda f:f.close() ,l)

创建目录代码

glance/ #Top-level package

├──__init__.py #Initialize the glance package

├── api#Subpackage for api

│ ├──__init__.py

│ ├── policy.py

│ └── versions.py

├── cmd#Subpackage for cmd

│ ├──__init__.py

│ └── manage.py

└── db#Subpackage for db

├──__init__.py

└── models.py

目录结构

#文件内容

#policy.py

defget():print('from policy.py')#versions.py

defcreate_resource(conf):print('from version.py:',conf)#manage.py

defmain():print('from manage.py')#models.py

defregister_models(engine):print('from models.py:',engine)

文件内容

在导入包时必须遵守一个原则:凡是在导入时带点的,点的左边都必须是一个包

from..import

需要注意的是from后导入的模块,必须是明确的一个不能带点,否则会有语法错误

from glance.db importmodels

models.register_models('mysql')from glance.db.models importregister_models

register_models('mysql')

import

importglance.db.models

glance.db.models.register_models('mysql')

__init__.py文件

不管是哪种方式,只要是第一次导入包或者包的任何其他部分,都会依次执行包下的__init__.py文件,这个文件可以为空,但是也可以存在一些初始化包的代码

from glance.api import *

此处是想从包api中导所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all__:

#在__init__.py中定义

x=10

deffunc():print('from api.__init.py')__all__=['x','func','policy']

绝对导入和相对导入

绝对导入:以glance作为起始

相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同的目录内)

例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

在glance/api/version.py#绝对导入

from glance.cmd importmanage

manage.main()#相对导入

from ..cmd importmanage

manage.main()

特别需要注意的是:可以用import导入内置或者第三方模块(已经在sys.path中),但是要绝对避免使用import来导入自定义包的子模块(没有在sys.path中),应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式。

绝对导入:

glance/├──__init__.py from glance importapifrom glance importcmdfrom glance importdb

├── api

│ ├──__init__.py from glance.api importpolicyfrom glance.api importversions

│ ├── policy.py

│ └── versions.py

├── cmdfrom glance.cmd importmanage

│ ├──__init__.py

│ └── manage.py

└── dbfrom glance.db importmodels

├──__init__.py

└── models.py

绝对导入

绝对导入

相对导入:

glance/├──__init__.py from . import api #.表示当前目录

from . importcmdfrom . importdb

├── api

│ ├──__init__.py from . importpolicyfrom . importversions

│ ├── policy.py

│ └── versions.py

├── cmdfrom . importmanage

│ ├──__init__.py

│ └── manage.pyfrom ..api importpolicy#..表示上一级目录,想再manage中使用policy中的方法就需要回到上一级glance目录往下找api包,从api导入policy

└── dbfrom . importmodels

├──__init__.py

└── models.py

相对导入

相对导入

单独导入包

单独导入包名称时不会导入包中所有包含的所有子模块,如:

#在与glance同级的test.py中

importglance

glance.cmd.manage.main()'''执行结果:

AttributeError: module 'glance' has no attribute 'cmd''''

解决方法:

#glance/__init__.py

from . importcmd#glance/cmd/__init__.py

from . import manage

执行:

#在于glance同级的test.py中

importglance

glance.cmd.manage.main()

import glance 之后直接调用模块中的方法

glance/├──__init__.py from .api import *

from .cmd import *

from .db import *├── api

│ ├──__init__.py __all__ = ['policy','versions']

│ ├── policy.py

│ └── versions.py

├── cmd__all__ = ['manage']

│ ├──__init__.py

│ └── manage.py

└── db__all__ = ['models']

├──__init__.py

└── models.pyimportglance

policy.get()import glance

View Code

软件开发规范

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

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

相关文章

C语言之struct A *b和struct A c区别

struct A *b; 是指针 struct A c; 是定义了一个struct A对象,你得提供相应的结构体的具体定义 结构体A没有具体的定义,当struct A c时,实际是定义一个结构体变量,这是要分配存储空间的,空间大小依结构体中具体的变量而定,如果没有具体的结构体定义,编译器不知道结构体到底是什…

JS的类型转换

当string,number函数不被用作构造函数的可以当成转换函数 如 string(false),number(‘3’),boolean([]) Object(3) new number(3); 除了NULL和undefined以外任何值都具有toString()方法 JS 在执行程序的时候会自动检测表达式来进行变量转换。 显示转换变量&#xf…

linux 下执行.sh文件总是提示permission denied

今天执行.sh文件懂得时候提示 permission denied错误 解决办法: chmod 777 file.sh 或者 chmod+x file.sh 比如我们执行一个变量加1的时候,不能这样写 a = 1; a = $($a +1) echo $a 需要这样写: a=1 a=$(($a+1)) echo $a 还有写sh文件的时候代码之间不需要留下空格…

ahjesus解决win下U盘无法写入的问题

可能是由于不同品牌的U盘出厂时磁盘分区和格式化方式不同而引起的兼容性问题。解决方案如下 启动cmd。输入diskpart,启动DISKPART工具 在DISKPART窗口中输入以下命令: >list disk (此命令是列出所有磁盘驱动器,请务必看清楚你的…

[探索 .NET 6]01 揭开 ConfigurationManager 的面纱

在这个系列中,我将探索一下 .NET 6 中的一些新特性。已经有很多关于 .NET 6 的内容,包括很多来自 .NET 和 ASP.NET 团队本身的文章。在这个系列中,我将探索一下这些特性背后的一些代码。在这第一篇文章中,来研究一下 Configuratio…

mysql锁表_MySQL中Alter table 你不知道的性能问题

前言:MySQL 的大表运维总是令人头疼的一件事,特别是大表表结构的修改尤为困难。首先,alter table 的process不可被kill , 一旦执行就不可回退。其次,大多数的alter table操作都会涉及 lock --- copy to new table --- …

打印文件前,千万记得把弹窗叉掉!!!

1 父母能有多迷信?(素材来源网络,侵删)▼2 打印前千万记得把弹窗关掉(素材来源网络,侵删)▼3 挺好的(素材来源网络,侵删)▼4 饭桌上,领导叫你去…

Java队列集合的性能测试

同时开10个线程存入和取出100万的数据&#xff0c;结论如下&#xff1a; DoubleBufferedQueue < ConcurrentLinkedQueue < ArrayBlockingQueue < LinkedBlockingQueue 执行结果如下&#xff1a; 100万 DoubleBufferedQueue入队时间&#xff1a;9510 出队时间&#xff…

linux之man命令用法入门

man命令的解释: man的全称是manual,手册的意思,所以man命令有帮助解释其它命令的作用 基本用法: man + 命令 比如: man pwd 就会出现下面信息 PWD(1) User Commands PWD(1) //注意括号中的数字 NAME //关于命令的名次和说明pwd - print name of current/work…

Node webkit启动最大化窗口

<!DOCTYPE html> <html> <head> </head> <body> <p style"text-align:center;margin-top:10%;color:green;font-weight:bold;font-size:12px">正在加载中...</p> <script language"javascript" …

高效的动态URL限流实现

访问限流对于一个网关来说是个比较重要的功能&#xff0c;它可以根据不同服务的处理能力来控制相关的访问量&#xff0c;从而保障服务更可靠地运行。但是URL控制的路径比较多还加上可动态添加删除&#xff0c;大量的访问匹配会很容易引起性能上的问题&#xff0c;接下来讲解一下…

cocos2d-x学习 之一

最近准备学习cocos2d-x的开发&#xff0c;首先要搭建一下开发环境。今天就先搭建一下开发环境。本人系统为Mint-15 64位的linux&#xff0c;以下的开发环境只用于linux。首先到cocos2d-x的官网上下载安装包&#xff0c;由于cocos2d-x是开源的&#xff0c;所以我们可以查看源码&…

python里while的用法_Python学习笔记之While循环用法分析

本文实例讲述了Python学习笔记之While循环用法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;前面一篇《Python学习笔记之For循环用法》详细介绍了Python for循环&#xff0c;这里再来讲述一下while循环的使用方法&#xff1a;Python 中的While循环For 循环是一种有限…

linux环境下最简单的C语言例子

1、装好linux系统和配置GCC环境 给自己的电脑上安装linux系统,比如我用大的是ubuntu,然后在ubuntu上配置GCC环境,如果不知道配置,请百度“linux上怎么配置GCC环境” 2、打开终端创建文件写代码 用组合命令打开终端 Ctrl+Alt+T 用vim创建文件编写代码 vim hello.c再点击下…

在 App 扩展和主 App 间共享数据

tags: iOS 8,Swift,App Groups 随着 iOS 8 的发布&#xff0c;苹果为广大开发者很多新的 API&#xff0c;其中最突出显著的就非 App Extension 莫属了。这为开发者们又带来了很多机会。 而我们在开发 App Extension 的时候&#xff0c;基本大多数人都会遇到这样一个问题。就是由…

Java8 (1)

参考资料&#xff1a; 《Java8 in Action》 Raoul-Gabriel Urma 一、jdk8 客观的说&#xff0c;Java8是一次有重大演进的版本&#xff0c;甚至很多人认为java8所做的改变&#xff0c;在许多方面都比Java历史上任何一次改变都深远。 Scala&#xff0c;python这样优秀编程语言中对…

[探索 .NET 6]02 比较 WebApplicationBuilder 和 Host

这是『探索 .NET 6』系列的第二篇文章&#xff1a;01 揭开 ConfigurationManager 的面纱02 比较 WebApplicationBuilder 和 Host在 .NET 中&#xff0c;有一种新的“默认”方法用来构建应用程序&#xff0c;即使用 WebApplication.CreateBuilder()。在这篇文章中&#xff0c;我…

python计算公式分母有0_你知道Python中的浮点除法和积分除法吗,python,float,整除,都...

从python2.2开始&#xff0c;便有两种除法运算符&#xff1a;"/"、"//"。两者最大区别在&#xff1a;python2.2前的版本和python2.2以后3.0以前的版本的默认情况下&#xff0c;"/"所做的除法是以一种两个数或者多个数出现一个浮点数结果就以浮点…