python中导入模块

什么是module?

在程序开发的过程中,随着代码量越来越大,我们可以把完成某个功能的函数进行分组,放在一个.py文件里边,这样的一个.py文件称为一个module,这样做最大的好处就是提高代码的可重用性和可维护性,新的开发可以调用原来模块的函数,我们经常用的python内置模块和第三方类库就属于module。简单来说,一个.py文件就是一个module。

比如说,我们有一个计算斐波那契数列的module,这个module用来计算斐波那契数列,这个module使用两种方式来计算斐波那契数列,一种使用返回list方式,一种使用生成器方式。这些代码保存在一个名为fibo.py的文件中,代码如下。

def fib_list(n):
    result = []
    k,a,b = 0,0,1
    while k<n:
        result.append(b)
        a,b = b,a+b
        k += 1
    return result

def fib_yield(n):
    k,a,b = 0,0,1
    while k<n:
        yield b
        a,b = b,a+b
        k += 1

fibo.py包含两个计算斐波那契数列的函数,一种使用list方式,比较耗费内存,另外一种使用生成器方式,该函数接收参数n,用来计算斐波那契数列的前n项。

 

如何使用module?

    在开发的过程中如果想使用某个module,必须首先导入该模块,导入模块使用关键字import,使用import导入模块的时候有以下几种方式。

(1) 命令格式:import module

    比如我们在main.py中想使用刚才定义的fibo.py模块中的函数来计算斐波那契数列。main.py函数的代码如下:

import  fibo

l = fibo.fib_list(10)
print(l)

for e in fibo.fib_yield(10):
    print(e, end = "-")

执行结果如下:

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
1-1-2-3-5-8-13-21-34-55-

导入module以后,可以通过modulename.xxx的方式来访问模块中对应的函数和变量,这里只有函数,也可以访问变量。这类似于类去访问一个成员函数。使用modulename.xxx的这种方式可以很清晰的看到变量或者函数的作用范围。这样即使导入的模块中具有同名的函数或者变量,也不会产生冲突。使用这种方式还有以下几种变形:

(1) import  module1,module2,...  
#使用这种方式一次性可以导入多个模块

(2) import moudle as alias
#使用这种方式将给导入的模块起了一个别名,后边调用的时候使用alias.xxx代替module.xxx

(2) 命令格式:from moudle import xxx

使用上述导入模块的方式其实是把模块中的所有内容都导入进来,调用的时候要通过modulename.xxx来调用,如果只想使用模块中的某个函数,可以通过from moudle import xxx的方式来导入。例如,我现在只想使用fibo模块中的fib_list函数,可以使用以下方式。

from fibo import fib_list
l = fib_list(10)
print(l)

使用这种方式导入模块时,在使用模块中的变量或者函数的时候,前边不用加模块的名字,而是直接像调用普通函数那样来调用模块中的函数,这样相比于第一种形式来说更加简便。但是这种导入方式在模块中已经存在相同名字,或者导入不同模块中的同名函数或者变量的时候会存在问题,后导入的名字会隐藏前边已经存在的名字。这个问题在下面的from module import *的方式中会解释。这种导入模块的方式还有以下的变形:

from module import *
#这种方式将模块中所有的变量和函数导入进来,除了以下划线(_)开头的名字

在python中并不推荐使用这种方式,因为你并不知道module中包含什么名字,假如在这之前你的程序中已经包含了一个名字为aaa的函数或者变量,那么使用这种方式导入的时候,你并不知道实际导入了什么变量或者函数,如果恰好这个模块中也有一个名字为aaa的变量或者函数,那后边导入的这个aaa就会覆盖前边已经存在的aaa。例如,导入fibo.py后,又用from module import *的方式导入了fibo1.py模块,fibo1.py的代码如下。

def fib_list(n):
    result = []
    k,a,b = 0,0,1
    while k<n:
        result.append(b)
        a,b = b,a+b
        k += 1
    print("this is fibo1.fib_list function")
    return result

修改main.py代码如下。

from fibo import fib_list
from fibo1 import *

l = fib_list(10)
print(l)

#执行结果
# this is fibo1.fib_list function
# [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

由结果可见,程序执行的fib_list实际上是fibo1.fib_list,这是因为在导入fibo1模块中的名字后,fibo1中的fib_list隐藏了从fibo.py中导入的fib_list函数,所以要谨慎使用这种导入方式,因为你根本不知道你导入了什么东西。对于模块比较多的程序,还是使用方式(1)会好一点,这样不会造成名字冲突。

 

去哪里搜索module

当我们导入一个模块的时候,系统去哪里寻找我们要到如的模块呢?python在导入系统模块的时候,python搜索模块的路径可以通过sys.path来查看,例如,我在main.py中打印目前搜索模块的路径。

from fibo import fib_list
import sys

print(sys.path)

#执行结果
# [ 'C:\\Users\\x2382\\PycharmProjects\\fibo',   main.py所在的目录,就是当前源程序的根目录
# 'C:\\Users\\x2382\\PycharmProjects\\fibo',
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\python36.zip', 
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\DLLs', 
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\lib', 
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32',
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages',
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\pyserial3.2.1-py3.6.egg', 
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\pyinstaller-3.3.dev0+483dfde-py3.6.egg', 
# 'C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\win32', 
#' C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\win32\\lib',
#' C:\\Users\\x2382\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\site-packages\\Pythonwin']
"""

所以,如果想要自己定义的模块被搜索到,就要把模块放在这些目录,或自己手动修改sys.path这个变量,在这个变量中增加自己想要搜索的目录。

 

.pyc文件是什么鬼?

.pyc文件是有.py文件经过编译得到的,称为字节码文件,这个文件经过python虚拟机以后可以变成可执行的二进制文件。.pyc文件和其对应的.py文件功能完全一样,唯一不同的是.pyc是经过编译的,生成的是字节码文件。使用.pyc文件有两个好处:
(1) 首先,使用.pyc文件可以提高程序加载的速度,例如在main.py每次导入fibo模块的时候,如果使用源代码,加载速度比较慢,使用.pyc文件可以提高加载的速度
(2) .pyc文件是跨平台的,也就是说在window上编译出来的.pyc文件在linux系统上也是可以用,如果并不想公开源代码,使用.pyc文件是一种很好的选择。
基于以上原因,python在每次执行import模块到如的时候,都会生成一个.pyc文件。

pyc

例如我的源程序根目录下回生成__pycache__目录,这个目录里边就是经过编译的.pyc文件,这个.pyc文件按照module.version.pyc的格式来命名,version指的是当前使用python的版本号,如下所示。

pyc1

那如果源代码修改了怎么办,python在每次导入模块的时候,会检查源程序和其对应.pyc文件的时间戳(就是文件的修改时间),如果两个文件的时间戳不同,python就会重新编译源文件,生成新的.pyc文件,如果两个文件时间戳相同,就直接加载.pyc文件。

 

总结:什么是module--->怎么导入module--->module放在什么地方--->优化module导入的过程(.pyc文件)

转载于:https://www.cnblogs.com/husterxmh/p/8692867.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值