python模块和包

导入模块的方式:
1.import 模块名
2.from 模块名 import 函数名(方法名)

import方式导入

自定义一个模块module.py
print('这里是py文件module的开始')
name = 'bob'
address = '上海'

def play():
    print(f'{name}去了{address}迪士尼')

print('这里是py文件module的结束')


在另外一个文件test3中引用这个模块
#此时我们已经导入了一个自定义模块module并重命名这个模块为modu(as的功能为重命名模块名)
#但这里pycharm报错,并不是python报错,因为pycharm找不到这个模块
#导入模块的时候,会把模块中的代码执行了一遍
import module as modu
def func():
    print('hello world')

print(modu.name)
print(modu.address)

func()          #自己这个文件中的方法
modu.play()     #模块中的方法
结果
这里是py文件module的开始
这里是py文件module的结束
bob
上海
hello world
bob去了上海迪士尼

注意: 由于模块在导入的时候会创建其自己的名称空间,所以在使用模块中的变量的时候一般是不会产生冲突的

一个文件中多次导入同一个自定义模块

import module
print('hhhhhhh')
import module   #如果已经导入过该模块,此时不会再执行模块中的代码了
import module
import module
结果
这里是py文件module的开始
这里是py文件module的结束
hhhhhhh

导入模块的过程:
1. 去判断当前正在导入的模块是否已经倒入过
2. 如果已经导入过,不会重新导入该模块
3. 如果没有导入过,首先开辟一个内存空间
4. 把该模块中的代码放在新开辟的空间中,运行该模块中的代码
5. 把该文件的名字作为当前名称空间的名字(前提是没有as)

查看已经导入的模块

import sys
print(sys.modules.keys())
或
print(globals())    #查看模块的名称空间

模块导入顺序:
1. 先导入内置模块
2. 第三方模块
3. 自定义的模块

事例1
import module as modu
print(modu.name)       #应用的是模块中的name变量

modu.name = '攻城狮'   #从另一个模块中改变应用的模块中变量的值
modu.play()            #所以模块中的name变量值改变为修改后的'攻城狮'
print(modu.name)
结果
这里是py文件module的开始
这里是py文件module的结束
bob
攻城狮去了上海迪士尼
攻城狮


事例2
import module as modu
print(modu.name)    #打印的是模块中的name变量

def func():
    global name     #此时在文件中开辟了一个name变量的内存空间
    name = '佩奇'   #把全局变量name内存空间赋值为'佩奇'
    modu.play()     #打印模块中的play方法
func()
modu.play()         #文件中gloal的全局变量name并不影响模块中name变量的值
print(name)         #这里打印的是此文件中全局name变量(并不是模块中的变量)
结果
这里是py文件module的开始
这里是py文件module的结束
bob
bob去了上海迪士尼
bob去了上海迪士尼
佩奇


事例3
vim module.py
print('这里是py文件module的开始')
name = 'bob'
address = '上海'

def play():
    global  name        #global 引用当前模块的全局
    name = '贝塔'       #模块中全局变量修改为'贝塔'
    print(f'{name}去了{address}迪士尼')

print('这里是py文件module的结束')

import module as modu
name = '佩奇'

modu.play()
print(modu.name)   #返回的是模块中修改后的name变量值

print(name)     #并没有改变文件内的name变量值
结果
这里是py文件module的开始
这里是py文件module的结束
贝塔去了上海迪士尼
贝塔
佩奇


也可以用import一次性导入多个模块(不建议这样用)
import module as modu,test2,time,os,...
modu.func()
test2.mode()
结果
我是模块1
我是模块2

模块测试: 要运行这个py的时候才执行代码
如果在模块中定义__name__ == __main__,作用就是测试模块中的某些功能
所以别的文件调用不了此模块中的方法,但单独执行这个模块可以执行这个模块中的方法

name = 'bob'
address = '上海'
def play():
    print(f'{name}去了{address}迪士尼')

if __name__ == '__main__':      # 当前文件如果是启动文件就执行
    print('这里是py文件module的开始')
    play()
    print('这里是py文件module的结束')

from方式导入模块: 导入的只有一个功能

vim module.py
def func1():
    print('我是模块中的方法一')

def func2():
    print('我是模块中的方法二')

vim test.py
from module import func1
func1()
结果
我是模块中的方法一


from module import func1
func1 = '定义的变量与导入的模块中的方法重名则会覆盖模块中的方法'
print(func1)
结果
定义的变量与导入的模块中的方法重名则会覆盖模块中的方法

总结
如果当前文件中出现了重名的变量时,会覆盖掉模块引入的那个变量
所以创建的py文件的名字不要和系统内置的模块重名

 

包的定义

包实际就是文件夹,包内可以写很多个模块
注意,在python2中规定,包内必须存在__init__.py文件,创建包的目的不是为了运行,
而是被导入使用,包只是一种形式而已,包的本质就是一种模块
自我理解
1.只要是文件夹就是包,
2.文件夹里边的py文件就是模块,
3.文件(模块)中的方法就是包中某个模块的方法
4.调用,包名.模块名.模块中的方法名(函数)

按照代码从小到大的顺序排列:

一个表达式 -> 一条语句  -> 语句块  -> 函数 -> 类  -> 模块  -> 包  -> 项目

__init__.py文件说明

在__init__.py文件中分别去引用所在目录(子包)中的内容
作用其实就是在文件中导入子包(此目录的下一级目录)或者模块名

导入包方法

import 包名.模块名.方法
from 包名 import 模块名
调用 模块.方法

包导入分类

绝对导入: 从顶级包开始导入的
相对导入: 用.或..作为起始位置的(在包内部可以使用)
from ..包名 import 模块名

程序对包或模块的查找路径是:sys.path,跟着你的启动文件所在的位置变化
无论使用绝对导入,还是相对导入,启动文件一定要放在最外面
注意
在pytho中不允许运行的程序导包的时候超过当前顶级包的范围(相对导入),如果使用绝对导入,没有这个问题
在导包出错的时候,一定要先导入sys模块,先看sys.path,看一下是否真的能获取到包的信息

 

posted @ 2018-12-30 16:02  清茶i  阅读(153)  评论(0编辑  收藏  举报