标签:效率 x11 rmdir 乱序 ext 编译 url 组合 soup
人与计算机交流的介质
通过编程语言写一堆文件
替代劳动力
控制硬件
算术运算和逻辑运算
优点:快
缺点:容量小/断掉即消失/贵
优点:容量大/永久存储/便宜
缺点:慢
《追寻记忆的痕迹》
输入信息,如键盘/鼠标
输出信息,如显示屏/打印机
一次性读取的二进制位
同一时刻干多件事情
读取数据
存储数据
划分磁道
5ms
4.15ms
9.15ms
基于电容存储数据
操作系统提供的虚拟概念,存储信息
把对硬件的复杂操作简单化
优点:执行效率高
缺点:开发效率低
优点:开发效率高
缺点:执行效率低
编译型: 先一次性编译然后再执行,类似于 "有道翻译"。
优点:执行效率高
缺点:开发效率相比于解释型语言要低。不可跨平台。
解释型: 遍解释(翻译)一遍执行, 类似于同声传译。
优点:开发效率高可跨平台,一份代码可以多个平台使用。
缺点:执行效率低
python , java , php
c , c++
网络延迟的时间远远大于程序执行的时间
- 将人类编写好的代码转成机器能看得懂的字符。-
解释器的作用: 帮你执行python代码。
- 编辑器的作用: 可以更好的编写python代码,编辑器内部有很多强大的功能。 能够快速编写代码。
结论: 以什么编码,就以什么解码。
utf-8:
- 存中文是3个字节。
- 存英文是1个字节
gbk:
- 存中文是2个字节。
- 存英文是2个字节
写一行解释一行
python 文件.py
描述世间万物变化的状态(指可变化的量)
变量名:可以与变量值绑定关系,通过变量名可以访问变量值
赋值符号(=): 是用来将变量名与变量值绑定关系。
变量值: 变量值 指的是 “数据”, 存放在内存中。
变量名(描述;接收变量值)= 变量值(一个具体的值)
比如: JasonSb
比如: jason_sb
常量只是约定俗成的不能变化,其实是可以变化的
变量值的引用次数加1,则引用计数加1
GC: 就是用来做垃圾回收机制的。
当变量值的引用计数为0的时候,自动触发垃圾回收机制,释放变量值的内存占用
c --> free()
针对[-5,256]之间的整数,python会在python启动的时候就会自动分配内存地址
虚拟地址() --》 硬盘(物理地址)
- id
- type
- value
使用方法:+-*/ % // **
import cmath
使用方法:+-*/ % // **
import cmath
定义方式:单(双)引号内的一串字符,三单(双)引号内的字符可以换行
使用方法:+ *
# 强制类型转换 --》 动态语言
str(10) --> 字符串的10
int('10') --> 整型的10
float('10') --> 浮点型的10.0
# 不可以强制类型转换 --》 静态语言
a = b = c = 10
x = 10
y = 20
x, y = y, x
[]内用逗号隔开多个元素(任意数据类型)
索引取值:索引从0开始,从-1开始
dic = {'a':1}
{}内用逗号隔开多个键(一般为字符串(不可变类型))值(任意数据类型)对
按key取值
所有数据类型都自带布尔值,0/None/空(空字符串/空列表/空字典)/False自带布尔值为False,其他均为True
一次性取多个值,如果某一个值不要,就用_表示
lt = [1,2,3]
s1,s2,s3 = lt
print(s1,s2,s3)
input()
f'{name}'
'%s'%(name)
'{}'.format(name)
+ - * / // % **
1. and 两边都为True,则为True
2. or 一边为True,则为True
3. not 否定
< <= > >= == !=
1. is 比较内存地址
2. is not
1. in 判断元素是否存在容器类元素内部(包括字符串)
2. not in
= += -= *= /= **= %= //=
x += 10 # x = x + 10
111 000
&
011 100
011 000
& 都为1则为1,否则为0
优先级: 要优先的加个括号就行了
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
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 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')
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循环
continue: 退出本次循环,不执行下面的代码,进行下一次循环。
n = 1
while n < 10:
if n == 8:
# n += 1 # 如果注释这一行,则会进入死循环
continue
print(n)
n += 1
else: 不被break中断就执行else缩进下的代码。
n = 1
while n < 3:
print(n)
n += 1
else:
print('else会在while没有被break时才会执行else中的代码')
#
1
2
else会在while没有被break时才会执行else中的代码
while tag(count < 3):
pass
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循环
info = {'name': 'nick', 'age': 19}
for item in info:
# 取出info的keys
print(item)
#
name
age
break: 中断循环。
name_list = ['nick', 'jason', 'tank', 'sean']
for name in name_list:
if name == 'jason':
break
print(name)
# nick
continue: 跳出本次循环,不执行下面代码,开始下一次循环。
name_list = ['nick', 'jason', 'tank', 'sean']
for name in name_list:
if name == 'jason':
continue
print(name)
#
nick
tank
sean
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 i in range(1,10):
for j in range(i):
print(....)
print()
int : 整型
float: 浮点型
str : 字符串
list : 列表
tuple :元组
dict : 字典
set : 集合
bool :布尔类型
- int:
number = 100 # number = int(100)
- 不可变类型
- float
salary = 1.0 # salary = float(1.0)
- 不可变类型
- str
str1 = 'tank' # str1 = str('tank')
- 不可变类型
# 按照索引取值
str1[1] # 取第二个值
str1[1:10:2] # 顾头不顾尾
# 内置方法
str1.split() # 切分
str1.strip() # 去左右两边的空格
str1.strip('i') # 去左右两边的i
# tank10
str1.join(['tank', '10']) # 字符串的拼接,必须是字符串类型
# 判断字符串开头,若正则返回True,否则返回False
str.startswith()
# 判断字符串结尾,若正则返回True,否则返回False
str.endswith()
# 判断字符串是否是数字,若正则返回True,否则返回False
str.isdigit()
# 新旧替换
str.replace('旧的', '新的')
# 获取某个字符的数量
str.count('字符')
# 查找字符的位置 索引 可能是面试题
str.find('字符') # 找不到返回-1
str.index('字符') # 找不到报错
- list
在[]内,可以存放多个值,每个值以逗号隔开。
list([v1, v2..])
- 可变类型
- 常用内置方法:
list.append() # 追加
list.insert() # 插入值到指定的索引中
list.pop() # 取出某个值,默认取出最后一个
list.remove() # 真正的删除元素
list.extend() # 列表合并
list.sort(reverse=True) # 默认升序 , reverse=True降序
list.copy() # 浅拷贝
- tuple
tuple((v1, v2...))
- 不可变类型
- dict
特点: key是唯一的。
dict({key:value, ...})
- 可变类型
dict[key] # 没有key会报错
dict.get(key, '自定义默认值') # 没有key会报错,默认返回None
dict.items() # 返回一个可迭代对象
dict.keys()
dict.values()
dict.fromkeys('k1', []) # 生成字典 ---》 {'k1': []}
- set
特点: 内置去重功能。
set({v1, v2...})
- 默认可变类型
# 内置方法
set.add()
set.remove()
- bool:
True or False
- 不可变类型
什么是可变?
值变了,id不变称之为可变类型。
什么是不可变?
值变了,id也变 称之为不可变类型。
什么是可变?
值变了,id不变称之为可变类型。
什么是不可变?
值变了,id也变 称之为不可变类型。
1. 索引取值
2. 索引切片
3. for循环
4. 成员运算
5. len长度
6. strip
7. split
1. rstrip/lstrip
2. rsplit
3. lower/upper
4. startswith/endswith
5. isdigit/isalpha
1. find/rfind/index/rindex/count
2. center/ljust/rjust/zfill
3. expandtabs
4. capital/swapcase/title
5. is系列
1. 索引取值/索引修改值
2. 索引切片
3. for循环
4. 成员运算
5. len长度
6. append
7. del 删除某一个元素
1. sort
2. reverse
3. pop
4. remove
5. index
6. insert
7. extend
8. copy
9. clear
有索引,有序;无索引,无序
可变:值变id不变
不可变:值变id变化
不可更改的列表,其他的和列表一模一样
[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']]
f = open('文件名的路径', '打开的模式', encoding='字符编码')
f.close()
# 文件的上下文管理: with , flask框架的上下文管理(后期学习)
with open('文件名的路径', '打开的模式', encoding='字符编码') as f:
# 内部帮你执行f.close()
操作系统提供的虚拟概念,用来存储信息的
两种方式一般不单独使用
从盘符开始
相对于当前执行文件的文件夹下的所有文件
跳出with缩进外,会自动关闭文件。可以一次性打开多个文件
如果真要即写又读,打开两次文件
- f.read():
直接将文件中所有数据一次性取出。
缺点:
内存容易溢出。
- for循环f句柄操作:
# 通过for循环,将每一行取出,保证不会内存溢出
for line in f:
print(line)
- f.readline(): (了解)
读取一行,光标移动到第二行。
文件没有插入,只有覆盖一说
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
# 为什么要有返回值
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
def func()
x = 'hello nick'
y = x
f = func
print(f)
<function func at 0x10af72f28>
def func():
print('123')
def func1(new):
new()
func1(func)
# 1 2 3
def func():
print('123')
return func
msg = func()
print(msg)
msg()
#
123
<function func at 0x000001D469711EE8>
123
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
- 函数调用
函数() # 若有参数则要传参
- 定义有参、无参、空函数
def func1(参数):
逻辑代码
pass
def func2():
# 逻辑代码
pass
def func3():
pass
- 函数的参数:
- 定义阶段: (参数用来接收调用者传入的)
- 位置形参参数
- 默认参数
- 可变长参数
- 调用阶段: (根据函数的定义者传的)
- 位置实参参数
- 关键字参数
- 注意:
# 参数从左到右的顺序
位置 ---》 关键字参数 ---》 可变长参数
- 函数的返回值:
- 返回值可以是一个或者多个
return 值1 ---> 值1
return 值1, 值2 ---> (值1, 值2)
放内置方法
除了内置和局部就是全局
函数内部的定义的变量/函数
内置 --》 全局 --》 局部
从当前位置开始 局部 --》 全局 --》 内置 --》 报错
全局作用域:全局有效,全局存活,包含内置名称空间和全局名称空间。
# 全局作用域
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
局部的可以修改全局的
修改全局作用域中的变量。
x = 1
def f1():
x = 2
def f2():
# global x # 修改全局
x = 3
f2()
f1()
print(x)
# 1
局部的修改外层局部的
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
.名称空间与作用域:
- 名称空间:
在内存中产生,是一个存放名字的地方。
- 内置名称空空间: python解释器
- 全局名称空空间: 文件中所有(顶着最左边写的)
注意: 无论嵌套if, while, for 多少层都是一个。
- 局部名称空空间: 在函数内部定义的。
- 查找顺序:
当前局部 ---》 外层局部 ---》 全局 ---》 内置
- 加载顺序:
内置 ---》 全局 ---》 外层局部 ---》 当前局部
- 作用域:
- 全局作用域:
- 内置
- 全局
- 局部作用域
- 外层局部
- 内层局部
- global: 在局部可以声明全局名字。
相当于将全局变量引用到局部中使用或修改。
- nonlocal: 在内层局部声明外层局部的名字。
可变长参数:在调用函数时,参入的参数个数可以不固定。
调用函数时,传值的方式莫非两种,一种是位置实参,另一种是关键字实参,因此形参也必须的有两种解决方式,以此来分别接收溢出的位置实参(*)也关键字实参(**)
形参中的会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给后的参数。需要注意的是:*后的参数名约定俗成为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
.名称空间与作用域:
- 名称空间:
在内存中产生,是一个存放名字的地方。
- 内置名称空空间: python解释器
- 全局名称空空间: 文件中所有(顶着最左边写的)
注意: 无论嵌套if, while, for 多少层都是一个。
- 局部名称空空间: 在函数内部定义的。
- 查找顺序:
当前局部 ---》 外层局部 ---》 全局 ---》 内置
- 加载顺序:
内置 ---》 全局 ---》 外层局部 ---》 当前局部
- 作用域:
- 全局作用域:
- 内置
- 全局
- 局部作用域
- 外层局部
- 内层局部
- global: 在局部可以声明全局名字。
相当于将全局变量引用到局部中使用或修改。
- nonlocal: 在内层局部声明外层局部的名字。
装饰器:
装饰的工具。
作用:
- 1:在不修改被装饰对象的源代码
- 2:在不修改被装饰对象的调用方式
- 基于1和2,为被装饰对象添加新功能。
# 无参装饰器:
def wrapper(func):
def inner(*args, **kwargs):
# 调用被装饰对象前添加新功能
res = func(*args, **kwargs) # index()
# 调用被装饰对象后添加新功能
return res
return inner
# 被装饰对象:
def index(参数1):
print('from index..')
index = wrapper(index)
index(实参1) # inner(实参1)
# 有参装饰器: ---> 本质上就是无参装饰器
def login_auth(name):
# 无参装饰
def wrapper(func):
def inner(*args, **kwargs):
# 对name做一个权限认证
if name == 'tank':
# 调用被装饰对象前添加新功能
res = func(*args, **kwargs) # index()
# 调用被装饰对象后添加新功能
return res
else:
print('你不是tank,get out!')
return inner
return wrapper
@ login_auth('tank') # wrapper
@wrapper
def index():
pass
- 叠加装饰器:
- 装饰顺序:
从下往上
- 执行顺序:
从上往下
要注意的是:
装饰器的实现必须遵循两大原则:
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__(),都是可迭代对象。
- 迭代器对象:
凡是内置有__iter__()与__next__(),都是迭代器对象。
优点:
- 可以不依赖索引取值
- 节省内存
缺点:
- 取值麻烦
- 无法获取长度
- for line in 可迭代对象: ----》 in: 将“可迭代对象”转成“迭代器对象”
- 内置有捕获异常机制:
while True:
try:
迭代器.__next__()
except StopIteration:
break
迭代器:迭代的工具。迭代是更新换代。
一切的对象中,但凡有__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__
方法,执行该方法会拿到迭代器本身缺点:
生成器:
生成器是一个自定义的迭代器, 生成器本质上就是一个迭代器。
- 如何生成:
- yield
def func():
yield 1
yield 2
yield 3
g = func()
g.__next__()
next(g)
# ---> 生成了生成器对象,然后每执行一次__next__,
# 会取出一个值,到下一个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()
条件成立时的返回值 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}
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'}
[line for line in 可迭代对象] # ---》 list ---》[line1, line2...]
[[1, 2, 3, line] for line in 可迭代对象] # [line1, line2...]
优点:
- 可以依赖索引取值,取值方便
- 可以获取长度
缺点:
- 占用内存空间
(line for line in 可迭代对象) # ---> 生成器
优点:
- 不占用内存空间
缺点:
- 不可以依赖索引取值,取值不方便
- 不可以获取长度
匿名函数与内置函数
- lambda 参数: 返回值
注意: 匿名函数必须配合内置函数使用,否则毫无意义
- 内置函数:
max(key=匿名函数) # 最大值
min(key=匿名函数) # 最小值
sorted(key=匿名函数) # 排序,默认升序,reverse=True降序
map(匿名函数) # 映射
reduce(匿名函数, ) # 合并
from functools import reduce
reduce()
filter(匿名函数,) # 过滤
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
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中,总共有以下四种形式的模块:
一般我们使用import和from...import...导入模块。
模块:
模块本质上就是一个.py后缀的文件。
模块是一系列功能(变量,函数)的结合体。
- 更好管理python代码
- 三种来源:
- 内置
- 第三方
- 自定义的
- 四种表现形式:
# 关注的:
- 包下带有__init__.py的文件夹中的一组py文件。
- python解释器自带的。
- 模块的导入方式:
- import 模块名字
- from 模块 import 函数/变量名
- 导入模块时发生的事情:
1.先执行当前执行文件,生成一个当前文件的名称空间。
2.会执行被导入的模块,会生成一个被导入模块的名称空间。
3.将被导入模块的名称空间加载到内存中。
- 首次导入模块发生的事情:
import demo
import demo
import demo
在执行文件中导入多次相同的模块,
会只加载首次导入的模块的名称空间。
import time
time.sleep(oldboy) #sleep(输入一个值)
一般我们使用import和from...import...导入模块。
如果你想使用多个方法:
from time import sleep,time #特定导入一些功能
如果你想导入非常多的方法
from time 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模块
模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径(某个文件夹)。如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。
模块的搜索路径指的就是在导入模块时需要检索的文件夹。
导入模块时查找模块的顺序是:从当前 局部 -> 全局 -> 内置
执行文件:当前运行的文件
模块
一个文件既可以是执行文件,也可以是模块文件。
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()
""""""
内置都是python提供的
要学习python内置的规则
subprocess模块
可以通过python代码给操作系统终端发送命令,并且可以返回结果
正则表达式:
正则表达式是一门独立的技术, 任何语言都可以使用正则表达式,
正则表达式是由一堆特殊的字符组合而来的。
字符组
元字符
组合使用
re模块:
在python中,若想使用正则表达式,必须通过re模块来实现。
。
比如要获取“一堆字符串”中的“某些字符”,
正则表达式可以帮我们过滤,并提取出想要的字符数据。
# 比如过滤并获取 “tank”
'wafawrjkwagfiu21knriut8ankjfdgau0q92ru20yrisana tank wyqfwqrqyr9q 9'
应用场景:
爬虫: re, BeautifulSoup4, Xpath, selector
数据分析过滤数据: re, pandas, numpy...
用户名与密码、手机认证:检测输入内容的合法性
用户名: na tank
import re
是用来记录日志的模块,一般记录用户在软件中的操作。
def get_logger(user_type):
# 1.加载log配置字典到logging模块的配置中
logging.config.dictConfig(LOGGING_DIC)
# 2.获取日志对象
logger = logging.getLogger(user_type)
return logger
logger = get_logger('user')
logger.info('日志消息')
if __name__ == '__main__':
执行测试模块
注意: 包也可以称之为模块。
1.什么是包?
包是一个带有__init__.py的文件夹,包也可以被导入,并且可以一并导入包下的所有模块。
2.为什么要使用包?
包可以帮我们管理模块,在包中有一个__init__.py, 由它来帮我们管理模块。
3.怎么使用包?
import 包.模块名
包.模块.名字
from 包 import 模块名
from 包.模块名 import 模块中的名字
导入包时发生的事情:
1.当包被导入时,会以包中的__init__.py来产生一个名称空间。
2.然后执行__init__.py文件, 会将__init__.py中的所有名字添加到名称空间中。
3.接着会将包下所有的模块的名字加载到__init__.py产生的名称空间中。
4.导入的模块指向的名称空间其实就是__init__.py产生的名称空间中。
import time
import datetime 格式化时间
random:
random.random() ---> 随机获取 0——1 的浮点数
random.uniform(1, 10) ---> 随机获取 1——0 的浮点数
random.randint(1, 10) ---> 随机获取 1——0的整数
random.choice(根据索引取值的可迭代对象) ---> 随机获取可迭代对象某一个值
random.shuffle(根据索引取值的可迭代对象) ---> 随机打乱
import os
import sys
import hashlib 加密
import json
pickle
collections 具名元组:
import re
subprocess
logging
第三方模块:
requests
openpyxl
- time (******) --> time.time() , time.sleep()
- datetime (******)
- --> 格式化时间 ---> Format String
- 时间的计算:
日期时间 = 日期时间 + or - 时间对象(时间间隔对象)
时间对象 = 日期时间 + or - 日期时间
- random:
random.random() ---> 随机获取 0——1 的浮点数
random.uniform(1, 10) ---> 随机获取 1——0 的浮点数
random.randint(1, 10) ---> 随机获取 1——0的整数
random.choice(根据索引取值的可迭代对象) ---> 随机获取可迭代对象某一个值
random.shuffle(根据索引取值的可迭代对象) ---> 随机打乱
- os
# 获取当前执行文件中的目录(文件夹)
os.path.dirname(__file__)
# 路径拼接
os.path.join('文件的路径', '文件名')
# 判断文件或文件夹是否存在
os.path.exists('文件绝对路径')
# 判断文件夹是否存在
os.path.isdir('文件夹绝对路径')
# 判断文件是否存在
os.path.isfile('文件绝对路径')
# 创建文件夹
os.mkdir()
# 删除文件夹
os.rmdir() # 注意: 只能删除空的文件夹
# 打印文件夹中所有的文件名
os.listdir('文件夹的路径')
- sys
sys.path # 环境变量中的路径
sys.path.append(
'项目目录'
)
sys.argv # 获取cmd中的命令行 [py文件路径, 'tank', '123']
# 可以做执行用户的校验,限制某个用户可以执行当前py文件
python3 py文件路径 tank 123
- hashlib
加密:
MD5:
md5_obj = hashlib.md5()
# 密码加密
md5_obj.update(密码.encode('utf-8'))
# 加盐
md5_obj.update(盐.encode('utf-8'))
md5_obj.hexdigest()
- 序列化与反序列化:
序列化: 将其他数据类型 ---》 json数据格式 ---》 字符串 ---》 写入文件中
反序列化: 读取文件 ----》 字符串 ---》 json数据格式 ---- 》 其他数据类型
- json
优点:
- 可以跨平台
缺点:
- 不支持python的set
注意: 传入的元组变成列表
json.dumps()
- res = 将其他数据类型 ---》 json格式的字符串
- f.write(res)
json.loads()
- json_res = f.read()
- python_data = json.loads(json_res)
json.dump()
内部执行了f.write()
json.load()
内部执行了f.read()
- pickle
优点:
- 支持python的任意数据类型
- 可以存入二进制的数据
- 存取速度快
缺点: (致命的)
- 不能跨平台使用
- 只能python自己使用
- collections
- 具名元组:
from collections import namedtuple
namedtuple('对象的名字', 'x y')
obj = namedtuple('坐标', ['x', 'y'])
target_obj = obj(10, 20)
target_obj.x # 10
target_obj.y # 20
- 有序字典:
from collections import OrderedDict
order_dict = OrderedDict({key: value})
- re:
- 正则表达式
正则表达式是一个独立的技术, 由一堆特殊的字符组成。
- 字符组
- 元字符
- 组合使用
- re模块
在python中要想使用正则表达式,必须通过re模块来编写。
- subprocess
可以通过python代码往操作系统终端输入命令,并返回结果。
- 可以远程操控电脑
- logging:
注意1: log文件的目录
注意2: log文件名
注意3: log配置字典
注意4:
logging配置字典:
LOGGING_DICT = {}
import logging.config
logging.config.dictConfig(LOGGING_DICT)
logger = logging.getLogger('普通用户')
logger.info('日志打印消息...')
if __name__ == '__main__':
执行测试代码
- 项目目录:
- conf:
- settings.py
- core:
- src.py # src ---> source
- db:
- data.json
- data.pickle
- interface:
- user_interface.py
...
- lib:
- common.py
- log:
- user_log.log
...
- bin/ start.py:
- start.py
- readme.txt
项目说明书
可迭代对象: list, tuple, dict
# [1, 2, 3]
enumerate(可迭代对象) ---》 g((0, 1), (1, 2), (2, 3))
标签:效率 x11 rmdir 乱序 ext 编译 url 组合 soup
原文地址:https://www.cnblogs.com/WQ577098649/p/11899746.html