这就是Python 模块(纯python模块)
off999 2024-09-20 22:41 24 浏览 0 评论
1. 模块简介
1.1 什么是模块
编写较长程序时,建议用文本编辑器代替解释器,执行文件中的输入内容,这就是编写 脚本 。随着程序越来越长,为了方便维护,最好把脚本拆分成多个文件。编写脚本还一个好处,不同程序调用同一个函数时,不用每次把函数复制到各个程序。为实现这些需求,Python 把各种定义存入一个文件,在脚本或解释器的交互式实例中使用。这个文件就是 模块
模块即是一系列功能的结合体。
1.2 为什么使用模块
提高了代码的可维护性,不用重复造 轮子 提升开发效率.
1.3 模块的各类
python
pip
1.4 模块的表现形式
- 使用python编写的代码(.py文件),就是平时写的一个python文件
- 已被编译为共享库或DLL的C或C++扩展
- 包好一组模块的包(文件夹)包其实就是多个py文件(模块)的集合包里面通常会含有一个 __init__.py 文件(在python3中这个文件可以没有)
- 使用C编写并链接到python解释器的内置模块
2. import句式
导入模块使用关键字 import 加 py 文件名,不要加 .py .
示例:
# 导入内置模块
>>> import time
>>> time.time() # 直接使用
1637651203.9467623
#导入自定义
# 代码文件:foo.py
name = 'Hans'
def hello(name):
print("Hello, %s" % name)
# 导入
>>> import foo
>>> foo.
foo.hello( foo.name
>>> foo.name
'Hans'
>>> foo.hello(foo.name)
Hello, Hans
>>> foo.hello("Jack")
Hello, Jack
# 同一个模块多次导入
# 代码文件:boo.py
print("hello")
# 导入
>>> import boo # 第一次导入,会执行里面的代码。
hello
>>> import boo # 第二次导入,不会执行
>>> import boo # 第二次导入,不会执行
>>> import boo # 第二次导入,不会执行
# 多次导入相同模块 只会执行一次
模块首次导入发生了什么?(以导入 boo.py 中导入 foo.py 为例)
# foo.py
name = 'Hans'
def hello(name):
print("Hello, %s" % name)
# boo.py
import foo
print("hello world")
foo.name
foo.hello(foo.name)
foo.hello("Jack")
# 执行结果:
hello world
Hello, Hans
Hello, Jack
- 运行导入文件( boo.py )产生该文件的全局名称空间
- 运行 foo.py
- 产生 foo.py 全局名称空间 运行 foo.py 文件内代码 将产生的名字全部存档于 foo.py 名称空间
- 在导入文件名称空间产生一个 foo 的名字指向 foo.py 全局名称空间
import 方法导入模块后就可以使用模块中的所有的变量名或函数名,而且绝对不会冲突,因为调用的时候已经指定了要使用哪个包中的那个变量或函数
3. from...import...句式
from...import... 句式为从哪个包或模块中导入哪个模块或功能。
示例:
# foo.py代码:
name = 'Hans'
def hello(name):
print("Hello, %s" % name)
def hi():
print("Hi, world")
# boo.py代码:
from foo import hi #在boo中只使用foo的hi功能
print("hello world")
hi()
# 执行结果:
hello world
Hi, world
# 代码 boo.py
from foo import hi
from foo import hi
from foo import hi
执行结果:
from foo
# from...import...多次导入也只会导入一次
使用 from...import... 导入:
- 先产生执行文件的全局名称空间
- 执行模块文件 产生模块的全局名称空间
- 将模块中执行之后产生的名字全部存档于模块名称空间中
- 在执行文件中有一个 hi 执行模块名称空间中 hi 指向的值
导入
# foo.py 代码
print("from foo")
name = 'Hans'
def hello(name):
print("Hello, %s" % name)
def hi():
print("Hi, world")
# boo.py 代码
from foo import hi
print("hello world")
def hi():
print("from boo hi")
hi()
# 执行结果:
from foo
hello world
from boo hi # 发现执行hi()的结果为boo.py中的函数不是从foo.py中导入进来的hi
from...import... 指定的导入某个名字
在使用的时候直接写名字即可 但是当前名称空间有相同名字的时候,就会产生冲突 使用的就变成了当前名称空间
4. 导入方式的扩展
4.1 使用别名
# import导入
>>> import foo as f # 把foo定义别名为f,这时只能调用f,如果再调用foo就会报错,说foo没有定义
>>> f.name
'Hans'
# from ... import ...导入
>>> from foo import hi as h # 把hi定义为别名为h,调用的时候直接使用h即可,同理hi也不能使用
>>> h()
Hi, world
4.2 连续导入
# import导入
>>> import sys
>>> import os
# 上面的导入方式可以写成下面:
>>> import sys, os # 这种方式和上面的方式功能是一样的
# from ... import ...导入
>>> from foo import hello
>>> from foo import hi
# 上面的导入方式可以写成下面:
>>> from foo import hello, hi # 这种方式和上面的方式功能是一样的
import 使用连续导入多个模块时,如果多个模块功能相似或者属于同一个系列时推荐使用。
如果功能不同并且不属于一个系列 那么推荐分行导入
4.3 通用导入
如果使用from ... import ...方式导入一个模块里全部功能时,最基本的方法是依次导入
>>> from foo import hello, hi, name
# 或
>>> from foo import hello
>>> from foo import hi
>>> from foo import name
#可以使用* 号把一个模块里的全部功能都导入
>>> from foo import *
# 如果一个模块里有三个功能,在使用from ... import ... 想让人用其中两个可以使用__all__
# 代码:
print("from foo")
name = 'Hans'
def hello(name):
print("from foo. Hello, %s" % name)
def hi():
print("from foo Hi")
def play():
print("from foo play")
__all__ = ['hi', 'play'] # 在被导入的模块文件中可以使用__all__指定可以被导入使用的名字
# 执行:
>>> from foo import *
from foo
>>> hi()
from foo Hi
>>> play()
from foo play
>>> hello("Hans")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'hello' is not define
4.4 判断py文件是作为模块文件还是执行文件
可以使用函数自带的 __name__ 方法
# foo.py 代码
print("from foo")
name = 'Hans'
def hello(name):
print("from foo. Hello, %s" % name)
def hi():
print("from foo Hi")
def play():
print("from foo play")
print("__name__: %s" % __name__)
# 执行如果:
from foo
__name__: __main__
# 如果foo.py是直接执行时。__name__为 __main__
# 如果foo.py 当成模块在别的文件里导入时:
# importTest.py 代码
import foo
#执行结果:
from foo
__name__: foo
# 如果foo.py文件是被当做模块导入则返回模块名
#
# 一个py文件当成模块被导入时,它会直接执行py文件里的全部代码,可以利用__name__来判断它是否被当成模块导入,如果是则不执行
# 代码 foo.py
def hello(name):
print("from foo. Hello, %s" % name)
def hi():
print("from foo Hi")
def play():
print("from foo play")
if __name__ == '__main__':
print("from foo")
name = 'Hans'
# 代码 importTest.py
import foo
# 执行结果:
#之前导入的时候会直接打印: from foo
5. 模块导入的顺序
模块导入的顺序:
- 先从内存中查找
- 再去内置模块中查找
- 最后去sys.path系统路径查找(自定义模块)
如果都没有查找到则报错
# 1.在内存中查找
# foo.py 代码:
def hello(name):
print("from foo. Hello, %s" % name)
def hi():
print("from foo Hi")
def play():
print("from foo play")
if __name__ == '__main__':
print("from foo")
name = 'Hans'
# importTest.py 代码:
from foo import hello
import time
print("Hello")
time.sleep(10)
hello("time")
# 执行结果:
Hello
#在time.sleep(10)的时候把foo.py删除,这时foo.py已经加载到内存中,所以下面依然执行
from foo. Hello, time
#如果再执行则会报错
# 2.再去内置模块中查找
# 可以自己定义一个和内置模块同名的模块,看看导入的是谁
# 自己编写:time.py 代码:
print("time...")
# boo.py 代码:
import time
print(time)
# 执行结果:
<module 'time' (built-in)>
# 发现time为内置的模块,所以在给py文件命名的时候不要与内置模块名冲突
# sys.path系统路径查找
>>> import sys
>>> sys.path
['', '/usr/lib64/python36.zip', '/usr/lib64/python3.6', '/usr/lib64/python3.6/lib-dynload', '/usr/local/lib64/python3.6/site-packages', '/usr/local/lib/python3.6/site-packages', '/usr/local/lib/python3.6/site-packages/cloud_init-17.1-py3.6.egg', '/usr/lib/python3.6/site-packages', '/usr/lib64/python3.6/site-packages']
# ''为当前目录,然后依次查找
当某个自定义模块查找不到的时候解决方案:
1.自己手动将该模块所在的路径添加到sys.path中
# 查看当前目录
[root@hans_tencent_centos82 tmp]# pwd
/tmp
[root@hans_tencent_centos82 tmp]# python3
>>> import foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'foo'
# 提示没有foo模块。
# 查找foo.py模块在哪
[root@hans_tencent_centos82 module]# pwd
/tmp/module
[root@hans_tencent_centos82 module]# ls -lrt foo.py
-rw-r--r-- 1 root root 202 Nov 23 16:54 foo.py
# foo.py在/tmp/module目录下。
# /tmp/module加入到sys.path
>>> import sys
>>> sys.path.append('/tmp/module')
>>> import foo
>>> sys.path
['', '/usr/lib64/python36.zip', '/usr/lib64/python3.6', '/usr/lib64/python3.6/lib-dynload', '/usr/local/lib64/python3.6/site-packages', '/usr/local/lib/python3.6/site-packages', '/usr/local/lib/python3.6/site-packages/cloud_init-17.1-py3.6.egg', '/usr/lib/python3.6/site-packages', '/usr/lib64/python3.6/site-packages', '/tmp/module']
# 可以看到 '/tmp/module'添加到sys.path
2.使用 from...import... 句式
from 文件夹名称.文件夹名称 import 模块名
from 文件夹名称.模块名称 import 名字
# from 文件夹名称.文件夹名称 import 模块名
# foo.py在/tmp/module目录下。
# 当前目录为/tmp
# 使用from...import...
# 执行结果:
>>> from module import foo
>>> foo.hi()
from foo Hi
#当前在/tmp下,而foo.py在/tmp/module/test/下
[root@hans_tencent_centos82 tmp]# ls -lrt /tmp/module/test/foo.py
-rw-r--r-- 1 root root 202 Nov 23 16:54 /tmp/module/test/foo.py
>>> from module.test import foo
>>> foo.play()
from foo play
# from 文件夹名称.模块名称 import 名字
#只导入foo模块中的一个功能:
>>> from module.test.foo import play
>>> play()
from foo play
6. 循环导入
不允许出现循环导入
真要出现了,一般解决方法(就是明知道有循环导入了还是让它运行,一错再错方法):
- 调换顺序
将彼此导入的句式放在代码的最后 - 函数形式
将导入的句式放入函数体代码 等待所有的名字加载完毕之后再调用
相关推荐
- 面试官:来,讲一下枚举类型在开发时中实际应用场景!
-
一.基本介绍枚举是JDK1.5新增的数据类型,使用枚举我们可以很好的描述一些特定的业务场景,比如一年中的春、夏、秋、冬,还有每周的周一到周天,还有各种颜色,以及可以用它来描述一些状态信息,比如错...
- 一日一技:11个基本Python技巧和窍门
-
1.两个数字的交换.x,y=10,20print(x,y)x,y=y,xprint(x,y)输出:102020102.Python字符串取反a="Ge...
- Python Enum 技巧,让代码更简洁、更安全、更易维护
-
如果你是一名Python开发人员,你很可能使用过enum.Enum来创建可读性和可维护性代码。今天发现一个强大的技巧,可以让Enum的境界更进一层,这个技巧不仅能提高可读性,还能以最小的代价增...
- Python元组编程指导教程(python元组的概念)
-
1.元组基础概念1.1什么是元组元组(Tuple)是Python中一种不可变的序列类型,用于存储多个有序的元素。元组与列表(list)类似,但元组一旦创建就不能修改(不可变),这使得元组在某些场景...
- 你可能不知道的实用 Python 功能(python有哪些用)
-
1.超越文件处理的内容管理器大多数开发人员都熟悉使用with语句进行文件操作:withopen('file.txt','r')asfile:co...
- Python 2至3.13新特性总结(python 3.10新特性)
-
以下是Python2到Python3.13的主要新特性总结,按版本分类整理:Python2到Python3的重大变化Python3是一个不向后兼容的版本,主要改进包括:pri...
- Python中for循环访问索引值的方法
-
技术背景在Python编程中,我们经常需要在循环中访问元素的索引值。例如,在处理列表、元组等可迭代对象时,除了要获取元素本身,还需要知道元素的位置。Python提供了多种方式来实现这一需求,下面将详细...
- Python enumerate核心应用解析:索引遍历的高效实践方案
-
喜欢的条友记得关注、点赞、转发、收藏,你们的支持就是我最大的动力源泉。根据GitHub代码分析统计,使用enumerate替代range(len())写法可减少38%的索引错误概率。本文通过12个生产...
- Python入门到脱坑经典案例—列表去重
-
列表去重是Python编程中常见的操作,下面我将介绍多种实现列表去重的方法,从基础到进阶,帮助初学者全面掌握这一技能。方法一:使用集合(set)去重(最简单)pythondefremove_dupl...
- Python枚举类工程实践:常量管理的标准化解决方案
-
本文通过7个生产案例,系统解析枚举类在工程实践中的应用,覆盖状态管理、配置选项、错误代码等场景,适用于Web服务开发、自动化测试及系统集成领域。一、基础概念与语法演进1.1传统常量与枚举类对比#传...
- 让Python枚举更强大!教你玩转Enum扩展
-
为什么你需要关注Enum?在日常开发中,你是否经常遇到这样的代码?ifstatus==1:print("开始处理")elifstatus==2:pri...
- Python枚举(Enum)技巧,你值得了解
-
枚举(Enum)提供了更清晰、结构化的方式来定义常量。通过为枚举添加行为、自动分配值和存储额外数据,可以提升代码的可读性、可维护性,并与数据库结合使用时,使用字符串代替数字能简化调试和查询。Pytho...
- 78行Python代码帮你复现微信撤回消息!
-
来源:悟空智能科技本文约700字,建议阅读5分钟。本文基于python的微信开源库itchat,教你如何收集私聊撤回的信息。[导读]Python曾经对我说:"时日不多,赶紧用Python"。于是看...
- 登录人人都是产品经理即可获得以下权益
-
文章介绍如何利用Cursor自动开发Playwright网页自动化脚本,实现从选题、写文、生图的全流程自动化,并将其打包成API供工作流调用,提高工作效率。虽然我前面文章介绍了很多AI工作流,但它们...
- Python常用小知识-第二弹(python常用方法总结)
-
一、Python中使用JsonPath提取字典中的值JsonPath是解析Json字符串用的,如果有一个多层嵌套的复杂字典,想要根据key和下标来批量提取value,这是比较困难的,使用jsonpat...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python自定义函数 (53)
- python进度条 (67)
- python吧 (67)
- python字典遍历 (54)
- python的for循环 (65)
- python格式化字符串 (61)
- python串口编程 (60)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python字典增加键值对 (53)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python人脸识别 (54)
- python多态 (60)
- python命令行参数 (53)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)