一 模块

1、什么是模块

​ 模块是一系列功能的结合体

​分为三大类:

​1、内置的模块

​2、第三方的模块

​3、自定义的模块

​一个 python 文件本身就是一个模块,文件名:m.py 模块名:m

ps:模块分为四种形式

​1 使用python编写的.py文件

2 已被编译为共享库或DLL的C或C++扩展

3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)

4 使用C编写并链接到python解释器的内置模块

2、为何要用模块

1、内置与第三方的模块拿来就用,无需定义,这种拿来主义,可以极大地提升自己的开发效率

2、自定义模块,可以将程序的各部分功能提取出来放到一模块中为大家共享使用

​好处:减少代码冗余,程序组织结构更加清晰

3、如何使用模块

1 导入模块

首次导入模块会发生的事情

import foo

1、产生 foo.py 的名称空间, 将 foo.py运行过程中产生的名字都丢到 foo 的名称空间中

2、执行 foo.py

3、在当前文件中产生的有一个名字 foo,该名字指向 1 中产生的名称空间

具体如下图:

之后的导入,都是直接引用首次导入产生的 foo.py名称空间,不会重复执行代码

import foo

import foo

import foo

2 引用

具体:

print(foo.x)

print(foo.get)

print(foo.charge)

强调1:模块名.名字,是指名道姓地问某一个模块要名字对应的值,不会与当前名称空间中的名字发生冲突

x=1111111111111

print(x)

print(foo.x)

强调 2:无论是查看还是修改,操作的都是模块本身,与调用位置无关

import foo

x=3333333333

# foo.get()

foo.change()

print(x)

可以以逗号为分隔符在一行导入多个模块

import time, foo, m

3、导入模块的规范(顺序)

​1、内置模块

​2、第三方模块

​3、程序员自定义模块

模块是第一类对象

imoport foo

自定义模块的命名应该采用纯小写 + 下划线的风格

可以在函数内导入模块

def func():

import foo

4、 py 文件的用途

​一个 py 文件有两种用途

​1)被当做程序运行

​2)被当做模块导入

1、执行 py 文件与导入文件的区别是什么?

​执行 py 文件:

​1)在内存中产生名称空间

​2)运行 py 文件

​3)将运行 py 文件产生的名字放到名称空间内

​名称空间会在文件运行结束后回收

​导入文件:

​1)产生模块文件的内存空间

​2)运行模块

​3)在该文件名称空间内产生模块字并指向模块文件的名称空间

2、from...import.....

​1、产生一个模块的名称空间

​2、运行 foo.py 将运行过程中产生的名字都丢到模块的名称空间去

​3、在当前名称空间拿到一个名字,该名字指向模块名称空间 中的某一个内存地址

from foo import x #x = 模块foo中的值1的内存地址

from foo improt change

from foo import get

x = 111 #重新将 x 赋值 指向新的内存地址

​优点:代码更精简,导入后在使用时不需要加前缀

​缺点: 容易与当前名称空间混淆

一行导入多个名字(不推荐)

from foo import x,get,change

导入模块中所有名字(不推荐)

from foo import *

了解:

__ all __:在模块中默认存的是模块中所有名字,所以在其它地方能通过 from foo import * 导入所有的名字

__ all__ =['login', 'get'] #控制*代表的名字有哪些

起别名

from foo improt x as xx

3、循坏导入问题

循环导入问题指的是在一个模块加载/导入的过程中导入另外一个模块,而在另外一个模块中又返回来调用第一个模块中名字,由于第一个模块尚未加载完毕,所以引用失败,抛出异常。原因是:在 python 中,同一个模块只会在第一次导入时执行其内部代码,再次导入该模块时,即便是该模块尚未完全加载完毕也不会重复执行内部代码。

具体案列:

m1.py

print('正在导入m1')

from m2 import y

x = 'm1'

m2.py

print('正在导入m2')

from m1 import x

y = 'm2'

run.py

import m1

#1、执行run.py会抛出异常

正在导入m1

正在导入m2

Traceback (most recent call last):

File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/aa.py", line 1, in

import m1

File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in

from m2 import y

File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m2.py", line 2, in

from m1 import x

ImportError: cannot import name 'x'

#2、分析

先执行run.py--->执行import m1,开始导入m1并运行其内部代码--->打印内容"正在导入m1"

--->执行from m2 import y 开始导入m2并运行其内部代码--->打印内容“正在导入m2”--->执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错

解决方案

方案一:

​将导入模块放到最后,保证在导入时,所有名字都已经加载过

# 文件:m1.py

print('正在导入m1')

x='m1'

from m2 import y

# 文件:m2.py

print('正在导入m2')

y='m2'

from m1 import x

# 文件:run.py内容如下,执行该文件,可以正常使用

import m1

print(m1.x)

print(m1.y)

方案二:

导入语句放到函数中,只有调用函数才会执行其内部代码

# 文件:m1.py

print('正在导入m1')

def f1():

from m2 import y

print(x,y)

x = 'm1'

# 文件:m2.py

print('正在导入m2')

def f2():

from m1 import x

print(x,y)

y = 'm2'

# 文件:run.py内容如下,执行该文件,可以正常使用

import m1

m1.f1()

注:循坏导入问题大多数情况下是因为程序设计失误导致的,在编写程序时应该尽量避免出现循环/嵌套导入。如果多个模块都需要共享某些数据,可以将共享的数据集中存放到某一个地方。

4、搜索模块的路径与优先级

​无论import 还是 from...impor在导入模块时都涉及到查找问题

优先级:

​1、内存(内置模块)

​2、硬盘:按照 sys.path中存放的文件的顺序依次查找要导入的模块

# mmm.py #它是代码文件夹下的py 文件

import sys

print(sys.path)

#环境变量路径

['/Users/tophan/Desktop/代码', '/Users/tophan/Desktop/代码', '/Applications/PyCharm.app/Contents/helpers/pycharm_display', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Users/tophan/Library/Python/3.6/lib/python/site-packages', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages', '/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend']

1、列表中的每一个元素都可以看做一个文件目录

2、列表中第一个目录为执行文件的路径

3、第二个目录为整个项目的路径

当第一次导入模块时,如果被导入模块与执行文件在同一目录下是肯定可以正常导入的,如果不在同一目录下,就涉遍历查找该模块的存放目录是否在环境变量路径中。为了确保模块对应的源文件在任何地方都可以被找到,需要将源文件所在的路径添加到 sys.path中。

#sys.append(模块源文件的路径)

sys.path.append(r'/pythoner/projects/') #也可以使用sys.path.insert(……)

import foo #无论foo.py在何处,都可以导入它

5、区分py文件

区分一个 py 文件是执行文件还是导入文件

print(__name__)

1、当 py 文件被运行时,__name__的值为'__mian__'

2、当 py 文件被当做模块导入时,__name__的值为模块名

if __ name__ == '__main__':

print('文件被执行')

get()

change()

else:

#被当做模块导入时做的事情

print('文件被导入')

二 包

1、包就是一个包含有__ init __ .py文件的文件夹

​包的本质是模块的一种形式,包是用来被当做模块导入,导入包其实其实是导入包下的__ init __文件

在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

创建包的目的不是为了运行,而是被导入使用,包只是模块的一种形式而已,包的本质就是一种模块

导入包会发生的事情:

​1、产生一个名称空间

​2、运行包下的__ init __.py 文件,将运行过程中产生的名字都 丢到 1(模块)产生的名称空间中

​3、在当前执行文件的名称空间中拿到一个名字,这个名字指向 1 (模块)的名称空间

import mmm

print(mmm.x)

print(mmm.y)

mmm.say()

环境变量是以执行文件为准的,所有被导入的模块或者说后续的其他文件引用的 sys.path都是参照执行文件的 sys.path

也就是说,一个项目在执行文件运行时,项目中其他的文件的模块或包被导入和引用时都是去执行文件的 sys.path查找的,被导入模块中有 sys.path.append('路径'),在执行文件运行时,被导入的模块会将路径添加到环境变量列表中。

#模块:mmm

print('运行了。。。。')

import sys

sys.path.append('/11111111111')

#执行文件

import sys

import mmm

sys.path.append('/aaaaaaaaaaaaaaaaaaaaaaaaaa')

print(sys.path)

结果展示:

运行了。。。。

['/Users/tophan/Desktop/代码', '/Users/tophan/Desktop/代码', '/Applications/PyCharm.app/Contents/helpers/pycharm_display', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Users/tophan/Library/Python/3.6/lib/python/site-packages', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages', '/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend', '/11111111111', '/aaaaaaaaaaaaaaaaaaaaaaaaaa']

#被导入模块中有 sys.path.append('路径'),在执行文件运行时,被导入的模块会将路径添加到环境变量列表中。

2 导入包 和 模块遵循原则

1、凡是在导入时带点的,点的左边都必须是一个包,否则非法。

2、可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

from a.b.c.d.e.f import xxx

import a.b.c.d.e.f

#其中a、b、c、d、e 都必须是包

导入包:

1、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

2、import 导入文件时,产生名称空间中的名字来源文件

​import 包,产生的名称空间的名字同样来源于文件,即包下的__ init __ .py , 导入包本质就是导入该文件。

3、导入包的两种方式

1、绝对导入

​绝对导入,以包的文件夹作为起始来进行导入

import sys

from foo.m3 import f3

2、相对导入

​相对导入:仅限于包内使用,不能跨出包(包内模块之间的导入,推荐使用相对导入)

​. :代码当前文件夹

​.. : 代表上一层文件夹

#目录

foo--|

bbb

|

m1

|

m2

|

foo1

# 在foo1执行文件中

from .m1 import f1

from .m2 import f2

from .bbb.m4 import f4

强调:

​1、相对导入不能跨出包,所以相对导入仅限于包内模板彼此之间应用

​2、绝对导入时没有任何限制的,所以绝对导入是一种通用的导入方式

补充:

在pycharm中导入自己写的模块时,得不到智能提示,并在模块名下出现下红线,但是代码可以执行,错误提示为下图所示:

原因:出现 以上情况,是因为文件目录设置的问题,pycharm中的最上层文件夹是项目文件夹,在项目中导包默认是从这个目录下寻找,当在其中再次建立目录,目录内的py文件如果要导入当前目录内的其他文件,单纯的使用import导入,是得不到智能提示的,这是pycharm设置的问题,并非导入错误。

解决方法:

​从根目录下导入时,就会有提示信息

from ATM.lib.common import logger

python中的模块原则_python 的模块与包相关推荐

  1. python中的帮助系统_python系统模块

    Python中大多数系统接口都集中在两个模块:sys和os.这么说有点过于简单化 还有一些其他的表转模块也属于这个领域他们包括: glob 用于文件名的扩展 socket 用于网络连接和进程间通信(I ...

  2. python中import time用法_Python time模块的用法

    在实际应用中,经常需要得到一些时间信息,如得到某个事件发生的时间.某个资源的有效期限及某个时间是否是周末等. 在 Python 中,有一个系统自带的库 time,在该库中提供了对时间.日期进行操作的一 ...

  3. python中的替换函数_python:替换模块类中的函数

    我试图替换类中定义的函数,以便在不更改实际代码的情况下修改其函数(如内部工作). 我以前从来没有这样做过,因此在更换它时遇到一些问题. 更改代码会让我访问python库中的包,这不是一个很好的选择. ...

  4. python中calendar怎么用_Python时间模块datetime、time、calendar的使用方法

    import time import datetime #两日期相减 d1 = datetime.datetime(2005, 2, 16) d2 = datetime.datetime(2004, ...

  5. python中configparser详解_python ConfigParser模块详解

    功能介绍 在程序中使用配置文件来灵活的配置一些参数是一件很常见的事情,配置文件的解析并不复杂,在python里更是如此,在官方发布的库中就包含有做这件事情的库,那就是ConfigParser,这里简单 ...

  6. Python中import导入上一级目录模块及循环import问题的解决

    Python中import导入上一级目录模块及循环import问题的解决 参考文章: (1)Python中import导入上一级目录模块及循环import问题的解决 (2)https://www.cn ...

  7. Python中第三方的库(library)、模块(module),包(package)的安装方法以及ImportError: No module named...

    Python中,想要安装第三方安装包,即third library,package等,对于熟悉的人来说,很简单. 但是对于新手,至少对于之前的我,很难,往往只是安装一个很小的包,都被搞得一头雾水. 现 ...

  8. python中使用sys模板和logging模块获取行号和函数名的方法

    From: http://www.jb51.net/article/49026.htm 这篇文章主要介绍了python中使用sys模板和logging模块获取行号和函数名的方法,需要的朋友可以参考下 ...

  9. python中常见的漏洞_Python常见安全漏洞及修复方法集合!你所不会的这里都有!...

    [51CTO技术沙龙]10月27日,让我们共同探索AI场景化应用实现之道 --> 概述 编写安全的代码很困难,当你学习一门编程语言.一个模块或框架时,你会学习其使用方法.在考虑安全性时,你需要考 ...

最新文章

  1. [转载] 晓说——第3期:梦回青楼 爱与自由的温柔乡(上)
  2. C# 对象深拷贝、浅铐贝、直接拷贝(转)
  3. 「后端小伙伴来学前端了」Vue中 this.$set的用法 | 可用于修改对象中数组的某一个对象、 可用于更新数据到视图
  4. QT学习:数据库基本概念
  5. 关于高级导数的一个不等式估计
  6. WCF技术剖析(卷1)正式出版
  7. shell 使用eval重新计算变量的变量
  8. 华三的stp根桥、端口角色选举规则
  9. 微信支付不靠谱 星巴克喝一杯咖啡被刷掉一千多
  10. 你真的理解亲密关系的价值吗?
  11. 哪些东西买了之后,会让人因生活质量和幸福感提升而感觉相见恨晚?
  12. 在计算机网络中wm表示什么网,网络基础知识
  13. 快衰落、慢衰落,平坦衰落、频率选择性衰落
  14. 【CocosBuilder 开发系列之一】cocos2dx使用CocosBuilder完成骨骼动画
  15. Unity(物理引擎)
  16. 物联网毕设 -- 智能花盆系统(蓝牙+APP)
  17. 10 23 周总结+一道奇妙数论
  18. 在Ubuntu上安装docker
  19. RANSAC及其经典变种
  20. table是什么函数c语言,c语言中table的用法

热门文章

  1. [云炬创业基础笔记]第七章创业资源测试6
  2. 2020中级财管(押题班)
  3. ustc小道消息20211230
  4. 科大星云诗社动态20210413
  5. 科大星云诗社动态20210509
  6. Ubunt16.04 搭建 GPU 显卡驱动 + CUDA9.0 + cuDNN7 详细教程
  7. 台湾大学林轩田机器学习技法课程学习笔记2 -- Dual Support Vector Machine
  8. Matlab神经网络十讲(7): Self-Organizing and LVQ Networks
  9. 有监督回归:鲁棒学习
  10. VTK修炼之道69:体绘制讨论_颜色传输函数