Python基础知识(八)——模块与包

本文介绍了Python中的模块和包的概念,包括模块的导入方式、命名空间、作用域及其关系,以及包的创建、导入和使用。重点讲解了import和from...import...的区别,并探讨了包的结构和__init__.py的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模块

  • 模块是Python中最高级别的程序组织单元,它将程序代码和数据封装起来以便重用,而模块就对应Python中的程序文件(.py文件)
  • 模块也是Python对象,具有随机的名字属性用来绑定或引用
  • 模块能定义函数、类和变量。
  • 模块里也能包含可执行的代码。
  • 引入
    • import:导入一个整体的模块
    • from :从一个模块中获取一些特定的内容
    • reload:在不中止Python程序的情况下,重新导入模块文件内容的方法

导入模块:import
语法
import module[,module2[,…modulen]

  • import导入整个模块内容
  • 在当前路径搜索要导入的模块
  • 一个模块只会被导入一次
  • 模块中的内容是导入到模块的命名空间中的,访问模块中的方 法和属性时,必须使用模块名.方法名/属性名的格式
#test.py
def print_func(name):
	return ('hello',str(name)
#demo.py
import test
print(test.print_func('china'))

导入模块:from… import …
语法
from modname import name1[, name2[,… nameN]]

  • 从模块中导入一个指定的部分到当前命名空间中
  • 导入到了当前.py文件命名空间中,直接访问函数名或属性名即可
  • 同名的属性和方法,后引入的模块会覆盖先引入的模块中同名的内容
#a.py
b=1
def add(a):
	a += 1
	return a
class P():
	print('hello,world')
#b.py
from a import b,add,p
	print(P())

import 和 from… import … 区别

  • import导入的是一整个模块,而from…import…导入的却是模块中某些特定的内 容
  • import导入的内容是存放在模块命名空间中的,而from…import…却是存放在当前命名空间中的
  • 使用import导入的模块,访问其中的属性与方法时,需要使用模块名.方法名(或 属性名等)
  • 使用from…import…导入的模块,由于是导入到当前的命名空间中的,所以只需 要直接使用属性名或方法名即可
  • 当导入的多个模块中含有同名方法或属性时,如果使用import导入,后导入的同 名方法或属性不会覆盖先导入的其他模块中的同名的方法或属性;如果使用 from…import…导入的,后导入的同名属性或方法会覆盖最先导入的其他模块中 的同名方法或属性

定位模块

  • 当前目录
  • PYTHONPATH: 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目
    录,用sys.path.append来进行添加
  • site-packages: 如果都找不到,python会查安装路径lib下的site-packages。Unix下,默认路
    径一般是/usr/local/python/
  • 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录, PYTHONPATH由安装过程决定的默认目录。

命名空间

定义
名称到对象的映射。命名空间是一个字典的实现,键为变量名,值是变量对应的值。各个命名空间是独立没有关系的,一个命名空间中不能有重名,但是不同的命名空间可以重名而没有任何影响

分类

  • 局部命名空间:每个函数所拥有的命名空间,记录了函数中定义的所有变量,包括函数的入参、内部定义的局部变量
  • 全局命名空间:每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量
  • 内建命名空间:任何模块均可以访问,放着内置的函数和异常

作用域

定义
作用域是针对变量而言,指申明的变量在程序里的可应用范围。或者称为变量的可见性
分类

  • Local(函数内部)局部作用域
  • Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)
  • Global(模块全局)全局作用域
  • Built-in(内建)内建作用域

命名空间和作用域的关系

  • 每个函数都有自己的命名空间
  • 局部变量和一个全局变量重名,则局部变量会覆盖全局变量
  • 任何在函数内赋值的变量都是局部变量
  • 全局变量在函数里赋值,使用global 关键字
  • 函数外的list变量在函数内部使用无需声明为global
Money=200
def addMoney():
	global Money
	Money += 1
print(Money)
addMoney()
print(Money)

包是一个分层的文件目录结构,它定义了一个由模块及子包和子 包下的子包等组成的Python的应用环境

  • 需要包含 init.py 文件
  • __all__的值:在from package-name import *这语句使用的,表示全部导出定义过的模块
#a.py
__all__ = ['bar','baz']
waz = 5
bar = 10
def baz():
	return 'baz'
#b.py
from a import *
print(bar)
print(baz)
print(waz)
#name 'waz' is not defined
使用 import 和 from… import … 导入包

在包文件中的__init__文件中的__all__表示允许其他程 序使用from testmodule import *时可以导入 testmodule中的哪些模块,防止一次导入太多模块导 致名称冲突

# module a.py
# module b.py
# module __init__.py
__all__ = ['a']

#b.py
from module import a

#d.py
from . import  *

包中创建子包
#moudle a.py
def add(a,b):
	return a+b

#moudle/submoudle c.py
from math import sqrt,pow
def multiple(a,b):
	return pow(2,3)

#b.py
import moudle.a
import moudle.submoudle.c

print(moudle.a.add(10,20))
print(moudle.submoudle.multiple(10,20))

包中添加路径

#test/a.py 
def add(a,b):
	return a+b
#test/b.py
def sub(a,b):
	return a-b
#__init__.py
import sys
sys.path.append('./test')
from a import *
from b import *

#c.py
import test
test.add(1,2)
test.sub(2,1)

包的总结

  • 第一次导入一个模块,会执行这个模块
  • 可以通过修改模块module的__all__列表,来改变from module import * 时的效果
  • 导入一个包,其实就是导入包的__init__.py模块
  • 如果包的__init__.py模块为空,那么import package这样的语句是不能使用包当中的任何模块的
  • 如果包的__init__.py模块为空,那我们只能使用import package.module或者from package import module这样的导入方式
  • init.py也是个模块,其实也可以在__init__.py中直接定义函数fun,那样import package就可以直接用package.fun这个函数了是吧。但是我们一般不会这么干,这样会使__init__.py文件太乱
  • init.py也是个模块,那也可以在这个模块中导入其他模块,这样importpackage时,就能直接使用一些符号了。
  • init.py也是个模块,也可以定义__all__列表变量,控制from package
    import * 的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值