1 前言

导包这个词我相信编程人员不会陌生。如何很好地在Python中导入别人的包以及自己写的工具函数?这时需要分清楚和用好的,特此总结以飨读者。

2 优雅地导入别人的包

当然这里主要指你使用pip(conda)安装到Python环境中的包。这里导包就很简单了,因为在Python解释器在解释程序时会在系统中扫描相关包的路径,不至于找不到。例如你安装了NumPy包,你可以这样导入:

import numpy

但是在写Python程序时,你的程序会显得繁琐,在Python编程社区中,我们通常会为其设置一个简称,如:

import numpy as np

这样在程序中代码会简洁一些,别人看到np也会知道你导的包是numpy,这已经是行业通用的习惯了。
有时候一个工具包会有多级工具,或者说一个py文件下会有多个函数,假如你想使用numpy中的sin()函数,你可以使用这种方式导入:

from numpy import sin

如果你想sin、cos()、tan()等函数,你也可以这样使用通配符“*”导入:

from numpy import *

也就是说你把numpy下所有函数导入,虽然可以像往常的时候那样使用,但是并不建议,最好是需要什么函数,你就导入什么函数。需要补充的是:这个“*”所导入的函数都在对应包的__init__.py文件中的__all__ = ['module_1', 'module_2']中。

除此之外,还需要注意的是,不仅numpy下有sin函数,系统的math函数也是有sin函数的,如果你的程序报错了也需要检查一下,特别是在使用from numpy import *。如果两个函数的输入和输出是相同的还好,如果两个函数功能有些差异等就可能报错,如果必须的导入的话,就为对应的函数起一个别名,如:

from numpy import sin as np_sin

或者不导入具体的函数,使用下面的方式:

import numpy as npnp.sin(10)

这种方式看起来也是比较简单明了的。

3 优雅地使用自己写的函数包

上面导包方式还是比较简单的,但是导入自己的包还是会经常出错的。有时候我们会自己写一些工具函数,但是每每调用是总会出现不同的错误,我们看看如何优雅地导入自己写的函数,或者跨文件夹的文件。在此之前先看看当前测试项目的目录结构和几个路径相关函数。

3.1 项目目录结构和几个路径相关的函数

当前项目的结构如下:

下面来看看几个路径,有如下程序:

import osimport sysdef main():    absPath = os.path.abspath(__file__)   # 返回运行当前程序py文件的路径    print('absPath', absPath)    temPath = os.path.dirname(absPath)    # 往上返回一级目录,得到文件所在的路径    print('temPath', temPath)    temPath = os.path.dirname(temPath)    # 在往上返回一级,得到文件夹所在的路径    print('temPath', temPath)    print(sys.path)                       # Python解释器查找Python包路径有哪些(Python解释器安装地址因人而异)    if __name__ == "__main__":    main()

运行结果如下:

absPath f:estTempmain.pytemPath f:estTemptemPath f:est['f:estTemp', 'C:DevelopmentPythonAnaconda3python37.zip', 'C:DevelopmentPythonAnaconda3DLLs', 'C:DevelopmentPythonAnaconda3lib', 'C:DevelopmentPythonAnaconda3', 'C:DevelopmentPythonAnaconda3libsite-packages', 'C:DevelopmentPythonAnaconda3libsite-packageswin32', 'C:DevelopmentPythonAnaconda3libsite-packageswin32lib', 'C:DevelopmentPythonAnaconda3libsite-packagesPythonwin']

可以看到这时的项目路径变成了'f:estTempmodel1',也就是说一个项目的主程序(自己总结,方便理解) 在运行时就决定了整个项目的路径,这为后面的导包提供了依据。需要注意的是导入自写的包后,自写的包被调用时,其整个项目路径依然是项目入口程序那个py文件所对应的路径(这个py文件所处的文件夹)。知道这个后,我们看看以下各种导包情况如何解决,默认只执行main.py这个文件,也就是说确定了这个项目路径(main.py调用其他模块的包)。

3.2 程序入口文件调用各个模块的包

因为默认只执行main.py这个文件,这里以main.py文件调用model1中m1_test1.py的model1_test1()函数为例,看看如何调用,示例程序如下:

其中m1_test1.py的程序如下:

import sysdef model1_test1():    print('model1_test1 is been called!')if __name__ == "__main__":    print(sys.path)

项目入口函数main.py代码如下:

import osimport sysimport model1.m1_test1 as m1t1def main():    m1t1.model1_test1()if __name__ == "__main__":    main()

程序运行结果:

model1_test1 is been called!

因为项目路径是在main.py所在的文件夹,而model1又与main.py处于同一文件级别,则在调用model1模块下的py文件时可以直接从model1开始书写。也需要注意 ,调用model1_test1.py文件时, model1.m1_test1 中的 m1_test1 为对应py文件的文件名。

3.3 同级文件自写py文件引用

以model1模块为例,用m1_test1.py调用m1_test2.py中的model1_test2()函数,在3.2的基础上,为model1_test1.py修改成如下代码:

3.3 同级文件自写py文件引用以model1模块为例,用m1_test1.py调用m1_test2.py中的model1_test2()函数,在3.2的基础上,为model1_test1.py修改成如下代码:

其中m1_test2.py文件中的代码如下:

def model1_test2():    print('model1_test2 is been called!')

可以看出,我们在main.py中去运行时,即使两个文件在同一级在导包时也需要从model1开始书写,如果写成这样import m1_test2 as m1t2的话,会出现:

Traceback (most recent call last):  File "f:estTempmain.py", line 3, in     import model1.m1_test1 as m1t1  File "f:estTempmodel1m1_test1.py", line 2, in     import m1_test2 as m1t2ModuleNotFoundError: No module named 'm1_test2'

如果两个同级文件所处深度太深,例如m1_test1.py和m1_test2.py文件在model1/sum_model/sub_sub_model目录下,如果从model1开始写,那导包语句岂不是特别长,这时可以使用以下方式进行修改:

import syssys.path.append('model1/')import m1_test2 as m1t2

当你想测试m1_test2.py文件函数时(直接运行m1_test1.py,即将m1_test1.py所在文件夹当做项目文件路径)这种sys.path导入方式也不会影响程序的运行。

3.4 跨模块导入包

现在我们的程序保持的状态是使用sys.path解决model1中m1_test1.py导入m1_test2 .py的方式。现在我们看看在model1中py文件如何使用model2模块中的py文件。这里我可以想到使用如下导入方式:

import model1.m1_test2 as mt2

这种方式就行了嘛。现在我们来看看实际是不是这样的,main.py文件修改如下:

import osimport sysimport model2.m2_test1 as m2t1def main():    m2t1.model2_test1()if __name__ == "__main__":    main()

m2_test1.py程序如下:

import model1.m1_test2 as m1t2def model2_test1():    print('model2_test1 is been called!')if __name__ == "__main__":    m1t2()

运行main.py文件查看结果:

model2_test1 is been called!

结果正是我们估计的。如果你猜到这么做了,基本上已经理解整个导包的流程。 但想使用sys.path改进,即m2_test1.py程序如下:

import syssys.path.append('model1/')import m1_test2 as m1t2def model2_test1():    print('model2_test1 is been called!')if __name__ == "__main__":    m1t2()

对于在main.py运行时,结果正常,但是,直接运行m2_test1.py程序时,就会出错,出错结果可想而知,除非你把model1的全路径添加到sys.path中。

3.5 让自写包变得更加标准

如果让你的包变得更加标准的话,这时就需要在对应的模块下添加__init__.py文件了,这个文件中的内容可以什么都没有,但会告诉解释器,这个文件所在文件夹就是一个标准的包了。可以通过配置__init__.py文件限制from module import *中可以导入的py文件等。

3.6 读取文件

在实际的开发过程中,也可能会出现读取同级文件,或跨包文件。类似于包,读取文件的操作则有所不同。读取同级文件如下,把main.py文件修改如下:

import osimport sysimport model2.m2_test1 as m2t1def main():    m2t1.read_file()if __name__ == "__main__":    main()

m2_test1.py添加如下函数即可(绝对路径方式):

def read_file():    import os    import sys    file_path = 'm2_file.txt'    abs_path = os.path.abspath(__file__)  # 获取当前py文件路径    dir_path = os.path.dirname(abs_path)   # 获取当前py文件所在目录路径    file_path = os.path.join(dir_path, file_path)   # 拼接    with open(file_path) as reader:        print(reader.read())

读取跨包的文件方法如下(使用项目路径定位),修改main.py文件代码如下:

import osimport sysimport model1.m1_test2 as m1t2def main():    m1t2.read_file()if __name__ == "__main__":    main()

修改m1_test2.py代码如下:

def model1_test2():    print('model1_test2 is been called!')def read_file():    import os    project_root = os.getcwd()  # 获取项目根目录    file_path = 'm2_file.txt'    file_path = os.path.join(project_root, 'model2', file_path)    with open(file_path) as reader:        print(reader.read())

运行main.py文件即可。

4 总结

总的来说,上面的方法能够应付大多导包和读取文件的问题。但在实际开发过程中,还需要灵活运用,避免按图索骥,生搬硬套。

idea导包都报错_不仅仅要会导别人的包也要会导自定义的包——Python导包总结...相关推荐

  1. idea导包都报错_IDEA+Springboot 导出jar包,war包

    一.jar包导出 使用IDEA内置导出工具会报错 1.安装maven http://maven.apache.org/download.cgi 下载 Binary zip archive 配置环境变量 ...

  2. mysql 5.6.23 源码包安装报错_大环境下MySQL5.6源码安装实战一步步教你 CentOS6.5_64bit下编译安装...

    一.关闭防火墙 chkconfig iptables off service iptables stop 二.检查操作系统上是否安装了MySQL [[email protected] backup]# ...

  3. npm安装任何包都报错解决方法

    报错: C:\Users\Administrator>npm install express npm ERR! Windows_NT 6.1.7601 npm ERR! argv "C ...

  4. java打开别人的代码报错_同样的代码,别人的可以运行我的报错,求解答

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 public class Override { public static void main(String[ ] args) { //创建两个实例 Ca ...

  5. java类里的包路径报错_[ERROR] 致命错误: 在类路径或引导类路径中找不到程序包 java.lang...

    maven执行install时出现错误: [ERROR] [源文件的搜索路径: E:\project\IdeaProjects\weixin\leimingtech-core\src\main\jav ...

  6. npm安装任何包都报错的解决办法

    解决办法:1.执行:npm config get proxy npm config get https-proxy 如果返回值不为null,继续执行: (这一步很重要,一定要保证两个命令的返回值都为n ...

  7. rpm安装mysql报错_【CentOS-65】通过rpm包安装mysql57解决了server报错和mysqld启动报错的问题...

    [CentOS-6.5]通过rpm包安装mysql5.7(解决了server包安装报错和mysqld启动报错的问题) 一.官网下载rpm包二.安装 wget三.检查是否已有数据库四.在linux在解压 ...

  8. 关于com.lowagie.text包的报错问题

    关于com.lowagie.text包的报错问题 接手了一个maven项目,导入之后发现一直报错 提示我找不到这个包,在右侧的maven projects一栏中找了一下,也确实没有com.lowagi ...

  9. 关于jar包运行报错:Exception in thread “main“ java.lang.UnsupportedClassVersionError的解决办法

    打包jar包后 ,在jar路径下cmd使用命令 java -jar  jar包名字 报错: Exception in thread "main" java.lang.Unsuppo ...

最新文章

  1. python在linux报错xe6,python出现SyntaxError: Non-ASCII character '\xe6' in file \的错误
  2. 手机1像素线粗,如何模仿1像素厚的线?
  3. LTE-V2X车联网无线通信技术发展
  4. 使用FoundationDB高效地将SQL数据映射到NoSQL存储系统中
  5. mysql-sql优化--笔记
  6. cms查询系统(一)背景以及需求分析与设计
  7. javascript 观察者(发布订阅)模式详解
  8. 数据结构--红黑树 Red Black Tree
  9. 分析师视角:2018年的数据中心3大预测
  10. 深度学习经典算法 | 遗传算法详解
  11. mp.weixin.php,GitHub - temberature/mp-php-sdk: 微信公众平台第三方授权php开发包, weixin mp developer SDK....
  12. Day4:python之文件操作、函数初识(2)
  13. C#的String.Split方法
  14. Ubuntu20.04安装qt详细教程
  15. sql 分组 行列转换
  16. AndroidStudio入门基础(一)——基础布局
  17. HTTP Status 400- Parameter conditions “username“ not met for actual request parameters:
  18. python中美元人汇率_Python爬虫练习:爬取美元历史汇率
  19. 浙江省计算机程序比赛员,计算机学子在“图森未来杯”第十七届浙江省大学生程序设计竞赛中斩获金奖...
  20. SOA+LDAP实现SSO单点登录思路

热门文章

  1. 《如何搭建小微企业风控模型》第五节 特征工程(上)
  2. SCUT - 244 - 全新的游戏 - 凸包
  3. 如何拔出手上的刺,假如不用缝衣针挑出来的话
  4. SSM中(Spring-SpringMVC-Mybatis)(二:整合)
  5. Loadrunner脚本优化-参数化之关联MySQL数据库获取数据
  6. 2014.8.25二分法,二维数组
  7. 循证e刊 安慰剂的前世今生
  8. Asp.net源码上周更新目录(5.12-5.18)
  9. Crontab- Linux必学的60个命令
  10. HNOI2019 退役记