目录
- 计算机基础之编程
- 计算机组成
- 固态硬盘
- 操作系统
- 编程语言的分类
- 网络的瓶颈效应
- 执行python程序的两种方式
- 变量
- 常量
- python变量内存管理
- 变量的三种打印方式
- 数字类型
- 字符串 str
- 花式赋值
- 列表list
- 字典dict
- 布尔值
- 解压缩
- python与用户的交互
- 三种格式化输出方式
- 基本运算符
- 流程控制之if判断
- 流程控制之while循环
- 流程控制之for循环
- 数字类型内置方法
- 字符串内置方法
- 列表内置方法
- 元组内置方法
- 散列表
- 字典内置方法
- 集合内置方法
- 深浅拷贝
- 文件处理的基本使用
- 打开文件的三种模式
- 绝对路径和相对路径
- with管理文件上下文
- 文件的高级应用
- 文件的修改
- 函数的定义
- 函数的三种定义方式
- 函数的调用
- 函数的返回值
- 函数的参数
- 函数嵌套
- 名称空间与作用域
- 1.可变长参数
- 闭包函数
- 两种为函数传参的方式
- 装饰器
- 匿名函数
- 内置函数:
- 面向过程编程:
- 模块的四种形式:
- import和from....import模块
- 循环导入
- 模块的索引路径
- python文件的两种用途
- 模块
计算机基础之编程
什么是编程语言
人与计算机交流的介质
什么是编程
通过编程语言写一堆文件
为什么要编程
替代劳动力
计算机组成
CPU
控制器
控制硬件
运算器
算术运算和逻辑运算
存储器
主存
优点:快
缺点:容量小/断掉即消失/贵
外存
优点:容量大/永久存储/便宜
缺点:慢
IO设备
《追寻记忆的痕迹》
输入设备
输入信息,如键盘/鼠标
输出设备
输出信息,如显示屏/打印机
32位和64位
一次性读取的二进制位
多核cpu
同一时刻干多件事情
机械硬盘工作原理
机械手臂
读取数据
磁道
存储数据
扇区
划分磁道
平均寻道时间
5ms
平均延迟时间
4.15ms
平均寻找数据时间
9.15ms
固态硬盘
基于电容存储数据
操作系统
什么是文件
操作系统提供的虚拟概念,存储信息
操作系统有什么用
把对硬件的复杂操作简单化
计算机三大组成
- 硬件
- 操作系统
- 软件
操作系统的启动
- 启动临时操作系统
- 临时操作系统启动真正的操作系统
- 关闭临时操作系统
应用程序的启动
- 双击qq(给操作系统发送指令)
- 操作系统给CPU发送指令
- CPU给内存发指令
- 内存给外存发指令
- 外存找到qq的数据丢给内存
- 启动qq
编程语言的分类
机器语言
优点:执行效率高
缺点:开发效率低
汇编语言
优点:开发效率高
缺点:执行效率低
高级语言
编译型语言
优点:执行效率高
缺点:开发效率低
解释型语言
优点:开发效率高
缺点:执行效率低
网络的瓶颈效应
网络延迟的时间远远大于程序执行的时间
执行python程序的两种方式
交互式
写一行解释一行
命令行式
python 文件.py
变量
什么是变量
描述世间万物变化的状态
变量的组成
变量名(描述;接收变量值)= 变量值(一个具体的值)
变量名的命名规范
- 具有描述意义
- 只能由数字/字母/下划线组成,不能以数字开头
- 不能用python关键字
变量名的两种定义方式
- 下划线(推荐)
- 驼峰体
常量
常量只是约定俗成的不能变化,其实是可以变化的
python变量内存管理
引用计数(变量值)
变量值的引用次数加1,则引用计数加1
垃圾回收机制
当变量值的引用计数为0的时候,自动触发垃圾回收机制,释放变量值的内存占用
c --> free()
小整数池
针对[-5,256]之间的整数,python会在python启动的时候就会自动分配内存地址
虚拟地址() --》 硬盘(物理地址)
变量的三种打印方式
- 打印变量值
- 打印变量内存地址
- 打印变量的数据类型
数字类型
整型 int
使用方法:+-*/ % // **
import cmath
浮点型 float
使用方法:+-*/ % // **
import cmath
字符串 str
定义方式:单(双)引号内的一串字符,三单(双)引号内的字符可以换行
使用方法:+ *
# 强制类型转换 --》 动态语言
str(10) --> 字符串的10
int('10') --> 整型的10
float('10') --> 浮点型的10.0
# 不可以强制类型转换 --》 静态语言
花式赋值
链式赋值
a = b = c = 10
def f1(a=1):
pass
交叉赋值
x = 10
y = 20
x, y = y, x
列表list
[]内用逗号隔开多个元素(任意数据类型)
索引取值:索引从0开始,从-1开始
字典dict
dic = {'a':1}
{}内用逗号隔开多个键(一般为字符串(不可变类型))值(任意数据类型)对
按key取值
布尔值
所有数据类型都自带布尔值,0/None/空(空字符串/空列表/空字典)/False自带布尔值为False,其他均为True
解压缩
一次性取多个值,如果某一个值不要,就用_表示
lt = [1,2,3]
s1,s2,s3 = lt
print(s1,s2,s3)
python与用户的交互
input()
- 暂停程序
- 接收用户的输入
- 接收的所有数据都为字符串
三种格式化输出方式
f-string
f'{name}'
占位符
'%s'%(name)
format
'{}'.format(name)
基本运算符
算术运算符
+ - * / // % **
逻辑运算符
- and 两边都为True,则为True
- or 一边为True,则为True
- not 否定
比较运算符
< <= > >= == !=
身份运算符
- is 比较内存地址
- is not
成员运算符
- in 判断元素是否存在容器类元素内部(包括字符串)
- not in
赋值运算符
= += -= *= /= **= %= //=
x += 10 # x = x + 10
位运算符
111 000
&
011 100
011 000
& 都为1则为1,否则为0
运算符的优先级
要优先的加个括号就行了
流程控制之if判断
单分支结构
if 条件:
代码块
cls = 'human'
gender = 'female'
age = 18
if cls == 'human' and gender == 'female' and age > 16 and age < 22:
print('开始表白')
print('end...')
#
开始表白
end...
双分支结构
if 条件:
代码块 条件成立走这个
else:
代码块 条件不成立走这个
cls = 'human'
gender = 'female'
age = 38
if cls == 'human' and gender == 'female' and age > 16 and age < 22:
print('开始表白')
else:
print('阿姨好')
多分支结构
if 条件:
代码块 条件成立走这个
elif 可以有多个
else:
代码块 条件不成立走这个
cls = 'human'
gender = 'female'
age = 28
if cls == 'human' and gender == 'female' and age > 16 and age < 22:
print('开始表白')
elif cls == 'human' and gender == 'female' and age > 22 and age < 30:
print('考虑下')
else:
print('阿姨好')
if 嵌套
if
if
cls = 'human'
gender = 'female'
age = 18
is_success = False
if cls == 'human' and gender == 'female' and age > 16 and age < 22:
print('开始表白')
if is_success:
print('那我们一起走吧...')
else:
print('我逗你玩呢')
else:
print('阿姨好')
开始表白
我逗你玩呢
流程控制之while循环
while True:
user_db = 'nick'
pwd_db = '123'
inp_user = input('username: ')
inp_pwd = input('password: ')
if inp_user == user_db and pwd_db == inp_pwd:
print('login successful')
else:
print('username or password error')
while + break
中断循环
while True:
user_db = 'nick'
pwd_db = '123'
inp_user = input('username: ')
inp_pwd = input('password: ')
if inp_user == user_db and pwd_db == inp_pwd:
print('login successful')
break
else:
print('username or password error')
print('退出了while循环')
#
username: nick
password: 123
login successful
退出了while循环
while + continue
退出本次循环,不执行下面的代码,进行下一次循环
n = 1
while n < 10:
if n == 8:
# n += 1 # 如果注释这一行,则会进入死循环
continue
print(n)
n += 1
while + else
不被break中断就执行else缩进下的代码
n = 1
while n < 3:
print(n)
n += 1
else:
print('else会在while没有被break时才会执行else中的代码')
#
1
2
else会在while没有被break时才会执行else中的代码
tag控制while退出
while tag(count < 3):
pass
while嵌套
while
while
while True:
user_db = 'nick'
pwd_db = '123'
inp_user = input('username: ')
inp_pwd = input('password: ')
if inp_user == user_db and pwd_db == inp_pwd:
print('login successful')
while True:
cmd = input('请输入你需要的命令:')
if cmd == 'q':
break
print(f'{cmd} 功能执行')
break
else:
print('username or password error')
print('退出了while循环')
username: nick
password: 123
login successful
请输入你需要的命令:q
退出了while循环
流程控制之for循环
info = {'name': 'nick', 'age': 19}
for item in info:
# 取出info的keys
print(item)
#
name
age
for + break
中断循环
name_list = ['nick', 'jason', 'tank', 'sean']
for name in name_list:
if name == 'jason':
break
print(name)
# nick
for + continue
跳出本次循环,不执行下面代码,开始下一次循环
name_list = ['nick', 'jason', 'tank', 'sean']
for name in name_list:
if name == 'jason':
continue
print(name)
#
nick
tank
sean
for + else
没有被break掉,就执行else缩进下的代码
name_list = ['nick', 'jason', 'tank', 'sean']
for name in name_list:
print(name)
else:
print('for循环没有被break中断掉')
#
nick
jason
tank
sean
for循环没有break中断掉
for循环嵌套
for i in range(1,10):
for j in range(i):
print(....)
print()
数字类型内置方法
整型
浮点型
字符串内置方法
优先掌握
- 索引取值
- 索引切片
- for循环
- 成员运算
- len长度
- strip
- split
需要掌握
- rstrip/lstrip
- rsplit
- lower/upper
- startswith/endswith
- isdigit/isalpha
了解
- find/rfind/index/rindex/count
- center/ljust/rjust/zfill
- expandtabs
- capital/swapcase/title
- is系列
列表内置方法
优先掌握
- 索引取值/索引修改值
- 索引切片
- for循环
- 成员运算
- len长度
- append
- del 删除某一个元素
需要掌握
1. sort
- reverse
- pop
- remove
- index
- insert
- extend
- copy
- clear
有序or无序
有索引,有序;无索引,无序
可变or不可变
可变:值变id不变
不可变:值变id变化
元组内置方法
不可更改的列表,其他的和列表一模一样
散列表
- 乱序
- 不可重复的
- key不能为可变数据类型
字典内置方法
- 乱序 --》 python2中字典是乱序的,但是python3做了优化(本来是乱序的,但是在c这个层面做了不乱序的优化)
- key为什么是不可变的,假设key是可变的,
[key]可以取值,也可以修改值
get 获取值,没有默认None
setdefault 有就不修改,没有就增加
集合内置方法
- 去重 --》同样的值存的位置是一样的,拿到第一个就不会拿到第二个
- 乱序 --》插值是按照某种哈希算法随机插的
- 进行数学集合运算
- 交集 &
- 并集 |
- 差集 -
- 补集 ^
add 添加
remove 删除
discard 删除
深浅拷贝
拷贝:
(你变我也变,如你添加函数值,我也跟着添加)
当l2为l1的拷贝对象,l1变换,l2变化
l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
l2 = l1
l1.append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f'], 'g']
浅拷贝
浅拷贝:(你的可变数据类型变化,我才跟着变化)
当l2为l1的浅拷对象,l1内部不可变数据类型变化,l2不变;l1内部可变数据类型变化,l2变
import copy
l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
l2 = copy.copy(l1)
l1.append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f']]
l1[3].append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f', 'g'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f', 'g']]
深拷贝
深拷贝:(不管你怎么变,我就是不变)
当l2为l1的深拷贝对象,l1内部变化,l2不变
import copy
l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
l2 = copy.deepcopy(l1)
l1.append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f']]
l1[3].append('g')
print(l1)
['a', 'b', 'c', ['d', 'e', 'f', 'g'], 'g']
print(l2)
['a', 'b', 'c', ['d', 'e', 'f']]
文件处理的基本使用
什么是文件
操作系统提供的虚拟概念,用来存储信息的
操作文件的流程
- 打开文件 --》 open
- 修改文件 --》 write/read
- 保存文件 --》 flush
- 关闭文件 --》 close
打开文件的三种模式
- r --》只读
- w --》清空写入,创建新文件
- a --》追加写入,创建新文件 把光标移动到文件尾部
文件打开的两种方式
两种方式一般不单独使用
- t 文本模式
- b 二进制模式,一般用于音频/图片/视频
绝对路径和相对路径
绝对路径:
从盘符开始
相对路径:
相对于当前执行文件的文件夹下的所有文件
with管理文件上下文
跳出with缩进外,会自动关闭文件。可以一次性打开多个文件
文件的高级应用
新的打开文件的模式
- r+,覆盖光标后(文件头)的内容
- w+,w清空文件,读的功能失去了意义
- a+,a让光标移到文件尾,你读也读不出来
如果真要即写又读,打开两次文件
光标移动的应用
- read,以字符为单位,读取n个字符,默认读取全部
以下三个方法以字节为单位
- seek:移动光标的,0表示文件头;1表示当前位置;2表示文件末尾
- tell:告诉你当前位置
- truncate:截断处理,truncate(0),清空文件
文件的修改
文件没有插入,只有覆盖一说
with open('test.txt','r',encoding='utf8') as fr, open('test_swap.txt','w',encoding='utf8') as fw:
data = fr.read()
# 做修改
fw.write(data)
import os
os.remove('test.txt')
os.rename('test_swap.txt','test.txt')
函数的定义
定义函数阶段只检测语法,不执行代码
def 函数名():
代码块
函数的三种定义方式
空函数
当你只知道你需要实现某个功能,但不知道该如何用代码实现时,你可以暂时写个空函数,然后先实现其他的功能。
def func():
pass
有参函数
在函数定义阶段括号内有参数,称为有参函数。需要注意的是:定义时有参,意味着调用时也必须传入参数。
如果函数体代码逻辑需要依赖外部传入的值,必须得定义成有参函数。
def sum_self(x, y):
"""求和"""
res = x+y
print(res)
sum_self(1,2) # 3
无参函数
在函数阶段括号内没有参数,称为无参函数。需要注意的是:定义时无参,意味着调用时也无需传入参数。
如果函数体代码逻辑不需要依赖外部传入的值,必须得定义成无参函数。
def func():
print('hello nick')
func() # hello nick
函数的调用
函数名()
函数名(…)
即调用函数,会执行函数体代码,直到碰到return或者执行完函数体内所有代码结束。
函数运行完毕所有代码,如果函数体不写return,则会返回None。
def foo():
pass
print(foo()) #None
函数的返回值
- return会返回一个值,默认返回None
- return会终止函数
- return会返回多个值
# 为什么要有返回值
def max_self(salary_x, salary_y):
if salary_x > salary_y:
return salary_x
else:
return salary_y
max_salary = max_self(20000, 30000)
print(max_salary*12)
# 360000
# 函数返回多个值
def func():
name = 'nick'
age = 19
hobby_list = ['read', 'run']
return name, age, hobby_list
name, age, hobby_list = func()
print(f"name,age,hobby_list: {name,age,hobby_list}")
name,age,hobby_list: ('nick', 19, ['read', 'run'])
#name,age,hobby_list: ('nick', 19, ['read', 'run'])
函数的参数
形参
接收实参,具有描述意义
位置形参
从左到右依次接收位置实参
默认形参
- 具有默认值,如果传参,使用传参的值;否则使用默认值(形参会多次使用同一个值)
- 默认形参必须得放在位置形参后面
实参
传值给形参,具有具体的值
位置实参
从左到右依次传参给位置形参
关键字实参
- 按照形参名传参(参数较多的情况使用该方法)
- 关键字实参必须得在位置实参的后面
*形参
用元组接收多余的位置实参,
形参中的*会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给*后的参数。需要注意的是:*后的参数名约定俗成为args。
def sum_self(*args):
res = 0
for num in args:
res += num
return res
res = sum_self(1, 2, 3, 4)
print(res)
# 10
*实参
打散列表,然后以位置实参传给位置形参
实参中的*,*会将*后参数的值循环取出,打散成位置实参。以后但凡碰到实参中带*的,它就是位置实参,应该马上打散成位置实参去看。
def func(x, y, z, *args):
print(x, y, z, args)
func(1, *(1, 2), 3, 4)
# 1 1 2 (3, 4)
**
**形参
用字典接收多余的关键字实参
def func(**kwargw):
print(kwargw)
func(a=5)
# {'a': 5}
**实参
打散字典,然后以关键字实参传给位置形参
def func(x, y, z, **kwargs):
print(x, y, z, kwargs)
func(1, 3, 4, **{'a': 1, 'b': 2})
# 1 3 4 {'a': 1, 'b': 2}
*形参**形参
接收所有的多余的参数
def index(name, age, sex):
print(f"name: {name}, age: {age}, sex: {sex}")
def wrapper(*args, **kwargs):
print(f"args: {args}")
print(f"kwargs: {kwargs}")
index(*args, **kwargs)
#结果:
wrapper(name='nick', sex='male', age=19)
args: ()
kwargs: {'name': 'nick', 'sex': 'male', 'age': 19}
name: nick, age: 19, sex: male
关键字形参
现在有一个需求:函数的使用者必须按照关键字实参传。
def register(x, y, **kwargs):
if 'name' not in kwargs or 'age' not in kwargs:
print('用户名和年龄必须使用关键字的形式传值')
return
print(kwargs['name'])
print(kwargs['age'])
register(1, 2, name='nick', age=19)
#
nick
19
1.引用
def func()
x = 'hello nick'
y = x
f = func
print(f)
<function func at 0x10af72f28>
2.当作参数传给一个函数
def func():
print('123')
def func1(new):
new()
func1(func)
# 1 2 3
3.可以当作函数的返回值
def func():
print('123')
return func
msg = func()
print(msg)
msg()
#
123
<function func at 0x000001D469711EE8>
123
4.可以当作容器类型的元素
dic = {}
def abc():
print('oldboy')
dic['a'] = abc
print(dic)
res= dic['a']
res()
{'a': <function abc at 0x00000284A3D11EE8>}
oldboy
函数嵌套
def
def
外面不能引用函数内部定义的函数
def f1():
def f2():
print('from f2')
f2()
f2() # NameError: name 'f2' is not defined
def f1():
def f2():
print('from f2')
f2()
f1()
from f2
名称空间与作用域
内置名称空间
放内置方法
全局名称空间
除了内置和局部就是全局
局部名称空间
函数内部的定义的变量/函数
执行顺序
内置 --》 全局 --》 局部
搜索顺序
从当前位置开始 局部 --》 全局 --》 内置 --》 报错
全局作用域
全局作用域:全局有效,全局存活,包含内置名称空间和全局名称空间。
# 全局作用域
x = 1
def bar():
print(x)
bar()
# 1
局部作用域
局部作用域1的 x 和局部作用域2的 x 没有半毛钱关系
局部作用域:局部有小,临时存储,只包含局部名称空间。
# 局部作用域
def f1():
def f2():
def f3():
print(x)
x = 2
f3()
f2()
f1()
# 2
注意点
需要注意的是:作用域关系在函数定义阶段就固定死了,与函数的调用无关。
# 作用域注意点
x = 1
def f1(): # 定义阶段x=1
print(x)
def f2():
x = 2
f1()
f2()
# 1
global
局部的可以修改全局的
修改全局作用域中的变量。
x = 1
def f1():
x = 2
def f2():
# global x # 修改全局
x = 3
f2()
f1()
print(x)
# 1
nonlocal
局部的修改外层局部的
x = 1
def f1():
x = 2
def f2():
# nonlocal x
x = 3
f2()
print(x)
f1()
2
x = 1
def f1():
x = 2
def f2():
nonlocal x
x = 3
f2()
print(x)
f1()
3
legb原则
1.可变长参数
可变长参数:在调用函数时,参入的参数个数可以不固定。
调用函数时,传值的方式莫非两种,一种是位置实参,另一种是关键字实参,因此形参也必须的有两种解决方式,以此来分别接收溢出的位置实参(*)也关键字实参(**)
一.可变长形参之*
形参中的会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给后的参数。需要注意的是:*后的参数名约定俗成为args。
二 .可变长实参之*
实参中的, 会将后参数的值循环取出,达三成位置实参。以后但凡碰到实参中带的,他就是位置实参,应该马上打散成位置实参去看。
三. 可变长实参之**
形参中的** 会将溢出的关键字实参全部接收,然后存储字典的形式,然后把字典赋值给** 后的参数。需要注意的是:**后的参数名约定俗成为kwargs。
def func(**kwargs):
print(kwargs)
func(a=5) #{"a":5}
四 .可变长实参之**
实参中的,会将** 后参数的值循环取出,打散成关键字实参。以后但凡碰到实参中带**的,它就是关键字实参,应该马上打散成关键字实参去看。
五. 关键字形参
现在有一个需求,函数的使用者必须按照关键字实参传。
def register(x, y, **kwargs):
if 'name' not in kwargs or 'age' not in kwargs:
print('用户名和年龄必须使用关键字的形式传值')
return
print(kwargs['name'])
print(kwargs['age'])
register(1, 2, name='liangjing', age=20)
#liangjing
# 20
命名关键字形参:在函数定义阶段,*后面的参数都是命名关键字参数。
特点:在传值时,必须按照key=value的方式传值,并且key必须命名关键字参数的指定的参数名。
闭包函数
闭包函数:闭是封闭(函数内部函数),包是包含。** 函数内部函数对外部作用域而非全局作用域的引用。
def outter():
x = 1
def inner():
print(x)
return inner
f = outter()
def f2():
x = 2
f()
f2()
# 1
两种为函数传参的方式
为函数传参的方式一:使用参数的形式
def func(x):
print(x)
func(1)
func(1)
func(1)
1
1
1
为函数传参的方式二:包给函数
def outter(x):
x = 1
def inner():
print(x)
return inner
f = outter(1)
f() #1
f() #1
f() #1
闭包函数的应用
我们如果使用默认参数也只能解决一个网址,因此我们可以考虑使用闭包的方式。
import requests
def outter(url):
def get():
response = requests.get(url)
print(f"done: {url}")
return get
baidu=outter('https://www.baidu.com')
python = outter('https://www.python.org')
baidu()
baidu()
python()
python()
#
one: https://www.baidu.com
done: https://www.baidu.com
done: https://www.python.org
done: https://www.python.org
装饰器
- 本质就是一个函数,用来给另外一个函数添加功能
- 不修改被装饰函数的源代码
- 不修改被装饰函数的调用方式
要注意的是:
- 装饰器本身其实是可以任意可调用的对象
- 被装饰的对象也可以是任意可调用的对象
装饰器的实现必须遵循两大原则:
- 不修改被装饰对象的源代码
- 不修改被装饰对象的调用方式
怎么用装饰器:
import time
def index():
start = time.time()
print('welcome to index')
time.sleep(1)
end = time.time()
print(F"index run time is {start-end}")
index()
#
welcome to index
index run time is -1.0008180141448975
装饰器模板
def deco(func)
def wrapper(*args,**kwargs)
res = func(*args,**kwargs)
ruturn res
return wrapper
迭代器
迭代器:迭代的工具。迭代是更新换代。
可迭代对象:
一切的对象中,但凡有__iter__
方法的对象,都是可迭代对象。
name = 'nick'.__iter__
lis = [1, 2].__iter__
tup = (1, 2).__iter__
可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象。
迭代器对象
让其他的可迭代对象不依赖索引索引取值。
迭代器对象的概念:可迭代的对象执行__iter__
方法得到的返回值。并且可迭代对象会有一个__next__
方法。
dic = {'a': 1, 'b': 2, 'c': 3}
iter_dic = dic.__iter__()
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
a b c
# 依赖索引的数据类型迭代取值
lis = [1, 2, 3]
iter_lis = lis.__iter__()
print(iter_lis.__next__())
print(iter_lis.__next__())
print(iter_lis.__next__())
1 2 3
方法:
s = 'hello'
iter_s = s.__iter__()
while True:
try:
print(iter_s.__next__())
except StopIteration:
break
h e l l o
总结
迭代器对象:执行可迭代对象的__iter__
方法,拿到的返回值就是迭代器对象。
特点:
- 内置
__next__
方法,执行该方法会拿到迭代器对象中的一个值 - 内置有
__iter__
方法,执行该方法会拿到迭代器本身 - 文件本身就是迭代器对象。
缺点:
- 取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
- 无法使用len()方法获取长度
三元表达式:
条件成立时的返回值 if 条件 else 条件不成立时的返回值
x = 10
y = 20
print(f"x if x > y else y: {x if x > y else y}")
x if x > y else y: 20
列表推导式:
字典生成式
print({i: i**2 for i in range(10)})
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
zip()方法
keys = ['name', 'age', 'gender']
values = ['nick', 19, 'male']
res = zip(keys, values)
print(F"zip(keys,values): {zip(keys,values)}")
info_dict = {k: v for k, v in res}
print(f"info_dict: {info_dict}")
zip(keys,values): <zip object at 0x11074c088>
info_dict: {'name': 'nick', 'age': 19, 'sex': 'male'}
生成器
yield关键字
yield的英文单词意思是生产,在函数中但凡出现yield关键字,再调用函数,就不会继续执行函数体代码,而是会返回一个值。
def func():
print(1)
yield
print(2)
yield
g = func()
print(g)
#<generator object func at 0x10ddb6b48>
def sub_generator():
yield 1
yield 2
for i in range(3):
yield i
for i in sub_generator():
print(i)
1
2
0
1
2
递归:函数在该函数内部,直接或间接调用该函数本身。
函数的嵌套调用是:函数嵌套函数
直接调用:
直接调用指的是:直接在函数内部调用函数自身。
import sys
print(f"最大递归层数: {sys.getrecursionlimit()}")
# 1000
最大递归层数: 1000
import sys
# 修改递归层数
sys.setrecursionlimit(10000)
def foo(n):
print('from foo',n)
foo(n+1)
foo(0)
# 一直递加递归数,直到最大值暂停。
间接调用指的是:不在原函数体内调用函数自身,而是通过其他的方法间接调用函数自身。
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
bar()
匿名函数
有名函数:
def func():
print('from func')
func()
func()
func()
print(func)
#
from func
from func
from func
<function func at 0x10518b268>
匿名函数:匿名函数,他没有绑定名字,使用一次即被收回,加括号既可以运行。
lambda x, y: x+y
<function __main__.<lambda>(x, y)>
res = (lambda x, y: x+y)(1, 2)
print(res)
3
内置函数:
bytes() :解码字符
res = bytes('你好', encoding='utf8')
print(res)
# b'\xe4\xbd\xa0\xe5\xa5\xbd'
2.chr()/ord()
chr()参考ASCII码表将数字转成对应字符;ord()将字符转换成对应的数字。
print(chr(65))
A
print(ord('A'))
65
3.divmod()
分栏。
print(divmod(10, 3))
(3, 1)
4.enumerate()
带有索引的迭代。
l = ['a', 'b', 'c']
for i in enumerate(l):
print(i)
(0, 'a')
(1, 'b')
(2, 'c')
5.eval()
把字符串翻译成数据类型。
lis = '[1,2,3]'
lis_eval = eval(lis)
print(lis_eval)
[1, 2, 3]
6.hash()
是否可哈希。
print(hash(1))
1
面向过程编程:
什么是面向过程编程:核心是编程二字,过程就是解决问题的步骤。即先干什么,后干什么,再干什么,然后干什么....基于该思想编写程序就好比在设计一条流水线,面向对称编程其实是一种机械式的思维方式。
模块的四种形式:
什么是模块?
模块是一系列功能的集合体,而函数是某一个功能的集合体,因此模块可以看成是一堆函数的集合体。一个py文件内部就可以放一堆函数,因此一个py文件就可以看成一个模块。如果这个py文件的文件名为module.py
,模块名则是module
。
二‘模块的四种形式
在Python中,总共有以下四种形式的模块:
- 自定义模块:如果你自己写一个py文件,在文件内写入一堆函数,则它被称为自定义模块,即使用python编写的.py文件
- 第三方模块:已被编译为共享库或DLL的C或C++扩展
- 内置模块:使用C编写并链接到python解释器的内置模块
- 包:把一系列模块组织到一起的文件夹
如何用模块
一般我们使用import和from...import...导入模块。
import和from....import模块
import模块名
- 开辟内存空间,以time模块为准创造一个模块的命名空间,内存空间名为time
- 执行模块对应的文件,将time.py中的所有代码读入名称空间,然后运行
- 通过time.方法使用time模块中的方法。
import time
time.sleep(oldboy) #sleep(输入一个值)
模块的用途
一般我们使用import和from...import...导入模块。
from 模块名 import 方法名
如果你想使用多个方法:
from time import sleep,time #特定导入一些功能
如果你想导入非常多的方法
from time import * #导入所有的功能
import 和from ...import...的优缺点.
import
#优点:永久保存
#缺点:每次带入多输入几个符号,非常麻烦。
from...import...
#优点:少数如几个字符
#缺点:容易发生冲突
循环导入
# oldboy1.py
print("from oldboy1.py")
from oldboy2 import x
y = "oldboy"
1.创建m2的名称空间
2.执行m2.py,将执行产生的名字丢到m2.py
3.在当前执行文件中拿到m2.x
# oldboy2.py
print("form oldboy2")
from oldboy1 import y
x = "lodboy2"
1.创建m1的名称空间
2.执行m1.py,将执行产生的名字丢到m1.py
3.在当前执行文件中拿到m1.y
#模块永远只会开辟一次 ; from m1 import 必须得执行m1.py中所有代码
1. 在m1中运行m2模块
2. 在m2中运行m1模块
模块的索引路径
模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径(某个文件夹)。如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。
模块的搜索路径指的就是在导入模块时需要检索的文件夹。
导入模块时查找模块的顺序是:从当前 局部 -> 全局 -> 内置
- 先从内存中已经导入的模块中寻找(内存)
- 内置的模块(内置)
- 环境变量sys.path中找(自定义)
python文件的两种用途
执行文件:当前运行的文件
模块
一个文件既可以是执行文件,也可以是模块文件。
from testt import shopping
# __name__ == '__main__'不成立, __name__ != '__main__'
# 当testt为模块文件时,__name__等于文件名
# __name__是每个文件独有的,当该文件作为执行文件运行时,__name__等于'__main__';当该文件作为模块文件导入时,__name__等于文件名
模块
import time 模块:
导入时间的模块:提供了三种不同类型的时间(时间戳),三种不同类型的时间可以相互转换
# 时间戳形式
print(time.time()) #1569651011.655515
# 格式化时间
print(time.strftime('%Y-%m-%d %X'))
#2019-09-28 14:15:23
time.time()
time.sleep(1) # 相隔一秒打印
''''''
import os 模块:os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口,多用于文件处理
import os
对文件的操作:
判断是否为文件:
os.path.isfile
res = os.path.isfile(r'D:\上海python12期视频\python12期视频\day 16\00 上节课回顾.md')
print(res)
删除文件:os.remove
res = os.remove(r'D:\上海python12期视频\python12期视频\day 16\00 上节课回顾.md')
print(res)
重命名文件:os.rename
res = os.rename(r"D:\上海python12期视频\python12期视频\day 16\00 上节课回顾.md",r"D:\上海python12期视频\python12期视频\day 16\oldboy.txt
''''''
import sys 模块:
sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
import sys
最常用,当使用命令行式运行文件,接收多余的参数。
res = sys.argv
print(res)
import requests
拿到当前导入的模块:
print(sys.modules.keys())
requests = __import__("requests")
''''''
import random 模块:
random是一个内置模块,也可以说是标准库之一。
使用命令import random 就可以导入这个模块,然后使用里面的方法。如果事先不导入就使用会报错。
#掌握
# 0- 1
print(random.random())
#[1-3]
print(random.randint(1,3))
# 3
# 打乱
lt = [1,2,3]
random.shuffle(lt)
print(lt)
#随机选择一个
print(random.choice(lt))
#只随机一次 --》 梅森旋转算法
import time
# random.seed(time.time())
# random.seed(123)
print(random.random())
""""""
import jion 模块:
跨平台数据交互,json串,用于传输数据。序列化字典为json串,并保存文件
dic = {'a': 1, 'b': 1}
# # 序列化字典为json串,并保存文件
import json
with open('test.json', 'w', encoding='utf8') as fw:
json.dump(dic, fw) #创建一个文件,并保存字典中的值。
""""""
import pickle模块:
不跨平台,针对python所有数据类型,如集合,使用方式和json一模一样
新建一个文件夹:test.pkl
import pickle
def func(): # 针对地址而言,只存了一个函数名
print('func')
with open('test.pkl','wb') as fw:
pickle.dump(func,fw)
ef func():
print('lksjdfkljskldfjlksjdlk')
with open('test.pkl', 'rb') as fr:
data = pickle.load(fr)
print(type(data), data)
data() # func()
""""""
x