博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

二、Python开发---18、模块

Posted on 2019-10-19 16:03  兰智杰  阅读(223)  评论(0编辑  收藏  举报

模块

  每一个 Python 脚本文件都可以被当成是一个模块,模块可以包含直接运行的代码块、类定义、函数定义或这几者的组合

  import

    在Python中用关键字import来引入某个模块,也可以在一行内导入多个模块

    在调用模块中的函数时,必须加上模块名调用,因为可能存在多个模块中含有相同名称的函数,此时,如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数

'''
    输出为      start
               (延时5秒)
               stop
'''
import time
print('start')
#sleep(5)       错误调用
time.sleep(5)  #正确调用
print('stop')

  from...import

    Python的from语句能够从模块中导入一个指定的部分到当前命名空间中,使用这种方式导入,不会整个模块导入到当前命名空间,它只会将import的内容导入

from time import sleep
print('start')
sleep(5)
print('stop')

  from…import *

    导入一个模块的所有内容也可以使用from…import*

#导入模块中的所有内容
from math import *
print(ceil(1.1))  #向上取整     输出为2
print(floor(1.1)) #向下取整     输出为1

  扩展import语句(as)

    有时候导入的模块名称已经在程序中使用了,或者不想使用现有的名称,则可以使用一个新的名称来替换原始的名称,一旦替换后原来的就不可以再用了

#给导入的模块取别名
import math as m
print(m.ceil(1.1))              #向上取整       输出为2
print(m.floor(1.1))             #向下取整       输出为1

from math import ceil as c     #不建议,函数名最好不要简化或者取别名
print(c(1.1))                   #向上取整       输出为2

定位模块

  一、当导入一个模块后,Python解析器对模块位置的搜索顺序是:

  1、当前目录

  2、如果不在当前目录,Python则搜索在环境变量PYTHONPATH下的每个目录

  3、如果都找不到,Python会察看默认路径;UNIX下,默认路径一般为/usr/local/lib/python/

  模块搜索路径存储在system模块的sys.path变量中(sys模块用于提供对python解释器的相关操作);变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录

  二、所以如果当前路径或 PythonPATH中存在与标准模块同样的模块,则会覆盖标准模块;也就是说,如果当前目录下存在xml.py,那么在执行import xml时,导入的是当前目录下的模块,而不是系统标准的xml.py

模块调用

    

  1、引入同级目录中的模块(mian.py和test.py文件在同一级目录)

#mian.py文件
import test                         #引入同级目录中的test模块
print(test.test_add(2,3))           #输出为5

from test import test_add           #两种引入方式
print(test_add(2,3))                #输出为5
#test.py文件
def test_add(x,y):
    return x+y

  2、引入同级目录下的文件夹里的子模块(mian.py和study文件夹在同一级目录,test2.py文件在study文件夹里)

#mian.py文件
import study.test2                      #模块名.函数名
print(study.test2.test2_add(2,3))       #输出为5

from study import test2
print(test2.test2_add(2,3))             #输出为5

from study.test2 import test2_add
print(test2_add(2,3))                   #输出为5
#test2.py文件
def test2_add(x,y):
    return x+y

  3、引入父目录的同级目录的文件夹里的子模块(mian.py的父目录moudle文件夹和msg文件夹在同一级目录,recv.py和send.py文件在msg文件夹里)

#mian.py文件
import sys                      #查看路径变量
print(sys.path)
#添加目标路径导当前环境中
sys.path.append('..\\')         #返回上一级目录,(..\\有一组返回一级)
print(sys.path)

import msg.send
msg.send.sendMsg()              #输出为 消息发送成功

from msg.recv import recvMsg
recvMsg()                       #输出为 成功接收消息

print('三种不同的实现方式')       #输出为 三种不同的实现方式

from msg import send,recv
send.sendMsg()                  #输出为 消息发送成功
recv.recvMsg()                  #输出为 成功接收消息
#send.py文件
def sendMsg():
    print('消息发送成功')
#recv.py文件
def recvMsg():
    print('成功接收消息')

  4、标准模块的覆盖(mian.py的父目录moudle文件夹和msg文件夹在同一级目录,math.py文件在msg文件夹里)

#mian.py文件
import sys
sys.path.append('..\\')            #返回上一级目录,(..\\有一组返回一级)

import math
print(math.ceil(1.1))              #输出为 2 引入的是标准模块   向上取整
print(math.floor(1.1))             #输出为 1

#覆盖标准模块
from msg import math               #自定义的模块
#print(math.ceil(1.1))             #程序无法执行,会报错,因为已经被覆盖了
math.getInfo()                     #输出为 SKT一定要夺冠啊
#math.py文件
def getInfo():
    print('SKT一定要夺冠啊')

dir()函数与标准模块

  dir()函数一个排好序的字符串列表,内容是一个模块里定义过的名字,返回的列表容纳了在一个模块里定义的所有变量,模块和函数

'''
输出为   ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test']
         ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test_add']
双下划线为系统自带
'''
import test
print(dir())
print(dir(test))

   标准模块:Python 本身带着一些标准的模块库(参考http://www.cnblogs.com/ribavnu/p/4886472.html),有一个特别的模块 sys ,它是内置在每一个 Python 解析器中

  1、包是一种管理 Python 模块命名空间的形式,采用"点模块名称",比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块B

  2、目录中只有包含一个叫做__init__.py的文件才会被认作是一个包

  3、在导入包的时候,Python会从sys.path中的目录来寻找这个包中包含的子目录

__init__.py

  1、msg文件夹下创建一个__init__.py文件,并且一定要在文件中写入__all__

  2、__init__.py 控制着包的导入行为,如果__init__.py文件为空的话,仅仅是把这个包导入,不会导入包中的模块;__init__.py中的__all__变量,是用来控制from包名import * 时导入的模块

  3、可以在__init__.py中编写其他内容,在导入时,这些编写的内容就会被执行

  4、可以在__init__.py中向sys.path添加当前被调用模块路径

#mian.py文件
import sys                      #查看路径变量
sys.path.append('..\\')         #返回上一级目录
#通过from一次性导入所有的模块
#做一个包一定要创建一个__init__.py  这么文件中一定要设置 __all__ = ['允许导入的模块名']
from msg import *
send.sendMsg()                  #输出为  消息发送成功
recv.recvMsg()                  #输出为  成功接收消息
math.getInfo()                  #输出为  SKT一定要夺冠啊
# __init__.py文件
__all__ = ['send','recv','math']  #表示运行被导入的模块send,recv,math

__all__

  1、编写Python代码(不建议在__init__中写python模块,可以在包中在创建另外的模块来写,尽量保证__init__.py简单)

  2、模块中不使用__all__属性,则导入模块内的所有公有属性、方法和类 ; 模块中使用__all__属性,则表示只导入__all__中指定的属性,因此,使用__all__可以隐藏不想被import的默认值; __all__变量是一个由string元素组成的list变量, 它定义了当我们使用 from 模块 import * 导入某个模块的时候能导出的符号(这里代表变量,函数,类等)注:区别于在包导入中,__all__控制导入的是模块

  3、from 模块 import * 默认的行为是从给定的命名空间导出所有的符号(当然下划线开头的变量,方法和类除外), 需要注意的是 __all__ 只影响到了 from 模块 import * 这种导入方式, 对于 from 模块 import 成员 导入方式并没有影响,仍然可以从外部导入

重载——importlib.reload()

  默认情况下,模块在第一次被导入之后,其他的导入都不再有效;如果此时在另一个窗口中改变并保存了模块的源代码文件,也无法更新该模块;这样设计原因在于,导入是一个开销很大的操作(导入必须找到文件,将其编译成字节码,并且运行代码),以至于每个文件、每个程序运行不能够重复多于一次

  当一个模块被导入到一个脚本,模块顶层部分的代码只会被执行一次;因此,如果想重新执行模块里顶层部分的代码,可以用reload()函数,该函数会重新导入之前导入过的模块

  语法如下:

    reload(模块名)

#mian.py文件
import test
import test                 #引入两遍只输出一句skt加油
import importlib
importlib.reload(test)      #重新导入test模块 输出 skt加油