1、模块

 

模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test)

 

包:用来从逻辑上组织模块的,本质就是一个目录(必须带有一个__init__.py文件)

 

导入:

1、import的使用:

 1 #模块可以包含可执行的语句和函数的定义,这些语句的目的是初始化模块,它们只在模块名第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块很import多次,为了防止你重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句),如下 
 2 
 3 #test.py
 4 import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
 5 import spam
 6 import spam
 7 import spam
 8 
 9 '''
10 执行结果:
11 from the spam.py
12 '''

ps:我们可以从sys.module中找到当前已经加载的模块,sys.module是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入。

2、为模块名起别名:为已经导入的模块起别名的方式对编写可扩展的代码很有用

import spam as sm
print(sm.money)

有两中sql模块mysql和oracle,根据用户的输入,选择不同的sql功能

 1 #mysql.py
 2 def sqlparse():
 3     print('from mysql sqlparse')
 4 #oracle.py
 5 def sqlparse():
 6     print('from oracle sqlparse')
 7 
 8 #test.py
 9 db_type=input('>>: ')
10 if db_type == 'mysql':
11     import mysql as db
12 elif db_type == 'oracle':
13     import oracle as db
14 
15 db.sqlparse()

假设有两个模块xmlreader.py和csvreader.py,它们都定义了函数read_data(filename):用来从文件中读取一些数据,但采用不同的输入格式。可以编写代码来选择性地挑选读取模块

1 if file_format == 'xml':
2     import xmlreader as reader
3 elif file_format == 'csv':
4     import csvreader as reader
5 data=reader.read_date(filename)

3、在一行导入多个模块

import sys,os,re

4、使用模块之from ... import...

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

 

5、from...import 与import的对比

import本质:把导入的模块代码全部赋值给一个新的变量,调用时 变量名.方法

from import 本质:把原模块代码复制到当前目录,调用时 方法()

 

1 #唯一的区别就是:使用from...import...则是将spam中的名字直接导入到当前的名称空间中,所以在当前名称空间中,直接使用名字就可以了、无需加前缀:spam.
2 
3 #from...import...的方式有好处也有坏处
4     好处:使用起来方便了
5     坏处:容易与当前执行文件中的名字冲突

验证一:当前位置直接使用read1和read2就好了,执行时,仍然以spam.py文件全局名称空间

 1 #测试一:导入的函数read1,执行时仍然回到spam.py中寻找全局变量money
 2 #test.py
 3 from spam import read1
 4 money=1000
 5 read1()
 6 '''
 7 执行结果:
 8 from the spam.py
 9 spam->read1->money 1000
10 '''
11 
12 #测试二:导入的函数read2,执行时需要调用read1(),仍然回到spam.py中找read1()
13 #test.py
14 from spam import read2
15 def read1():
16     print('==========')
17 read2()
18 
19 '''
20 执行结果:
21 from the spam.py
22 spam->read2 calling read
23 spam->read1->money 1000
24 '''

验证二:如果当前有重名read1或者read2,那么会有覆盖效果。

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

验证三:导入的方法在执行时,始终是以源文件为准的

1 from spam import money,read1
2 money=100 #将当前位置的名字money绑定到了100
3 print(money) #打印当前的名字
4 read1() #读取spam.py中的名字money,仍然为1000
5 
6 '''
7 from the spam.py
8 spam->read1->money 1000
9 '''

6、包

包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

需要强调的是:
  1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错   2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块

注意事项:
1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,

点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,

点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
2、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件 3、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间


7、模块搜索路径

模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块

 

导入模块的本质就是把python文件解释一遍,然后赋值给模块名,(import test 相当于 test='test.py all code')

 

导入模块的过程:找文件,找文件所在的路径,找sys.path

所以 我们需要把当前脚本的绝对路径的父父路径,加到sys.path里去,这样就可以找到其他模块。

所以我们引入一个新模块os,os.path.abspath(__file__)可以获得当前模块的绝对路径

 

然后再通过os.path.dirname可以获取到除文件名以外的路径,我们使用2次,就可以得到父父级目录,现在我们获得了父父级目录,我们把目录加到 sys.path去,但是我们注意我们需要把这个目录放到列表sys.path的第一个位置去~!

导入包的本质就是执行该包下面的__init__.py文件

 

8、os路径处理

 1 os路径处理
 2 #方式一:推荐使用
 3 import os
 4 #具体应用
 5 import os,sys
 6 possible_topdir = os.path.normpath(os.path.join(
 7     os.path.abspath(__file__),
 8     os.pardir, #上一级
 9     os.pardir,
10     os.pardir
11 ))
12 sys.path.insert(0,possible_topdir)
13 
14 
15 #方式二:不推荐使用
16 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

 

 posted on 2018-08-06 10:17  二十二a  阅读(225)  评论(0)    收藏  举报