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

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

以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(模块名)      ***
    可以获取这个模块中的所有名字

二、导入包
1、
1.无论是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

三、开发规范(插图)

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

时间: 2024-11-05 05:17:34

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

Python常用模块——包&跨模块代码调用

Python常用模块--包&跨模块代码调用 一.包(Package) 当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹. my_proj/ ├── apeland_web #代码目录 │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── my_proj #配置

第七篇、Python之模块/包

一.模块(module)的概念 1.模块定义和分类 在python中,一个.py文件就称之为一个模块(Module). 模块的使用方式都是一样的,细分模块可以分为三类: 1 自定义模块:使用python编写的单个.py文件,或者把一系列的.py文件组织在一起的文件夹.(注:文件夹下有个__init__.py文件,该文件夹称之为包) 2 第三方模块:已被编译为共享库或DLL的C或C++扩展 3 python标准库:使用C编写并链接到python解释器的内置模块 2.模块优点 1) 从文件级别组织程

python的模块安装、导入

一.模块的安装 1.有网络的情况下: 直接在cmd里面,输入pip install  xxx ,就是安装某个模块 2.无网络的情况下,下下来的安装包: .whl的后缀,pip install xxx.whl .tar.gz的后缀,解压后,进入模块文件夹,执行: python setup.py install 3.卸载:pip uninstall xxx 二.导入模块的顺序 1.第一步去当前目录下找这个python文件 2.第二步去python的环境变量里面找这个python文件 3.导入模块的实

Python 1-2模块的循环导入问题

run.py文件: import m1 # 第一次导入 # 验证解决方案一: ''' 正在导入m1 正在导入m2 ''' # print(m1.x) # print(m1.y) # 验证解决方案二: import m1 # 第一次导入 ''' 正在导入m1 ''' # print(m1.x) # print(m1.f1) m1.f1() ''' 正在导入m2 m1.f1---->y:m2 m2.f2--->x:m1 ''' m1.py文件: # 错误示范 ''' print('正在导入m1')

浅谈 Python 的模块导入

浅谈 Python 的模块导入 本文不讨论 Python 的导入机制(底层实现细节),仅讨论模块与包,以及导入语句相关的概念.通常,导入模块都是使用如下语句: import ... import ... as ... from ... import ... from ... import ... as ... 一般情况下,使用以上语句导入模块已经够用的.但是在一些特殊场景中,可能还需要其他的导入方式.例如 Python 还提供了 __import__ 内建函数和 importlib 模块来实现动

14.模块的使用,包,及程序开发规范

1.模块的基础认识 为啥使用模块: 从文件级别组织程序,更加方便管理,且实现了功能的重复利用 提高开发效率 查看当前已加载模块: 打印sys.module,里面包含模块名与对象的映射 为模块起别名: import temp as tp print(tp.name) 这个的用处一:可以根据用户的输入来选择使用不同模块中的同一功能 inp = input('json or pickle>>>') if inp == 'json': import json as m elif inp == '

异常处理、模块包、时间模块、subprocess(调用shell命令)

异常处理 捕捉异常可以使用try/except语句.try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理.如果你不想在异常发生时结束你的程序,只需在try里捕获它. 更多的异常关键字:http://www.runoob.com/python/python-exceptions.html Exception:常规错误的基类IOError:输入/输出操作失败例子1:写入信息到tt.txt文件中,如果报错,就打印错误 try: with open('tt.tx

python软件开发规范&分文件对于后期代码的高效管理

根据本人的学习,按照理解整理和补充了python模块的相关知识,希望对于一些需要了解的python爱好者有帮助! 一.软件开发规范--分文件 当代码存在一个py文件中时: 1.不便于管理 (修改,增加) 2.可读性差 3.加载速度慢 Django--雏形(约定俗称) 1.启动文件 启动接口 2.公共文件 大家需要的功能 3.配置文件(静态文件) 变量 4.主逻辑 核心 5.用户相关数据 账号和密码等文件 6.日志 记录主要信息,记录开发人员的行为 高内聚 二.sys sys python解释器做

【Python 生成器 匿名函数 递归 模块及包的导入 正则re】

一.生成器 1.定义 生成器(generator)是一个特殊的迭代器,它的实现更简单优雅,yield是生成器实现__next__()方法的关键.它作为生成器执行的暂停恢复点,可以对yield表达式进行赋值,也可以将yield表达式的值返回. 也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态. yield的功能: 1.相当于为函数封装好__iter__和__next__ 2.return只能返回一次值,函数就终止了,而yield能返