第七章:包、模块、函数与变量作用域
1.循环相关知识
1)while循环与使用场景
2)for循环:主要用来遍历/循环 序列或集合、字典
例子1:
a=['apple','orange','banana']
for x in a:
print(x)
例子2:
a=[['apple','orange','banana'],[1,2,3]]
for x in a:
print(x)
执行代码得到:
['apple', 'orange', 'banana']
[1, 2, 3]
例子3:
a=[['apple','orange','banana'],[1,2,3]]
for x in a:
for y in x:
print(y)
执行代码得到:
apple
orange
banana
1
2
3
想让结果在一行打出来:
a=[['apple','orange','banana'],[1,2,3]]
for x in a:
for y in x:
print(y,end='')
结果:
appleorangebanana123
for else语句 :当遍历完所有元素之后,再执行else语句(用的比较少)
break:强行终止当前的循环
continue:跳过当前的,继续下一个循环
a=[1,2,3]
for x in a:
if x == 2:
break
print(x)
else:
print('EOF')
代码执行完后不会输出EOF
因为for的遍历还没执行完,就被强制退出了,这样是不会执行else语句的。
如果把break换成continue,则会执行else语句,因为是遍历完了的。
3)思考题
代码:
a=[['apple','orange','banana','grape'],(1,2,3)]
for x in a:
for y in x:
if y == 'orange':
break
print(y)
else:
print('fruit is gone')
运行结果:
这里的break跳出的是内部的循环,而外部的循环仍然会执行,这里的else语句对应的是外层,所以也依然会执行。
2. for与 range函数
1)
for x in range(0,5):
print(x)
输出:
0
1
2
3
4
注:0代表起始位置,5代表长度
2)
for x in range(0,5,2):
print(x)
输出:
0
2
4
注:2代表差值
3)
for x in range(0,5,2):
print(x,end='|')
以行的形式输出一个递增数列
4)
for x in range(5,0,-2):
print(x,end='|')
以行的形式输出一个递减数列
5)
for x in range(5,8):
print(x)
输出:
5
6
7
不管起始位置是几,计算长度都是从0开始数的,
也就是说这里总长度是8,不管起始位置是几,最多只能输出 0-7 这8个数
3. python包与模块的名字
python项目的组织结构:
包————可看做文件夹
模块————可看做文件
类
函数、变量
函数、变量 属于类本身,是类一个特性,并不是一个组织结构。
让一个普通的文件夹变成python的一个包,必须在文件夹里包含一个名字为:_init_.py
的文件,这个文件其实就可看做一个模块,这个模块的名字比较特殊,它所在的包的名字就是它的名字。
4. import导入模块
引用另一文件的变量,要先导入才能用:import 模块名.文件名.
假设t是一个包名,c7是一个模块名,a是模块c7中的一个变量
import t.c7
print(t.c7.a)
as关键字:把很长的命名空间简化成一个标识符
import t.c7 as m
print(m.a)
5. from import 导入变量
用法:from module import a,def
示例:假设t是一个包名,c7是一个模块名,a是模块c7中的一个变量
from t.c7 import a
print(a)
——————之前import导入的是模块,而这里的from是直接把变量a导入了,就不需要在变量前面再加上命名空间了
from t import c7
print(c7.a)
———————from也是可以访问模块的,但这样就和单独使用import没什么区别了
6. _init_.py
的用法
1) 扩展:
VScode小技巧:如何在资源管理器中隐藏(不是删除)自动生成的 _pycache_
目录 和 _init_.py
文件呢?(这些文件对于开发者来说没什么意义)(要隐藏其他文件也同理)
文件——首选项——设置——搜索files.exclu——点击添加模式,输入**/_pycache_
2)
换行可以在末尾加上反斜杠:\ ,但不推荐该方法。可以加上括号来换行,如下:
from c9 import (a,b,
c)
3)
导入 包 或者 包下某个模块的变量 的时候, _init_.py
文件都会优先被自动运行
_init_.py
的实际运用:
作用一:
在一个包中,
假设在 _init_.py
文件输入:_all_ = ['c1']
c1模块定义了变量 a
c2模块中定义变量了 b
那么新建一个模块c3,输入import *————————————只会导入c1模块中的变量a,而不会导入c2模块的变量。
——————因为init文件只定义了c1,通过 *
导入包下的模块时,只会导入c1。
作用二:
可以批量导入:在该文件下写入多个模块都要 重复导入的包或模块,那么在其他模块中,就不需要再重复写了,会直接导入包。
7. 包与模块的几个常见错误
包和模块是不会被重复导入的。
避免循环导入(例如:从模块一导入模块二,从模块二导入模块三,从模块三导入模块四,从模块四又导入模块一)
8.模块内置变量
定义:python系统已经定义好了的,一般带双下划线
_name_
_package_
_doc_
: 对当前模块的注释
_file_
9.作为入口文件的模块和普通模块中 内置变量的区别
如果一个.py文件被当做是应用程序的入口文件(main.py)
1)_name_
的值不再是模块名,而是被强制更改为_main_
2)该文件顶级不会再有包,_package_
变量取值为Nonetype(空类型)
_file_
:取值与执行python命令所在目录有关系
返回上一级命令:cd
10. _name_
的经典应用
1)dir ( ) 函数
例子:
import sys
infos = dir(sys)
print(infos)
——————————————输出了模块sys中的变量
想去查看某一模块/类下相关的变量时,可以使用 dir( ) 函数。
2)
若C1模块有代码如下:
if _name_ == '_main_':
print('This is app')
print ('This is a module')
C2模块:
import C1
执行C1文件,会输出:
This is app
This is a module
执行C2文件,会输出:
This is a module
————————上面就是 _name_
的经典应用,实际上C1就是一个入口文件
扩展:
如果一个模块让它成为普通的模块,必须要有一个包,除非他不是一个普通的模块,而是一个可以直接执行的文件。
11.相对导入和绝对导入
包和模块导入时,有 相对路径 和 绝对路径。
通常情况,一个python项目通常都是通过入口文件来对python的命令来运行的,会在 入口文件main.py 的内部引入各种各样的包,以及包下的模块。从而来实现一些业务的功能。
(1)顶级包与入口文件的位置有关
例如:
如下级别的目录(Demo包含了package1、2,main.py文件在demo文件夹中),顶级包不是demo,而是package1,2所在级别,因为mian.py的位置是在该级别。
Demo
package1
package2
main.py
(2)绝对路径必须从顶级包开始
(3)相对路径中:.
表示当前目录,..
表示·上一级目录, ...
表示上上级目录。相对路径也不能超过顶级包
(4)在入口文件里面不能用相对路径导入
若执意要用相对路径,只能把入口文件当做一个模块方式来运行,(即 python -m…)
例子:
如下路径中,m2文件中有如下代码
在main.py文件中用绝对路径可成功导入模块m2,打印出了m2的package变量(m2的顶级包是package2)
若要用相对路径:
此时main.py文件中代码改为:from .package2.package4.m2 import m
如果我们想把main.py文件当作一个模块,用python -m的命令来运行的话,一定要回到python code 的上一级去。
但是我们现在是位于python code这一目录下,所以首先: D:\python\python code> cd..
,回到了上一层。
然后:D:\python> python -m python code.main
然后成功打印出了m2 的package变量:python code .package2.package4
即此时m2的package路径,顶级包是python code,因为我们现在是从包的外部运行的。