Python学习第二阶段,Day2,import导入模块方法和内部原理
怎样导入模块和导入包??
1.模块定义:代码越来越多的时候,所有代码放在一个py文件无法维护。而将代码拆分成多个py文件,同一个名字的变量互不影响,模块本质上是一个.py文件或者".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"结尾的文件,使用模块可以更有逻辑地组织Python代码段。简单来说,模块就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。
如果路人甲写的模块和路人乙写的模块中都有Util.py模块怎么办呢》?可以使用包package区分。 因为路人甲(p1.util)和路人乙(p2.util)同名模块的完整模块名不同。
2.定位模块
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
* 当前目录
* 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
* 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
2.导入模块:
import a,b,c,d... 从PATH路径搜索到abcd 执行的时候是a.xx
from p import a,b,c.... 从PATH路径搜索到p再到它儿子 abc... 执行的时候 a.xx b.xx
import p.a,p.b 执行的时候 p.a.xx p.b.xx
from p import * 从PATH路径搜索到p再到它所有儿子...
导入模块干的事可以理解为1、把模块的一坨代码用一个名字代替(后面可以引用)
2、运行当前脚本的时候会依次执行模块里的代码(相当于直接把代码复制粘贴过来)
导入模块干的事情就是:把模块的代码复制粘贴过来,然后给他们整体取个名字(这样可以避免重复的方法等),如果方法或类重名可以用模块去包装,模块重名可以用包或目录去包装
用的时候考虑 “这样会不会引起重名” 这样的问题就可以了
例如.../day2/core/ccc.py 中想导入.../day2/module/model1.py 模块
# model1.py 模块内容
attr = "model1 attr.........."
def md1():
print("this is model1.md1 function")
import os,sys DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(DIR) #....\day2绝对路径 from module import model1 # 这里不能直接用import,因为model1不直接在day2绝对路径下 print(model1.attr)
model1.md1()
A 模块与主程序在同一目录下,模块与主程序为“兄弟”关系: 直接import modulename
B 模块在主程序所在文件夹的子文件夹下,主程序是模块的“叔叔”:.../main.py .../module/model.py
直接 import module.model 调用:module.model.func() 或者 from module import model 调用:model.func()
C 模块在主程序上级目录中,或者在主程序上级目录的子目录。 模块跟主程序之间的关系是 “堂/表兄弟” 关系:
模块的init文件 import sys
sys.path.append("..")
---------------------------------------------------------------
主程序 import __init__ Python3 没用了
import suf.model
-----------------------c第二种方式------------------------------------------------------------------
BASE_DIR = os.path.dirname( os.path.dirname( os.path.abspath(__file__) ) ) : 再上一级Atm
sys.path.append( BASE_DIR ) 添加环境变量
----------------------------------------
看个例子:Python脚本是顺序执行的,程序中的路径都是该脚本所在的位置做为基准的,所以在不同的地方去执行,有的会报错:“找不到文件或路径”
目录结构:
| Group
| conf
info
| core
file_io
file_io.py
main_business
main_bus1.py
main_bus2.py
main.py
-----------main_bus1.py
import os
import sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) from file_io.file_io import read_file def main_bus1_1(str_object):
print("main_bus1_1", str_object)
print(read_file('../../conf/info')) def main_bus1_2(str_object):
print("main_bus1_2", str_object) main_bus1_1("sssssssssss") # 执行成功
---------main.py---
from main_business.main_bus1 import main_bus1_1 main_bus1_1("a") # 执行错误No such file or directory: '../../conf/info'
# 将上面print(read_file('../../conf/info'))改为print(read_file('../conf/info'))后执行成功
可以看出 from import 相当于将代码原封不动的定义
一般情况应该使用import , 但有几个例外
1)module文档告诉你要用from-import的
2)导入一个包组件。需要一个包里面的某个子模块,一般用from A.b import c比import A.b.c 更方便 且不会冒混淆的危险.这个纯属扯淡吧! 。。。。我个人还是觉得A.b.c 不会混淆
Python中模块、库、包区别 ::
模块,包含并且有组织的代码片段为模块。
包:
包是一个有层次的文件目录结构,它定义了由n个模块或n个子包组成的python应用程序执行环境。通俗一点:包是一个包含__init__.py 文件的目录,该目录下一定得有这个__init__.py文件和其它模块或子包。
常见问题:
引入某一特定路径下的模块
使用sys.path.append(yourmodulepath)
将一个路径加入到python系统路径下,避免每次通过代码指定路径
利用系统环境变量 export PYTHONPATH=$PYTHONPATH:yourmodulepath,
直接将这个路径链接到类似/Library/Python/2.7/site-packages目录下
好的建议:
经常使用if __name__ == '__main__',保证写包既可以import又可以独立运行,用于test。
__name__是模块的名字, 如果该模块是被import的,__name__为模块名,如果该模块是主程序入口,调用其他模块的模块,那么它的__name__就为'__main__'
多次import不会多次执行模块,只会执行一次。可以使用reload来强制运行模块,但不提倡。
常见的包结构如下:
package_a├── __init__.py├── module_a1.py└── module_a2.py
package_b├── __init__.py├── module_b1.py└── module_b2.py
main.py
如果main.py想要引用package_a中的模块module_a1,可以使用:
from package_a import module_a1
import package_a.module_a1
如果package_a中的module_a1需要引用package_b,那么默认情况下,python是找不到package_b。
我们可以在package_a中的__init__.py添加这句话sys.path.append('../'),,然后该包下得所有module都添加* import __init_即可。
库:
库的概念是具有相关功能模块的集合。这也是Python的一大特色之一,即具有强大的标准库、第三方库以及自定义模块。
为什么包要有__init__.py
在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中也有__init__.py 那么它就是这个包的子包了。当你将一个包作为模块导入(不论是import pack.mod还是from pack import mod)的时候,实际上导入了它的__init__.py 文件。 如果仅仅import pack 而 __init__里面为空的话,那么主程序里是不能使用mod的,想使用mod 还需要在__init__里面写:import mod 现在应该明白了吧
确实不能这样import pack 然后下面写pack.mod.func 因为调用只能是上面:命名.func
一个包是一个带有特殊文件 __init__.py 的目录。__init__.py 文件定义了包的属性和方法。其实它可以什么也不定义;可以只是一个空文件,但是必须存在。如果 __init__.py 不存在,这个目录就仅仅是一个目录,而不是一个包,它就不能被导入或者包含其它的模块和嵌套包。可以呀!为什么不行
__init__.py 中还有一个重要的变量,叫做__all__。
__init__.py 的作用>>>
1. Python中package的标识,不能删除
2. 定义__all__用来模糊导入,包下的模块 e.g. __all__ = ["Pack1Class","Pack1Class1"]
3. 编写Python代码(不建议在__init__中写python模块,可以在包中在创建另外的模块来写,尽量保证__init__.py简单)
import 和 From .. import ..的本质区别
使用import导入模块时,要做以下三件事:
1.为源代码文件中定义的对象创建一个名字空间,通过这个名字空间可以访问到模块中定义的函数及变量。(为spam对象创建类似 dir(model))
命名空间的概念:http://www.cnblogs.com/windlaughing/archive/2013/05/26/3100362.html
2.在新创建的名字空间里执行源代码文件.
3.创建一个名为源代码文件的对象,该对象引用模块的名字空间,这样就可以通过这个对象访问模块中的函数及变量
- import spam # 导入并运行模块 spam
- print (spam.a) # 访问模块 spam 的属性
- spam.foo()
- c = spam.bar()
模块导入时可以使用 as 关键字来改变模块的引用对象名字:
- import spam as sp 改变spam模块的引用对象名字
- print (sp.a)
- sp.foo()
- c = sp.bar()
Python学习第二阶段,Day2,import导入模块方法和内部原理的更多相关文章
- Python学习第二阶段Day2(json/pickle)、 shelve、xml、PyYAML、configparser、hashlib模块
1.json/pickle 略. 2.shelve模块 import shelve # shelve 以key value的形式序列化,value为对象 class Foo(object): de ...
- Python学习第二阶段Day2,模块time/datetime、random、os、sys、shutil
1.Time. Datetime(常用) UTC时间:为世界标准时间,时区为0的时间 北京时间,UTC+8东八区 import time print(time.time()) # timestamp ...
- Python学习第二阶段Day2,模块subprocess、 logging、re
1.logging 日志开关,设置全局只打印什么级别的日子,默认是warning以下的都不打印 改默认级别:依次升高 logging.debug("") logging.info( ...
- Python学习笔记:import sys模块(argv、path、platform、exit)
sys模块是Python标准库中自带的一个模块. sys模块包括了一组非常实用的服务,内含很多函数方法和变量,用来处理Python运行时配置以及资源,从而可以与当前程序之外的系统环境交互,如:Pyth ...
- python学习第五讲,python基础语法之函数语法,与Import导入模块.
目录 python学习第五讲,python基础语法之函数语法,与Import导入模块. 一丶函数简介 1.函数语法定义 2.函数的调用 3.函数的文档注释 4.函数的参数 5.函数的形参跟实参 6.函 ...
- python笔记-1(import导入、time/datetime/random/os/sys模块)
python笔记-6(import导入.time/datetime/random/os/sys模块) 一.了解模块导入的基本知识 此部分此处不展开细说import导入,仅写几个点目前的认知即可.其 ...
- Python学习day17-常用的一些模块
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- 模块(modue)和包(package)的概念-import导入模块
模块 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较 ...
- Python学习—基础篇之常用模块
常用模块 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...
随机推荐
- presentModalViewController和dismissModalViewControllerAnimated的使用总结
在实际开发中,如果要弹出视图: 我们常用到presentModalViewController方法和dismissModalViewControllerAnimated方法. presentModal ...
- oracle数据库的导入 导出实例
oracle数据库的导入 导出实例 分类: DataBase2011-09-07 23:25 377人阅读 评论(0) 收藏 举报 数据库oraclefileusercmdservice 我要从另外一 ...
- 简述Python中的break和continue的区别
众所周知在Python中,break是结束整个循环体,而continue则是结束本次循环再继续循环. 但是作为一个新手的你,还是不明白它们的区别,这里用一个生动的例子说明它们的区别,如下: 1.con ...
- MyBatis高级查询 一对多映射
数据库表在一对一映射中. 在数据库sys_user_role中新增一条记录 一个用户可以有多个角色.查询出所有用户和所对应的角色. 1.collection集合的嵌套结果映射 <!-- SysU ...
- bzoj 1034: [ZJOI2008]泡泡堂BNB【贪心】
是贪心 先把两个数组排序,然后贪心的选让a数组占优的(如果没有就算输),这是最大值,最小值是2n-贪心选b数组占优 #include<iostream> #include<cstdi ...
- 洛谷 P2365 任务安排【dp】
其实是可以斜率优化的但是没啥必要 设st为花费时间的前缀和,sf为Fi的前缀和,f[i]为分组到i的最小花费 然后枚举j转移,考虑每次转移都是把j到i分为一组这样意味着j及之后的都要增加s的时间,同时 ...
- OpenGL 2D模式
// // left top 这里设置的默认是左上角 // void push_view2d(int left, int top, int width, int height) { //glPushA ...
- python 操作数据库时遇到的错误
pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; ch 之前的写法是从文件里 ...
- 贪心 Codeforces Round #191 (Div. 2) A. Flipping Game
题目传送门 /* 贪心:暴力贪心水水 */ #include <cstdio> #include <algorithm> #include <cstring> us ...
- [ SPOJ Qtree1 ] Query on a tree
\(\\\) Description 给定 \(n\) 个点的树,边按输入顺序编号为\(1,2,...n-1\) . 现要求按顺序执行以下操作(共 \(m\) 次): \(CHANGE\ i\ t_i ...