模块和包,模块与包

壹.哪些是模块

  3个模块正是1个分包了python定义和注解的文书,文件名便是模块名字加上.py的后缀

  其实import加载的模块分别为死歌通用项目:

    一.施用pytho编写的代码(.py文件)

    二.已被编写翻译为共享库或DLL的C或C++扩张

    3.包好1组模块的包

    四.选择C编写并链接到python解释器的松开模块

一丶模块

模块

1、什么是模块?

3个模块就是二个Python文件,文件名就是模块名字加上.py后缀。由此模块名称也务必符合变量名的命名规范。

  一运用python编写的代码

  2已被编写翻译为共享库或DLL的C或C++增加

  3包好一组模块的包

  4选用C编写并链接到python解释器的停放模块

二、为啥要运用模块?

要是您退出python解释器然后再行进入,那么你从前定义的函数也许变量都将遗失,由此我们平常将次第写到文件中以便永久保存下去,须求时就经过python
test.py形式去执行,此时test.py被称呼脚本script。

乘胜程序的向上,作用更是多,为了方便管理,我们通常将次第分成3个个的文件,那样做程序的构造更清楚,方便管理。那时我们不光能够把那么些文件作为脚本去实践,还足以把她们作为模块来导入到其余的模块中,完毕了效能的重复使用,

三、怎么着利用模块?

  • 方式一:import
  • 方式二:from …
    import …

一、模块

2.什么样团结写三个模块

    创建一个py文件,给它起二个适合变量命名规则的名字,这些名字正是模块名

  大家平日说模块模块的,究竟什么样是模块呢?

import

先是,自定义一个模块my_module.py,文件名my_module.py,模块名my_module

亚洲必赢官网 1亚洲必赢官网 2

name = "我是自定义模块的内容..."def func():    print("my_module: ", name)print("模块中打印的内容...")

my_module

在import三个模块的进度中,发生了哪些工作?

# 用import导入my_module模块import my_module>>>模块中打印的内容... # 怎么回事,竟然执行了my_module模块中的print语句import my_moduleimport my_moduleimport my_moduleimport my_moduleimport my_module>>>模块中打印的内容... # 只打印一次

从地点的结果能够看来,import二个模块的时候一定于实践了那个模块,而且3个模块是不会再次被导入的,只会导入二次(python解释器第2回就把模块名加载到内部存款和储蓄器中,之后的import都只是在相应的内部存储器空间中追寻。)成功导入1个模块后,被导入模块与公事之间的命名空间的标题,就改成接下去要搞理解的概念了。

被导入模块与本文件之间命名空间的涉嫌?

比方当前文件也有1个变量为:
name = ‘local file’, 也有1个同名的func方法。

# 本地文件name = "local file"def func():    print    # 本地文件有跟被导入模块同名的变量和函数,究竟用到的是哪个呢?import my_moduleprint(my_module.name)   # 根据结果可以看出,引用的是模块里面的namemy_module.func()        # 执行的是模块里面的func()函数>>>模块中打印的内容...我是自定义模块的内容...my_module:  我是自定义模块的内容...print             # 使用的是本地的name变量func()                  # 使用的是本地的func函数>>>local filelocal file

在import模块的时候发生了上边包车型客车几步:

  1、先物色模块

  二、如若找到了,就在内部存款和储蓄器中开拓1块空间,从上至下执行那个模块

  3、把这几个模块中用到的目的都选择到新开发的内部存款和储蓄器空间中

  四、给那么些内部存款和储蓄器空间创造三个变量指向那个空间,用来引用其内容。

  总而言之,模块与公事之间的内部存款和储蓄器空间始终是割裂的

亚洲必赢官网 3

给导入的模块取外号,用as关键字

假设导入的模块名太长倒霉记,那么能够透过“import 模块名 as
别称”的法子给模块名取三个别称,但那时本来的模块就不再生效了(相当于创制了新的变量名指向模块内部存储器空间,断掉原模块名的引用)。

# 给my_module模块取别名import my_module as smprint>>>我是自定义模块的内容...print(my_module.name)   # 取了别名后,原来的模块名就不生效了>>>NameError: name 'my_module' is not defined

给模块去别称,还足以使代码越来越灵活,缩短冗余,常用在根据用户输入的不等,调用差别的模块。

# 按照先前的做法,写一个函数,根据用户传入的序列化模块,使用对应的方法def dump:    if method == 'json':        import json        with open('dump.txt', 'wb') as f:            json.dump('xxx', f)    elif method == 'pickle':        import pickle        with open('dump.txt', 'wb') as f:            pickle.dump('xxx', f)# 上面的代码冗余度很高,如果简化代码?通过模块取别名的方式,可以减少冗余def dump:    if method == 'json':        import json as m    elif method == 'pickle':        import pickle as m    with open('dump.txt', 'wb') as f:        m.dump('dump.txt', f)

何以同时导入八个模块?

方式一:每行导入八个模块

import osimport sysimport time

主意二:壹行导入多少个模块,模块之间通过逗号“,”来分隔

import os, sys, my_module

然则,依据PEP8规范规定选用第叁种形式,并且两种模块有先后顺序(内置>第二方>自定义)

# 根据PEP8规范import osimport djangoimport my_module

模块搜索路径

因而sys内置模块,大家精晓sys.path存款和储蓄了具备模块的途径,然则不荒谬的sys.path的路径中除去内置模块,第2方模块所在的门径之外,唯有3个路径是永久正确的,便是当前履行的文件所在目录。贰个模块是或不是能够被导入,就取决于那些模块所在的目录是不是在sys.path中。

python解释器在运维时会活动加载1些模块,能够利用sys.modules查看

在率先次导入有个别模块时(比如my_module),会先检查该模块是或不是已经被加载到内部存储器中(当前履行文书的称号空间对应的内部存款和储蓄器),要是有则直接引用

要是未有,解释器则会寻找同名的内建立模型块,要是还尚无找到就从sys.path给出的目录列表中逐条寻找my_module.py文件。

由此计算模块的追寻顺序是:内部存款和储蓄器中已经加载的模块->内置模块->sys.path路径中包蕴的模块

须求特别注意的是:我们自定义的模块名不该与系统内置模块重名。

模块和剧本

运转3个py文件有二种办法,不过那二种实施办法之间有三个显著的差异,正是__name__。

  1、已脚本的法门履行:cmd中“python
xxx.py” 只怕pycharm等IDE中实践

    __name__ =
‘__main__’

  贰、导入模块时实施:import模块,会履行该模块。

    __name__ =
模块名

而是,当您有1个py文件既能够作为脚本执行,又能够看成模块提必要任何模块引用时,那时作为模块要求导入时而不出示多余的打字与印刷逻辑/函数调用,所以那些逻辑能够放在“if __name__ = ‘__main__’: xxx”
代码块中。

如此py文件作为脚本执行的时候就可见打字与印刷出来,以模块被导入时,便不会打字与印刷出来。

  一、什么是模块

叁.模块的导入

  导入多个模块便是实施三个模块

  模块导入的经过中产生了哪些:

    1.找到那些模块

    贰.断定这么些模块是或不是被导入过了

    三.就算未有被导入过:

      成立3个属于那一个模块的命名空间

      让模块的名字指向那个空间

      执行那么些模块中的代码

  给模块起外号:起了小名之后,就只可以使用这一个模块的小名引用变量了

  导入三个模块:

    import os,time

  规范提出:

    模块应该三个三个的导入:

      内置模块

      扩展(第三方)模块

      自定义模块

  from  import  

    模块导入的进度中发出了什么样:

亚洲必赢官网 ,      1.找到要被导入的模块

      贰.判定这些模块是或不是被导入过

      叁.假如那么些模块没被导入过

        成立三个属于那一个模块的命名空间

        执行那几个文件

        找到要导入的变量

        给导入的变量成立3个引用,指向要导入的变量

 1 #测试一:导入的函数read1,执行时仍然回到my_module.py中寻找全局变量money
 2 #demo.py
 3 from my_module import read1
 4 money = 1000
 5 read1()
 6 
 7 #测试二:导入的函数read2,执行时需要调用read1(),仍然回到my_module.py中找read1()
 8 #demp.py
 9 from my_module import read2()
10 def read1():
11     print("1")
12 read2()

只要当前有重名read壹只怕read二,那么会有覆盖效果

1 #测试三:导入的函数read1,被当前位置定义的read1覆盖掉了
2 #demo.py
3 from my_module import read1
4 def read1():
5     print("1")
6 read1()
7 执行结果:
8 from the my_module.py
9 1

from my_module import
*把my_module中拥有的不是以下划线(_)初阶的名字都导入到当前岗位

from my_module import *
print(money)
print(read1)
print(read2)

执行结果:
from the my_module.py
1000

如果my_module.py中的名字前加_,即_money,则frommy_module import
*,_money不能够被导入

模块引用中的情形:模块之间不容许循环引用

  2个模块正是包罗了Python定义和注明的文件,文件名正是模块名字加上.py的后缀

from … import …

from…import是另一种导入模块的方式,就算您不想每一趟调用模块的目的都抬高模块名,就能够利用那种艺术。

在from … import
… 的进度中发生了怎么事情?

from my_module import name, funcprint     # 此时引用模块中的对象时,就不要再加上模块名了。func()

  1、寻找模块

  二、假诺找到模块,在内部存款和储蓄器中开拓1块内部存款和储蓄器空间,从上至下执行模块

  三、把模块中的对应关系总体都封存到新开发的内部存款和储蓄器空间中

  四、建立二个变量xxx引用改模块空间中对应的xxx,
即使未有import进来的时候,就采取持续。

from … import …
形式取小名

与import格局如出一辙,通过”from
模块名 import 对象名 as 小名”。

from my_module import name as n, func as f

from … import
*

import *
约等于把这么些模块中的所著名字都引进到近日文件中,然则只要您协调的py文件如若有重名的变量,那么就会产生倒霉的影响,因而使用from…import
*时需求谨慎,不建议接纳。

*模块和包,模块与包。 与
__all__

__all__是与*相当使用的,在被导入模块中扩张1行__all__=[‘xxx’,’yyy’],就鲜明了接纳import
*是不得不导入在__all__中鲜明的属性。

# 在my_module模块中定义__all____all__ = ['name']name = 'My module...'def func():    print("my_module: ", name)# 在其他文件中通过import *导入所有属性from my_module import *print>>>My module...func()>>>NameError: name 'func' is not defined

拓展知识点:

  pyc文件与pyi文件
*

  pyi文件:跟.py1样,仅仅看做三个python文件的后缀名。

  pyc文件:
python解释器为了提升加载模块的快慢,会在__pycache__目录中变化模块编写翻译好的字节码文件,并且相比较修改时间,只有模块改变了,才会再也编写翻译。pyc文件仅仅用于节省了运营时间,可是并无法增加程序的施行成效。

  模块的导入和修改*

  一.导入模块后,模块就已经被加载到内部存储器中,此后计算对模块进行改动,读取的剧情依然内部存款和储蓄器中原来的结果。

  二.万壹想让改动生效,能够透过“from
importlib import reload”, 须求’reload
模块名’重新加载模块,改动才生效。

  模块的轮回利用
****

  谨记模块的导入必须是单链的,无法有轮回引用,借使存在循环,那么正是程序设计存在难点。

  dir
***

  可以获得该模块中兼有的名字,而且是字符串类型的,就能够透过反射去实践它。

    常见的现象:1个模块就是贰个含有了python定义和阐明的公文,文件名正是模块名字加上.py的后缀。

4.模块的加载与修改

  每种模块只被导入二回,放入到sys.modules中,若是改变了模块中的内容,必须重启程序

  但实则import加载的模块分为多少个通用项目:

包是一种通过‘.模块名’来公司python模块名称空间的点子。

无论import方式依然from
… import
形式,凡是在导入语句中相遇带点的,都要第权且间进步警惕:那是关于包才有的导入语法

包是目录级的,文件夹是用来组成py文件(包的精神正是二个涵盖__init__.py文件的目录)

import导入文本时,发生名称空间中的名字来自与公事,import包,发生的称谓空间的名字同样来自与公事,即包下的__init__.py,导入包本质正是在导入文本

  注意:

    1、在python三中,尽管包下未有__init__.py文件,import包仍旧不会报错,而在python第22中学,包下一定要有该公文,不然import包会报错

    二、创设包的指标不是为了运转,而是被导入使用,记住,包唯有模块的一种方式而已,包即模块

包A和包B下有同有名的模特块也不会争执,如A.a与B.a来自多个指令空间

示范环境如下:

亚洲必赢官网 4亚洲必赢官网 5

import osos.makedirs('glance/api')os.makedirs('glance/cmd')os.makedirs('glance/db')l = []l.append(open('glance/__init__.py','w'))l.append(open('glance/api/__init__.py','w'))l.append(open('glance/api/policy.py','w'))l.append(open('glance/api/versions.py','w'))l.append(open('glance/cmd/__init__.py','w'))l.append(open('glance/cmd/manage.py','w'))l.append(open('glance/db/models.py','w'))map(lambda f:f.close

创制目录代码亚洲必赢官网 6亚洲必赢官网 7

glance/                   #Top-level package├── __init__.py      #Initialize the glance package├── api                  #Subpackage for api│   ├── __init__.py│   ├── policy.py│   └── versions.py├── cmd                #Subpackage for cmd│   ├── __init__.py│   └── manage.py└── db                  #Subpackage for db│   ├── __init__.py│   └── models.py

目录结构亚洲必赢官网 8亚洲必赢官网 9

#文件内容#policy.pydef get():    print('from policy.py')#versions.pydef create_resource:    print('from version.py: ',conf)#manage.pydef main():    print('from manage.py')#models.pydef register_models:    print('from models.py: ',engine)

文本内容

    但实则import加载的模块分为几个通用项目: 

5.把模块当成脚本来使用

  能够由此模块的全局变量__name__来查阅模块名:

    当做脚本运行:

      __name__等于’__main__’

    当做模块导入:

      __name = 模块名

  功用:用来控制.py文件在不一样的行使场景下进行不1的逻辑

  if __name__ == ‘__main__’:

 1 def fib(n):
 2     a,b = 0,1
 3     while b<n:
 4         print(b,end = '')
 5         a, b = b, a+b
 6     print()
 7 
 8 if __name__ == "__main__":
 9     print(__name__)
10     num = input("num:")
11     fib(int(num))

py文件:直接运转这些文件,那么些文件正是2个本子

    导入那几个文件,那一个文件便是2个模块

当一个py文件:

  当做叁个剧本的时候:能够独立的提供3个效益,能独立完结交互

  当成贰个模块的时候,能够被导入那调用那一个功用,不能够自主交互

1个文件中的__name__变量:

  当以此文件被看做脚本执行的时候:__name__ == ‘__main__’

  当以此文件被当做模块导入的时候:__name__ == ‘模块的名字’

    一.利用Python编写的代码

从包中程导弹入模块

从包中程导弹入模块有两种办法,可是无论哪类,无论在怎么岗位,都必须比照贰个规则:(举凡在导入时带点的,点的右边都无法不是一个包),不然违法。

对于导入后,在选拔就向来不那种范围,点的左侧能够是包,模块,函数,类(它们都得以用点的办法调用本身的习性)

相对而言import item 和from
item import
name的使用场景:假诺我们想平素动用name那么必须利用后者。

方式一:import

  例如:
包名1.包名2.包名3.模块名

# 在与包glance同级别的文件中测试import glance.db.modelsglance.db.models.register_models('mysql') """执行结果:from models.py mysql"""

方式二:from … import …

  例如:from
包名1.包名2 import 模块名

     from
包名1.包名2.模块名 import 变量名/函数名/变量名

  注意:须要小心的是from后import导入的模块,必须是明摆着的贰个无法带点,不然会有语法错误,如:from
a import b.c是不对语法

# 在与包glance同级别的文件中测试from glance.db import modelsmodels.register_models('mysql')"""执行结果:from models.py mysql"""from glance.cmd import managemanage.main()"""执行结果:from manage.py"""

    1 运用python编写的代码(.py文件)

陆.模块搜索路径

  在首先次导入某些模块时,会先检查该模块是还是不是业已被加载到内部存款和储蓄器中(当前进行文书的称谓空间对应的内部存款和储蓄器),如若有则直接引用,若是未有,解释器则会招来同名的内建立模型块,假如还尚无找到就从sys.path给出的目录列表中逐条寻找那几个模块

为此模块的搜寻顺序是:内部存款和储蓄器中已经加载的模块->内置模块->sys.path路径中包蕴的模块

 

    二.已被编写翻译为共享库或DLL的C或C++扩张

一向导入包

假若是一向导入2个包,那么一定于履行了这么些包中的__init__文件

并不会帮您把这些包下边包车型客车此外包以及py文件自动的导入到内部存款和储蓄器

一旦您愿意直接导入包之后,全数的那一个包上边包车型大巴别的包以及py文件都能一贯通过包来调用,那么需求你自身处理__init__文件。

__init__.py文件

不论是哪一类艺术,只就算首先次导入包依然是包的其余此外1些,都会相继执行包下的__init__.py文件;那个文件能够为空,可是也足以存放一些开首化包的代码。

绝对导入和相对导入

我们的最一级包glance是写给别人用的,然后在glance包内部也会有互相之间相互导入的急需,这时候就有相对导入和相对导入三种方法:

相对导入:以glance作为开局

对峙导入:用. 恐怕..
的不2秘诀作为开局(只幸亏多个包中使用,不能够用来不一样目录内)

纯属导入和相对导入示例:

绝对导入:    既然导入包就是执行包下的__init__.py文件,那么尝试在啊glance的__init__.py文件中"import api",执行一下,貌似没有报错,在尝试下在包外导入,情况如何?    在包外创建一个test.py文件,在里面操作如下:    import glance    glance.api    ModuleNotFoundError: No module named 'api'    原因:为什么还会报错?因为一个模块能不能被导入就看在sys.path中有没有路径,在哪里执行文件,sys.path永远记录该文件的目录。    (1)在glance的__init__.py文件中,sys.path的路径是:    'E:\\Python练习\\包\\glance'    所以能够找到同级的api    (2)但是在test文件中导入,此时sys.path的路径是:    'E:\\李彦杰\\Python练习\\包'    所以找不到不同层级的api,所以就会报No module name 'api'    解决办法一:    使用绝对路径(绝对路径为当前执行文件的目录)    (1)在glance包中的__init__.py中通过绝对路径导入:    "from glance import api"    (2)这样在test文件中执行,就能找到同层级的glance,再去里面找api    同理,如果想使用api包中的模块,也要在api包中的__init__.py文件中导入"from glance.api import policy, veersions",    (4)现在在test文件中调用glance下的api下的policy模块就不会报错:        import glance        glance.api.policy.get()        glance.api.versions.create_resource('测试')        执行结果:            from policy.py            from versions.py 测试绝对导入的缺点:如果以后包的路径发生了转移,包内的所有__init__.py文件中的绝对路径都需要改变解决办法二:    使用相对导入        . 表示当前目录        .. 表示上一级目录    (1)在glance包中的__init__.py中通过相对路径的形式导入:     “from . import api”    (2)同理在api包中的__init__.py中通过相对路径的形式导入:     “from . import policy,version”    (3)同样在test文件中调用glance下的api下的policy模块就不会报错:        import glance        glance.api.policy.get()        glance.api.versions.create_resource('测试')        执行结果:            from policy.py            from versions.py 测试相对导入的优点:    包发生路径转移,其中的相对路径都没有改变,所以不用逐个逐个修改。相对导入的缺点:    但凡带着相对导入的文件,只能当做模块导入,不能作为一个脚本单独执行!!!

扩充知识:

  同级目录下的包导入

  需要:现在内需在bin下边包车型地铁start文件中程导弹入core目录下的main模块;怎么破?

project├── bin                 #Subpackage for bin    ├── __init__.py    └── start.py├── core                #Subpackage for core    ├── __init__.py    └── main.py

# main.py文件中的内容:def func():    print("In main")

、在start中直接导入,因为路径不对,所以直接报错:

import main # 执行,报错ModuleNotFoundError: No module named 'main'

、由上面报错我们知道肯定路径不对,那么我们想到直接将core路径加进去不就好了吗?是的,这样是可行的

import syspath = 'E:\练习\包\core'   # 复制得到core的绝对路径sys.path.append     # 将core路径添加import main         # 再次导入便不会报错main.func()         # 执行结果:In main

、上面的方法看似可行,但是还是有一个问题,如果我将project打包发给别人,或者我换个环境运行呢?   那么又得更改对应的path。不怎么合理,那么我们看下面的方法:

import sysprint(__file__)ret = __file__.split('/')base_path = '/'.join(ret[:-2])sys.path.append(base_path)from core import mainmain.func()     # In main

 1、__file__ 可以得到当前文件的绝对路径,E:/练习/project/bin/start.py

 2、__file__.split 将当前文件的绝对路径进行处理,按照'/'分隔得到:['E:', '练习', 'project', 'bin', 'start.py']

 3、'/'.join 因为我们只需要拿到project项目的动态路径,所以进行切割,在jojn得到: E:/练习/project

 4、sys.path.append(base_path) 再将得到的路径添加到sys.path中

 5、from core import main   因为我们拿到的是project目录,所以导入是从当前路径的core包导入main模块

 6、main.func()  最后再是模块名.方法。

    ② 已被编写翻译为共享库或DLL的C或C++扩大

7.包

  一.文件夹中有2个__init__.py文件

  二.是多少个模块的聚集

  三.无论是import情势依然from..import方式,凡是在导入语句中(而不是在运用时)遭逢带点的,那是有关包才有的导入语法

  四.包是目录级的(文件夹级),文件夹是用来构成py文件(包的本质正是三个蕴涵__init__.py文件的目录)

  五.import导入文本时,发生名称空间中的名字来自文件,import包产生的名称空间的名字1样来自文件,即包下的__init__.py,导入包本质正是在导入该公文

  陆.导入一个包相当于实践了那么些包上边包车型地铁__init__.py文件

有关包相关的导入语句也分为import和from..import..三种,但不论哪一种,在什么样职位,都依照三个准绳:

      凡是在导入时带点的,点的左手都必须是三个包

对此导入后,在运用时就从不那种限制了,点的左侧能够是包,模块,函数,类(他们都得以用点的格局调用自个儿的习性)

绝对导入:

  在执行3个py脚本的时候,这几个本子以及这一个剧本同级的模块中只可以用相对导入

  缺点:

    全部的导入都要从1个根目录下今后解释文件夹之间的涉及

    假使当前导入包的文件和被导入的包的职位关系产生了变通,那么具有的init文件都要做相应的调动

1 import glance
2 glance.__init__.py
3 import api
4 sys.path = [path]
5 glance.api.policy.get()

相对导入:

  不供给去反复的修改路径

  只要一个包中的有着文件夹和文书的相对位置不发生变动,init文件就不须要调整

  不供给去关爱当前那一个包和被实践的文本之间的层级关系

  缺点:

    含有相对导入的py文件不能被直接执行

    必须放在包中被导入的调用才能健康的应用

一经只是从包中程导弹入模块的话,就不供给做别的多余的操作

借使期望导入包的时候,能够顺便的把模块也导入进来,需求统一筹划init文件夹

    三.包好1组模块的包

    叁 包好一组模块的包

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

    肆 选拔C编写并链接到python解释器的放置模块

import

  2、为啥要采用模块

  fromimport导入的历程中产生了怎样事情?

    若是你退出python解释器然后再行进入,那么您前边定义的函数或许变量都将遗失,因而大家平常将次第写到文件中以便永久保存下去,要求时就通过python
test.py格局去执            行,此时test.py被喻为脚本script。

  一.找到要被导入的模块

           
随着程序的上进,功用越多,为了方便管理,大家一般将先后分成1个个的公文,那样做程序的布局更清楚,方便管理。那时大家不仅能够把这几个文件作为脚本去执行,
         仍是可以把他们当作模块来导入到其余的模块中,完结了意义的再一次使用

  2.判定那么些模块是还是不是被导入过

  三、怎么着运用模块

  3.只要这些模块没被导入

    3.1 import

    成立三个属于这些模块的命名空间

    示例文件:spam.py,文件名spam.py,模块名spam       

    执行那一个文件

spam.py
print('from the spam.py')

money=1000

def read1():
    print('spam->read1->money',money)

def read2():
    print('spam->read2 calling read')
    read1()

def change():
    global money
    money=0

    找到你要导入的变量

    三.一.一 模块只在模块名第3次相遇导入import语句时才实施(import语句是足以在程序中的任意地点运用的,且针对同2个模块很import数次,为了以防你再次导入,python的优化
             
 手段是:第一遍导入后就将模块名加载到内部存款和储蓄器了,后续的import语句仅是对已经加载大内部存款和储蓄器中的模块对象扩展了1次引用,不会再也履行模块内的语句)

    给您要导入的变量创造3个引用,指向你要导入的变量

#test.py
import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
import spam
import spam
import spam

'''
执行结果:
from the spam.py
'''

  自定义模块:my_module.py,文件名my_module.py,模块名my_module

import sysprint(sys.modules)  #导入的模块会写在这里面sys.path.append(my_module)    #将my_module模块写入里面import my_module    #导入my_module模块print(my_module.name)    #调用my_module中的name

  我们得以从sys.module中找到当前曾经加载的模块,sys.module是二个字典,内部含有模块名与模块对象的炫耀,该字典决定了导入模块时是或不是须要再度导入。

  为模块起别称

# 给模块起别名import my_moudle as mm.read1#给模块起别名,起了别名之后,使用这个模块就都使用别名引用变量了

  三.一.二 每种模块都以三个独自的名目空间,定义在这几个模块中的函数,把那一个模块的称号空间作为全局名称空间,那样我们在编辑本身的模块时,就不要顾虑大家定义在祥和模块
          中全局变量会在被导入时,与使用者的全局变量争辩

  导入八个模块

#导入多个模块import os,timeimport os as o,time as t# 规范建议:先导入内置模块,再导入扩展模块,再导入自定义模块

  三.一.三计算:第3回导入模块spam时会做三件事:

  from..import

from my_module import read1def read1():    print('in my read1')from my_module import read2read1()

    壹.为源文件(spam模块)创立新的称呼空间,在spam中定义的函数和方式若是使用到了global时访问的正是那个称号空间。

  要求特别强调的一点是:python中的变量赋值不是壹种存款和储蓄操作,而只是1种绑定关系,如下:

from my_module import money,read1money=100 #将当前位置的名字money绑定到了100print #打印当前的名字read1() #读取my_module.py中的名字money,仍然为1000'''from the my_module.pymy_module->read1->money 1000'''

    2.在新创造的命名空间中推行模块中富含的代码,见早起始入import
spam

  frommy_moduleimport *

from my_module import * #将模块my_module中所有的名字都导入到当前名称空间printprintprintprint'''执行结果:from the my_module.py<function read1 at 0x1012e8158><function read2 at 0x1012e81e0><function change at 0x1012e8268>'''

    叁.成立名字spam来引用该命名空间

  __all__能约束*导入的变量的情节

__all__ = ['name','read1','read2']from my_module import *printread1

        三.1.4 为模块名起别名

  把模块当做脚本执行

    import spam as sm

  当一个py文件

    三.1.伍在一行导入四个模块

    当做2个剧本的时候:能够独立的提供1个效益,能自主实现交互

    import sys,os,re

    当成多个模块的时候,能够被导入这些调用这么些意义,无法自主交互

    3.2  from…import…

  我们得以由此模块的全局变量__name__来查看模块名:

    3.二.一 相比import
spam,会将源文件的称谓空间’spam’带到日前名称空间中,使用时必须是spam.名字的方法

  当做脚本运行:

               而from
语句也等于import,也会创建新的名目空间,不过将spam中的名字直接导入到当前的名号空间中,在当前名称空间中,直接运用名字就足以了、

    __name__等于’__main__’

      from spam import read1,read2
    这样在当前位置直接使用read1和read2就好了,执行时,仍然以spam.py文件全局名称空间
    如果当前有重名read1或者read2,那么会有覆盖效果。
    需要特别强调的一点是:python中的变量赋值不是一种存储操作,而只是一种绑定关系
    
    3.2.2 也支持as
    from spam import read1 as read
    3.2.3 也支持导入多行
    from spam import (read1,

                  read2,
                   money)
    3.2.4 from spam import * 把spam中所有的不是以下划线(_)开头的名字都导入到当前位置,大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题。

    可以使用__all__来控制*(用来发布新版本)

  当做模块导入:

    在*.py中新增一行

    __name__=模块名

    __all__=['money','read1'] #这样在另外一个文件中用from spam import *就这能导入列表中规定的两个名字

  功效:用来控制.py文件在差异的利用场景下执行不1的逻辑

    能够行使__all__来控制*(用来公布新本子)

  if__name__==’__main__’ 

def fib:       a, b = 0, 1    while b < n:        print(b, end=' ')        a, b = b, a+b    print()if __name__ == "__main__":    print(__name__)    num = input('num :')    fib

    倘若spam.py中的名字前加_,即_money,则from spam import
*,则_money不能够被导入

  模块搜索路径

    三.二.伍 思考到品质的由来,每一种模块只被导入一次,放入字典sys.module中,倘使您转移了模块的始末,你必须重启程序,python不帮助再一次加载或卸载以前导入的模块,

  Python解释器在运转时会活动加载1些模块,能够采取sys.modules查看

    三.3 把模块当做脚本执行

  在首先次导入有个别模块时(比如my_module),会先检查该模块是还是不是已经被加载到内部存款和储蓄器中,假诺有则平素引用,若是没有,解释器则会寻找同名的内建立模型块,如若还从未找到就送sys.path给出的目录列表中相继寻找my_module.py文件

    大家可以因此模块的全局变量__name__来查阅模块名:

  所以计算模块的查找顺序是:内部存储器中已经加载的模块->内置模块->sys.path路径中隐含的模块

import sysimport calculateprintpath = r'D:\Learn\day21\模块的循环引用'sys.path.append

     当做脚本运维:
    __name__ 等于’__main__’

  编译Python文件

    当做模块导入:
    __name__=

    一.即便是在命令中被直接导入模块,则遵照那种方法,每一次导入都会再度编写翻译,并且不会储存编写翻译后的结果

    成效:用来控制.py文件在差异的利用场景下进行分化的逻辑
    if __name__ == ‘__main__’:

    二.假设源文件不存在,那么缓存的结果也不会被采纳,若是想在未有源文件的意况下来使用编写翻译后的结果,则编写翻译后的结果必须在源目录下

    三.4模块搜索路径

  dir()函数

    python解释器在运营时会自动加载1些模块,能够采纳sys.modules查看

  内建函数dir是用来寻觅模块中定义的名字,重临二个平稳字符串列表.固然未有参数,dir()列举出如今定义的名字

import my_moduledir(my_module)

    在率先次导入某些模块时(比如spam),会先反省该模块是还是不是业已被加载到内存中(当前实践文书的名目空间对应的内部存款和储蓄器),如果有则平素引用

二丶包

  一.无论是import格局还是from…import格局,凡是在导入语句中相遇带点的,都要第暂且间升高警觉:那是有关包才有的导入语法

  贰.包是目录级的,文件夹是用来构成py文件(包的原形正是八个包含__init__.py文件的目录)

  三.import导入文本时,发生名称空间中的名字源于文件,import包,发生的名称空间的名字同样来自文件,即包下的__init__.py,导入包的原形正是在导入该文件

  强调:

  1.在Python三中,即便包下未有__init__.py文件,import包照旧不会报错,而在Python第22中学,包下一定要有该文件,不然import包报错

  二.创造包的指标不是为着运转,而是被导入使用,记住,包只是形式的1种情势而已,包即模块

亚洲必赢官网 10亚洲必赢官网 11

import osos.makedirs('glance/api')os.makedirs('glance/cmd')os.makedirs('glance/db')l = []l.append(open('glance/__init__.py','w'))l.append(open('glance/api/__init__.py','w'))l.append(open('glance/api/policy.py','w'))l.append(open('glance/api/versions.py','w'))l.append(open('glance/cmd/__init__.py','w'))l.append(open('glance/cmd/manage.py','w'))l.append(open('glance/db/models.py','w'))map(lambda f:f.close

始建目录代码亚洲必赢官网 12亚洲必赢官网 13

glance/                   #Top-level package├── __init__.py      #Initialize the glance package├── api                  #Subpackage for api│   ├── __init__.py│   ├── policy.py│   └── versions.py├── cmd                #Subpackage for cmd│   ├── __init__.py│   └── manage.py└── db                  #Subpackage for db    ├── __init__.py    └── models.py

目录结构亚洲必赢官网 14亚洲必赢官网 15

#文件内容#policy.pydef get():    print('from policy.py')#versions.pydef create_resource:    print('from version.py: ',conf)#manage.pydef main():    print('from manage.py')#models.pydef register_models:    print('from models.py: ',engine)

文件内容

  在导入包时必须遵循三个尺度:凡是在导入时带点的,点的右侧都必须是2个包

from..import

内需专注的是from后导入的模块,必须是显明的三个不可能带点,不然会有语法错误

from glance.db import modelsmodels.register_models('mysql')from glance.db.models import register_modelsregister_models('mysql')

    假若未有,解释器则会寻找同名的内建模块,假若还并未有找到就从sys.path给出的目录列表中各样寻找spam.py文件。

import

import glance.db.modelsglance.db.models.register_models('mysql') 

    所以计算模块的摸索顺序是:内部存款和储蓄器中已经加载的模块->内置模块->sys.path路径中蕴藏的模块

__init__.py文件

    3.5编译python文件

  不管是哪一种艺术,只若是率先次导入包照旧包的别的别的部分,都会相继执行李包裹下的__init__.py文件,那几个文件可以为空,可是也能够存在部分早先化包的代码

    为了升高加载模块的速度。python解释器会在__pycache__目录中下缓存各个模块编写翻译后的本子,格式为:
module.version.pyc。平常会蕴藏python的版本号。例如,在                  
   
CPython3.3本子下,spam.py模块会被缓存成__pycache__/spam.cpython-3三.pyc。那种命名规范保障了编写翻译后的
              结果多版本共存。

fromglance.apiimport *

二、包

  此处是想从包api中程导弹全体,实际上该语句只会导入包api下__init__.py文件中定义的名字,大家能够在这几个文件中定义__all__:

#在__init__.py中定义x=10def func():    print('from api.__init.py')__all__=['x','func','policy']

  包是一种通过接纳‘.模块名’来协会python模块名称空间的情势。

相对导入和龃龉导入

    相对导入:以glance作为开局

    相对导入:用.也许..的措施最佳早先(只能在多个包中使用,无法用来差别的目录内)

    例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

在glance/api/version.py#绝对导入from glance.cmd import managemanage.main()#相对导入from ..cmd import managemanage.main()

  尤其供给留意的是:能够用import导入内置也许第2方模块(已经在sys.path中),可是要断然幸免选用import来导入自定义包的子模块(未有在sys.path中),应该使用from…
import …的相对化也许相对导入,且包的对立导入只可以用from的方式。

  1.
无论import形式照旧from…import格局,凡是在导入语句中(而不是在接纳时)遇到带点的,都要第如今间提升警惕:那是关于包才有的导入语法

  相对导入:

亚洲必赢官网 16亚洲必赢官网 17

glance/                   ├── __init__.py      from glance import api                             from glance import cmd                             from glance import db├── api                  │   ├── __init__.py  from glance.api import policy                              from glance.api import versions│   ├── policy.py│   └── versions.py├── cmd                 from glance.cmd import manage│   ├── __init__.py│   └── manage.py└── db                   from glance.db import models    ├── __init__.py    └── models.py绝对导入

相对导入

  贰.
包是目录级的(文件夹级),文件夹是用来整合py文件(包的实质就是2个包涵__init__.py文件的目录)

  绝对导入:

亚洲必赢官网 18亚洲必赢官网 19

glance/                   ├── __init__.py      from . import api  #.表示当前目录                     from . import cmd                     from . import db├── api                  │   ├── __init__.py  from . import policy                     from . import versions│   ├── policy.py│   └── versions.py├── cmd              from . import manage│   ├── __init__.py│   └── manage.py    from ..api import policy                        #..表示上一级目录,想再manage中使用policy中的方法就需要回到上一级glance目录往下找api包,从api导入policy└── db               from . import models    ├── __init__.py    └── models.py相对导入

周旋导入

  三. import导入文本时,爆发名称空间中的名字来自文件,import
包,发生的称号空间的名字1样来自文件,即包下的__init__.py,导入包本质就是在导入该公文

  单独导入包

强调:

  单独导入包名称时不会导入包中全部包涵的全体子模块,如:

#在与glance同级的test.py中import glanceglance.cmd.manage.main()'''执行结果:AttributeError: module 'glance' has no attribute 'cmd''''

  一. 在python三中,即便包下未有__init__.py文件,import
包如故不会报错,而在python第22中学,包下一定要有该公文,否则import 包报错

  解决格局:

#glance/__init__.pyfrom . import cmd#glance/cmd/__init__.pyfrom . import manage

  二.
创设包的目标不是为着运维,而是被导入使用,记住,包只是模块的1种样式而已,包即模块

  执行:

#在于glance同级的test.py中import glanceglance.cmd.manage.main()

  _init__.py文件

  importglance之后直接调用模块中的方法

亚洲必赢官网 20亚洲必赢官网 21

glance/                   ├── __init__.py     from .api import *                    from .cmd import *                    from .db import *    ├── api                  │   ├── __init__.py   __all__ = ['policy','versions'] │   ├── policy.py│   └── versions.py├── cmd               __all__ = ['manage']    │   ├── __init__.py│   └── manage.py    └── db                __all__ = ['models']                  ├── __init__.py    └── models.pyimport glancepolicy.get()import glance

View Code

  软件开发规范

亚洲必赢官网 22

*  不管是哪类情势,只如果率先次导入包依然是包的其它其它一些,都会挨个执行李包裹下的__init__.py文件(我们得以在每一种包的文书内都打印一行内容来验证一下),这么些文件可以为空,但是也足以存放一些初步化包的代码。*

*   2.2 from glance.api import \

*    在讲模块时,大家早就探讨过了从二个模块内导入全体\,此处大家斟酌从二个包导入全部*。

      此处是想从包api中程导弹入全体,实际上该语句只会导入包api下__init__.py文件中定义的名字,大家得以在那几个文件中定义__all___:

   二.三 相对导入和争论导入

    导入和相持导入三种艺术:

    相对导入:以glance作为开局

    相对导入:用.或然..的措施最佳起头(只可以在2个包中使用,不能够用于不相同目录内)

    尤其须求留意的是:能够用import导入内置或然第一方模块(已经在sys.path中),不过要相对防止选择import来导入自定义包的子模块(未有在sys.path中),应该利用
                  from… import
…的绝对大概相对导入,且包的争辨导入只好用from的款式。

   二.四单独导入包

    单独导入包名称时不会导入包中全体包蕴的全数子模块,如

 

 

 

 

 
网站地图xml地图