python之模块

模块的导入

在Python中,一个py文件就是一个模块,文件名为xxx.py模块名则是xxx,导入模块之后可以使用模块中已经写好的函数和属性

将程序模块化会使得程序的组织结构清晰,维护起来更加方便(也叫解耦合)。比起直接开发一个完整的程序,单独开发一个小的模块也会更加简单,并且程序中的模块可以被重复使用。所以总结下来,使用模块既保证了代码的重用性,又增强了程序的结构性和可维护性。另外除了自定义模块外,我们还可以导入使用内置或第三方模块(别人写好的功能)提供的现成功能,这种“拿来主义”极大地提高了程序员的开发效率

# 现在有一个模块a,里面有函数jump(),hit()和变量name='二狗',age=18
# 文件b,里面有函数jump(),run()

# 1.模块的导入(在文件b中导入模块a)
import a  # 这样导入会直接加载a文件中的所有内容
from a import jump  # 制指定导入的内容,这里只导入文件中的jump函数
# import a 和 from a import * 是一样的效果(星号代表全部) 

# 2.导入多个模块
# 书写多个import语句
import module1
import module2
    ...
import moduleN
# 还可以在一行导入,用逗号分隔开不同的模块
import module1,module2,...,moduleN

# 3.起别名
from a import get as c
# 再次使用的时候可以使用别名
c.jump()

'''
模块导入后的加载:
1、执行源文件代码(被导入的模块)
2、产生一个新的名称空间用于存放源文件执行过程中产生的名字
3、在当前执行文件所在的名称空间中得到一个名字a,该名字指向新创建的模块名称空间,若要引用模块名称空间中的名字,需要加上该前缀,如a.func1()
'''
# 模块的使用
a.jump()  # 使用a模块中的jump函数
a.name  # 使用a模块中的name变量
age  # 使用a模块中的age变量
# a、b中的文件如果存在重名的函数或者变量,只能加前缀(a.jump())使用模块中的函数,否则直接使用b中的jump函数,但是对于a中存在而b中不存在的函数和变量,可以不加前缀直接使用
# 原理:当你使用一个变量或者函数时,会首先在本文件的名称空间中寻找,如果找到,直接在引用,如果找不到,会去导入的模块中寻找,找到直接使用,找不到就报错

循环导入问题

# m1文件内容
print('正在导入m1')
from m2 import y
x='m1'

# m2文件内容
print('正在导入m2')
from m1 import x
y='m2'

# run.py文件内容
import m1

# 执行m1时会直接报错
'''
正在导入m1
正在导入m2
Traceback (most recent call last):
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/aa.py", line 1, in <module>
    import m1
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in <module>
    from m2 import y
  File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m2.py", line 2, in <module>
    from m1 import x
ImportError: cannot import name 'x'
'''

解析:执行run.py文件,导入m1文件,加载到from m2 import y去m2文件,执行m2文件,加载到from m1 import x去m1文件找变量x,由于刚才m1文已经被导入过了(只是在第一次导入的时候进行加载,之后直接去m1文件的名称空间中寻找),但是里面的x变量并没有加载出来,所以会报错(找不到变量x)
解决方案

'''
1.将导入的语句放在文件最后
	文件在被加载的时候是从文件开始一直加载到文件结束
	将导入语句(import)放在文件的最后,待文件中的内容全部加载完毕再进行导入
2.导入语句放到函数中,只有在调用函数时才会执行其内部代码
文件:m1.py
print('正在导入m1')
def func1():
    from m2 import y
    print(x,y)
x = 'm1'

文件:m2.py
print('正在导入m2')
def func2():
    from m1 import x
    print(x,y)
y = 'm2'

# 文件:run.py内容如下,执行该文件,可以正常使用
import m1
m1.f1()
'''
# 应该尽量避免导入的问题,上面的方法尽量不要使用

模块搜索优先级

如果模块已经被导入,使用的时候优先查找杯倒入的模块,找不到再去检索内置模块,还找不到,检索sys.path中定义的路径,直到找到对应的路径为止,如果都找不到,会直接报错

sys.path也被称为模块的搜索路径,它是一个列表

import sys
print(sys.path)

['',
'/Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip',
'/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5',
...,
'/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages']

sys.path中的第一个路径通常为空,代表执行文件所在的路径,所以在被导入模块与执行文件在同一目录下时肯定是可以正常导入的
对于被导入的模块与执行文件在不同路径下的情况,为了确保模块对应的源文件仍可以被找到,需要将源文件m.py所在的路径添加到sys.path中,假设m.py所在的路径为/pythoner/projects/

import sys
sys.path.append(r’/pythoner/projects/’) ,也可以使用sys.path.insert(……)
import m

无论m.py文件在什么位置,都可以对其进行导入并使用模块中的函数与变量

py文件的两种用途

py文件有两种用途,一种是直接当做主程序/脚本执行(就是我们运行一段程序),一种是被当做模块被导入

每个py文件都内置了__name__变量,该变量在py文件被当做脚本执行时被赋值为__main__,在py文件被当做模块导入时赋值为模块名

# foo.py
...
if __name__ == '__main__':
    # foo.py被当做脚本执行时运行的代码
else:
    # foo.py被当做模块导入时运行的代码

编写模块的注意事项

  • 首先,应该在开头部分写上模块用途的文档描述
  • 模块所需的属性和函数
  • 添加下面的代码,将一些被当做脚本执行的时候的内容放在里面
if __name__ == '__main__':  # 主程序
    test()  # 在被当做脚本执行时,执行此处的代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值