码迷,mamicode.com
首页 > 编程语言 > 详细

python之模块、包的导入过程和开发规范

时间:2018-09-07 23:16:12      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:命名   bsp   存在   两种   多个   span   bpa   判断   语法错误   

摘要:导入模块、导入包、编程规范


以My_module为例,My_module的代码如下:
 __all__ = [name,read]

print(in mymodule)

name = 帅锅

def read():
    print(in read,name)

def read2():
    print(in read2,name)

if __name__ == __main__:
    print(in mymodule)
    print(__name__ : ,__name__)


一、导入模块
1、import 模块名
1-1、在import的过程中发生了哪些事情:
import一个模块相当于先执行了一次这个被导入模块,然后在本命名空间建立一个与被导入模块命名空间的联系,
相当于在本命名空间新建了一个变量,这个变量名称是被导入模块的名称,指向被导入模块的命名空间。

1-2、一个模块不会被重复导入,也就是说,import了一次这个模块,然后再import一次,也只是执行了第一次的imoptr
import My_module  # 执行了
import My_module  # 不会执行


1-3、如何去使用被导入模块中的名字
import My_module
print(My_module.name)               # 打印出My_module中的name
My_module.My_module_fun()   # 执行了My_module中的函数

1-4、小结导入模块的过程
导入模块的时候:
    1.寻找模块
    2.如果找到了,就开辟一块空间,执行这个模块
    3.把这个模块中用到的名字都收录到新开辟的空间中
    4.创建一个变量来引用这个模块的空间(变量名与这个模块名一致)

    *1.模块不会被重复导入
    *2.模块和文件之间的内存空间始终是隔离的
    *3.模块的名字必须是符合变量命名规范的
技术分享图片
1-5、本文件中存在与导入模块相同的变量 # My_module中的内容: name = 帅锅 def read(): print(in read,name) # 执行文件的内容: import My_module My_module.read() # in read 帅锅 name = SB My_module.read() # in read 帅锅 My_module.name = SB My_module.read() # in read SB 总结: 在本文件中定义了一个与导入模块相同的变量, 并不会影响导入模块中的变量,因为这两个变量是存在不同的命名空间中的,互不影响。 1-6、本文件中存在一个变量,这个变量名是导入的模块名 这个时候就相当于把指向导入模块的指针断开了,再指向新的值 My_module = 1 print(My_module) # 1 My_module.read() #报错
技术分享图片
    
1-7、一次导入多个模块的方式
import os,time,My_module
但是一般不建议这么使用,因为根据pep8规范(python编写规范):
我们导入模块的顺序应该是:内置模块,第三方模块,自定义模块
import os          # 内置
import time      # 内置

import django  # 第三方

import my_module  # 自定义


1-8、给模块起别名,一旦给模块起了别名,那么原名就不能使用了
import My_module as m
print(m.name)  # 帅锅
print(My_module.name)  # 报错


1-9、如何判断模块能否被导入
sys.path是一个存放了所有模块路径的列表,
一个模块是否能被导入,就看这个模块所在的目录在不在sys.path中,
如果这个模块的路径不在sys.path中,那么就不可被导入,
不过可以自己手动添加:sys.path.append(“自定义的模块路径”)
    

    
1-10、循环引用模块(看图) 
技术分享图片
1-11、运行一个py文件的两种方式方式 1,直接运行它 : 在cmd终端运行: python xx.py 或者在pycharm中直接运行 当用这种方式运行这个py文件,那么这个py文件就称为:脚本 这个时候py文件中的:__name__ == __main__ 2,导入它 : 导入一个模块,也会运行一次这个py文件 当用这种方式运行py文件,这个py文件就称为:模块 这个时候py文件中的:__name__ == 模块名 import My_module __name__ = my_module 例如: 在My_module中有这样的代码: print(in mymodule) print(__name__ : ,__name__) 那么直接在My_module中运行结果为:in mymodule __name__ : __main__ 在导入My_module的文件中执行导入模块(会默认执行一次My_module) import My_module 然后执行,结果为:in mymodule __name__ : My_module 2、from xx import xx 2-1在from import的过程中发生了哪些事情 from My_module import name from My_module import read 1,要找到My_module 2,开空间,执行my_module 3,所有的My_module中的名字都存储在My_module所属的空间中 4,本文件空间中建立对应的变量名(name,read),分别取引用My_module空间中对应的名字 from My_module import name from My_module import read print(name) # 帅锅 read() # in read 帅锅
技术分享图片

2-2、引用模块的变量后,进行修改(看图)
from My_module import name
from My_module import read
print(name)   # 帅锅

name = aaa
read()            # in read 帅锅

print(name)  # aaa
技术分享图片

2-3、from import 多个内容 from My_module import name,read,read2 2-4、给导入的内容起别名 from My_module import name as n,read as r,read2 as r2 2-5、from import *和 __all__关系 1,只有from import * 没有__all__的时候,My_module的所有变量都可以在本文件中使用 from My_module import * print(name) # 帅锅 read() # in read 帅锅 read2() # in read2 帅锅 2,即有from import * 也有__all__的时候,只有被__all__声明的变量才能在本文件中使用 My_module中:__all__ = [name,read] 本文件中执行: from My_module import * print(name) # 帅锅 read() # in read 帅锅 read2() # 报错:name ‘read2‘ is not defined 2-6、模块的导入和修改 模块在导入后,在程序运行期间,你再去修改导入的模块,导入的内容依旧是不变的。 如果硬是要在程序运行期间修改模块的内容,并让修改的内容生效,那么可以使用reload. from importlib import reload ‘‘‘ 在这期间修改模块的内容 ‘‘‘ # 重新reload,修改的内容就生效了 reload(My_module) 3、补充的内容 1.pyc文件、pyi文件 * pyc文件是导入包的时候自动产生的字节码文件,只能提高程序的启动效率并不能提高程序的执行效率 2.模块的导入和修改 * 3.模块的循环引用 **** 不能循环 4.dir(模块名) *** 可以获取这个模块中的所有名字 二、导入包 11.无论是import形式还是from...import形式,凡是在导入语句中遇到带点的都是关于包的导入语法。 2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录) 3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件 4.导入包就相当于执行力这个包下的__init__.py文件,在__init__下导入了什么模块,你就等于导入了什么模块 强调:   1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包会报错   2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块 2、目录结构创建 创建代码目录: import os os.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() ,l) 目录结构: 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 文件内容 #policy.py def get(): print(from policy.py) #versions.py def create_resource(conf): print(from version.py: ,conf) #manage.py def main(): print(from manage.py) #models.py def register_models(engine): print(from models.py: ,engine) 3、注意事项 1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则: 凡是在导入时带点的,点的左边都必须是一个包,右边可以是包也可以是文件,否则非法。可以带有一连串的点,如glance.db.models,但都必须遵循这个原则。 2.对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。 4、import:import什么,调用的时候就要写全 import glance.db.models glance.db.models.register_models(hello) # from models.py: hello 5、from...import 需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法 from glance.db import models models.register_models(hello) from glance.db.models import register_models register_models(hello) 6、__init__.py文件 不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件, 也就是说每次导入一个包都会先执行包下的__init__.py文件。 在包api下的__init__.py文件写入这样的代码: print(__init__) __all__ = [policy] 然后在主程序执行: from glance.api import * policy.get() # __init__ # from policy.py versions.create_resource(aa) # 报错:name ‘versions‘ is not defined 7、绝对导入和相对导入 我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式: 绝对导入:以glance作为起始 相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内) 一旦使用了相对导入,那么这个文件只能作为模块使用,不用直接执行了。 8、单独导入包 直接单独导入包,比如import glance,是不会导入包中的模块的, 直接导入包名称的时候,只会去执行包中的__init__文件,所以单独导入包名称的时候,需要 去包下的__init__文件中导入相应的模块。 例如:在与glance同级的test.py文件下运行代码: import glance glance.api.policy.get() # 报错:module ‘glance‘ has no attribute ‘api‘ 导入包就等于导入包下__init__的内容,而此时在glance的__init__内没有导入相应的内容,所以会报错 在glance包下的__init__写入: from glance.api import policy 再次执行 import glance glance.api.policy.get() 结果:from policy.py 三、开发规范(插图)
技术分享图片

 

python之模块、包的导入过程和开发规范

标签:命名   bsp   存在   两种   多个   span   bpa   判断   语法错误   

原文地址:https://www.cnblogs.com/Zzbj/p/9607462.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!