python模块搜索原则_python 从小白开始 - 模块,包以及路径搜索

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 importspam6 importspam7 importspam8

9 '''

10 执行结果:11 from the spam.py12 '''

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

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

importspam as smprint(sm.money)

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

1 #mysql.py

2 defsqlparse():3 print('from mysql sqlparse')4 #oracle.py

5 defsqlparse():6 print('from oracle sqlparse')7

8 #test.py

9 db_type=input('>>:')10 if db_type == 'mysql':11 importmysql as db12 elif db_type == 'oracle':13 importoracle as db14

15 db.sqlparse()

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

1 if file_format == 'xml':2 importxmlreader as reader3 elif file_format == 'csv':4 importcsvreader as reader5 data=reader.read_date(filename)

3、在一行导入多个模块

import sys,os,re

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

1 from spam importread1,read22 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 importread14 money=1000

5 read1()6 '''

7 执行结果:8 from the spam.py9 spam->read1->money 100010 '''

11

12 #测试二:导入的函数read2,执行时需要调用read1(),仍然回到spam.py中找read1()

13 #test.py

14 from spam importread215 defread1():16 print('==========')17 read2()18

19 '''

20 执行结果:21 from the spam.py22 spam->read2 calling read23 spam->read1->money 100024 '''

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

1 #测试三:导入的函数read1,被当前位置定义的read1覆盖掉了

2 #test.py

3 from spam importread14 defread1():5 print('==========')6 read1()7 '''

8 执行结果:9 from the spam.py10 ==========11 '''

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

1 from spam importmoney,read12 money=100 #将当前位置的名字money绑定到了100

3 print(money) #打印当前的名字

4 read1() #读取spam.py中的名字money,仍然为1000

5

6 '''

7 from the spam.py8 spam->read1->money 10009 '''

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

e48b70991e4aa5bb8e3a3419f1cbf135.png

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

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

84a8cd6f6af98ecfd9dc729482dd0bc3.png

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

e7222b3f62d21a8a039762465361c235.png

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

351dead7ff66b003eba6f6266120e110.png

d6a3fb24a691ae9691dd5e8dfe91d151.png

8、os路径处理

1 os路径处理2 #方式一:推荐使用

3 importos4 #具体应用

5 importos,sys6 possible_topdir =os.path.normpath(os.path.join(7 os.path.abspath(__file__),8 os.pardir, #上一级

9 os.pardir,10 os.pardir11 ))12 sys.path.insert(0,possible_topdir)13

14

15 #方式二:不推荐使用

16 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值