python基础部分:
一:计算机基础及python运算符:
1.1编码:
- ASCII编码:只能表示英文字符,数字及特殊的英文字符。用1个字节表示。
- Unicode编码:能表示世界上所有的字符,用4个字节表示。
- UTF-8编码:Unicode的压缩版,能表示世界上所有的字符,用1~4个字节表示,中文占3个字节。
- GBK编码:国标码,中文占2个字节。
1.2python2和python3的区别:
python2 | python3 | 注备 | |
---|---|---|---|
str不同 | 有unicode类型 v = u'李杰' str类型 v='李杰' | 有str类型 byte类型 v = b'李杰' | py2中的str等价于py3中的byte,py2的unicode类型等价于py3的str类型 |
编译器编码 | ASCII | UTF-8 | # _ * _ coding:utf-8 _ * _ 可以指定编译器的编码 |
整数 | int具有范围,超出后自动转换成long | 无范围 | |
两个整数相除 | 只保留整数部分 | 保留全部 | from future import division可解决python2中2个整数相除只保留整数部分 |
输入 | raw_input() | input() | |
输出 | print 关键字 | print() 函数 | |
随机数 | xrange() 生成一个可迭代对象 range() 生成的是一个列表 | range()直接生成一个可迭代对象 | |
文件和包 | 包里面必须有__init__.py | 可有可无 | |
字典items,keys,values map/filter | 直接生成列表 | 返回迭代器 |
1.3python运算符的优先级
运算符 | 概述 |
---|---|
** | 指数(最高优先级) |
~、+、- | 按位翻转,一元加号和减号(最后两个的方法名为+@ 和-@ ) |
*、/、%、// | 乘、除、取模和取整除 |
+、- | 加法、减法 |
>>、<< | 右移、左移运算符 |
& | 位与 |
^、| | 位运算符 |
<=、<、>、>= | 比较运算符 |
<> == != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in in not | 成员运算符 |
not or and | 逻辑运算符 |
二:数据类型:
2.1.1整形(int)
在python2中:
- 在32位机器上,整数的位数为32位,取值范围为-2* * 31~2 * * 31-1
- 在64位机器上,整数的位数为64位,取值范围为-2* * 63~2 * * 63-1
- 超出范围之后自动转换为long
在python3中:
- 只有int类型,没有long
注意:在ptrhon2中2个整数相除只会保留整数位,如果想要保留全部需要导入模块:form __ future __ import divsision
2.1.2布尔值(bool)
true或者false
以下值会被解释为false:
- 0,'',{},(,),[],set(),None
2.1.3.字符串(str)
独有功能:
- 大小写转换:upper()/lower
- 判断是否可以转换为数字:isdecimal()
- 去两端空格:strip()
- 替换:replace()
- 分割:split()
- 判断开头和结尾:startswith()/endswith()
- 连接:join()
- 格式化:format()
- 编码:encode()
- 查找:find()/index()
区别:find()找不到返回-1,index()找不到会报错
通用功能:
- len/索引/切片/步长/for循环
2.1.4.列表:
独有功能:
-
添加:
append(元素) 在末尾追加元素
insert(索引值,元素) 在指定位置添加
extent() 追加用于for循环的每一个元素
-
删除:
remove(元素) 删除指定元素
pop(索引值) 删除指定位置的元素,不写索引值默认删除最后一个
clear() 清空列表中的所有元素
-
查找:
reverse() 翻转列表中的元素
-
排序:
sort(reverse=True/False) 从大到小/从小到大排序,默认False
通用功能:
- len/索引/切片/步长/for循环/删除/更新
列表表达式:
- [变量名 for 变量名 in 可迭代对象 条件 ]
print([i for i in range(10)])
#结果:[0,1,2,3,4,5,6,7,8,9]
print([i for i in range(10) if i > 5])
#结果:[6,7,8,9]
2.1.5.元祖:
独有功能:
- 无
通用功能:
- len/索引/切片/步长/for循环
2.1.6.字典
独有功能:
- 获取键,值,键值对 keys()/values()/items()
- 获取值 get()
- 删除键值对 pop(key)
- 增加键值对 update()
通用功能:
- len/索引/for循环/修改/删除
2.1.7.集合
独有功能:
-
增加
add()
update()
-
删除 discard()
-
交并差:instersection()/union()/difference()
通用功能:
- len/for循环
2.2.可变类型和不可变类型:
- 可变类型:列表,字典,集合
- 不可变类型:数字,字符串,元祖,布尔值
2.3.深浅拷贝
-
深拷贝:
拷贝嵌套层次中的所有可变类型
在一些赋值操作中可能会用到这个时候就要导入copy库使用copy.deepcopy进行深拷贝 -
浅拷贝:
只能拷贝第一层的内容
2.4.is 和 == 的区别:
- is是判断内存是否相等
- == 是判断值是否相等
三:文件操作
大文件的内容读取:
#方法1:
str = ""
with open("data.txt", mode="r", encoding="utf-8") as f:
for data in f:
str += data # 按行读取
#方法2:
str = ""
with open("data.txt", mode="r", encoding="utf-8") as f:
while True:
data = f.readline()
if data != "":
str += data
else:
break
print(str)
移动光标:seek()
- 移动到开头seek(0,0)
- 移动到结尾seek(0,2)) seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾
- seek(6)如果是单数而且不是0是按照字节来移动
获取光标的位置:tell()
四:函数相关
函数的默认返回值为None
函数式编程:增加代码的可读性和重用性
4.1传参的分类:
- (1)位置传参:只能参数一一对应
- (2)关键字传参:关键字参数只能放在位置传参的后面.
- (3)默认参数传参:可以接受参数,不传参数将使用默认值,
- 注意:默认关键字如果是不可变类型,可以随便玩,如果是可变类型,需要注意有一个坑.
- 如果默认参数设置成可变类型为空,改可变类型会创建在函数中,不会被释放,因此在下次调用时还会继续使用上次一创建的可变类型中的数据.
def func(data, value=[]): # 不推荐
value.append(data)
return value
print(func(11)) # [11]
print(func(1, [11, 22, 33])) # [11,22,33,1]
print(func(22)) # [11,22]
def fun1(data, value=None): # 推荐
if not value:
value = []
value.append(data)
return value
print(fun1(11)) # [11]
print(fun1(1, [11, 22, 33])) # [11,22,33,1]
print(fun1(22)) # [22]
- (4)万能传参:可以接受n个参数
# 实例1: *args 只能接受位置传参
def fun1(*args):
print(args)
fun1((11, 22, 33, 44)) # 结果: ((11, 22, 33, 44))
fun1(*(11, 22, 33, 44)) # 结果: (11, 22, 33, 44)
# 实例2: **kwargs 只能接受关键字传参
def fun2(**kwargs): # 添加冒号
print(kwargs)
fun2(k1=11, k2=22) # 结果: {'k1': 11, 'k2': 22}
fun2(k1=11, **{'k2': 22, 'k3': 33}) # 结果: {'k1': 11, 'k2': 22, 'k3': 33}
4.2函数的作用域
- 一个函数就是一个作用域.
- 作用于查找数据的规则:优先在自己的作用域中查找数据,自己没有就去上一级去找,
- 子作用域只能找到父级中的值,默认无法重写赋值
# 全局变量 a 是一个列表
a = [11, 22]
def fun():
global a # 声明 a 是全局变量
a.append(33) # 修改全局变量 a
fun()
print(a) # 结果: [11, 22, 33]
# 全局变量 a 是一个字符串
a = "aaa"
def fun1():
# 这里不声明全局变量
a = "bbb" # 修改全局变量 a
fun1()
print(a) # 结果: "aaa"
-
如果非要修改上一级或者全局变量需要添加关键字global或者nonlocal关键字
-
如果非要去修改则可以使用global 或 nonlocal关键字
globla:直接声明为全局变量
nonlocal:声明为上一级变量,不一定是全局变量大
-
全局变量的命名采用全部大写,局部变量采用小写
4.3函数小高级
4.3.1函数可以赋值
def func():
print(123)
list = [func,func,func] # func为函数的地址
for i in list:
i() # 运行函数
4.3.2函数做参数
def fun(arg):
arg()
def show():
print(111)
fun(show) # 输出111
4.3.3函数做字典的值
#应用:
def fun1():
print("fun1")
def fun2():
print("fun2")
def fun3():
print("fun3")
def fun4():
print("fun4")
def fun5():
print("fun5")
fun_dict ={"f1":fun1,"f2":fun2,"f3":fun3,"f4":fun4,"f5":fun5,}
chooice = input("请选择功能:")
find_fun = fun_dict.get(chooice)
if find_fun:
find_fun()
else:
print("请检查输入内容后在重新运行!")
4.4lambda表达式及三元运算符
4.4.1三元运算符:
- 为了解决简单的if else情况
# 定义变量 a 和 b
a = 10
b = 20
# 普通写法:
max_value = None
if a > b:
max_value = a
else:
max_value = b
print(f"较大的数是: {max_value}")
# 三元运算符写法
max_value = a if a > b else b
print(f"较大的数是: {max_value}")
4.4.2lambda表达式:为了解决简单的函数
def func(a, b):
return a + b
result = func(3, 5)
print("普通函数结果:", result)
func = lambda a, b: a + b
result = func(3, 5)
print("lambda表达式结果:", result)
4.5内置函数:
-
数据类型转换相关:
-
int 转换为整形
-
float 转换为浮点型
-
bool 转换为布尔型
-
chr 转换为字符型
-
ord 将一个unicode编码中的一个字符转换成10进制数
-
#实例:验证码生成器
import random
def get_yzm(longth=6):
yzm = []
for x in range(6):
v = random.randint(65,90)
yzm.append(chr(v))
return "".join(yzm)
print(get_yzm())
-
str 转换为字符串类型
-
list 转换为列表
-
dict 转换为字典
-
tuple 转换为元祖
-
set 转换为集合
-
数学相关:
-
abs 取绝对值
-
max 取最大值
-
min 取最小值
-
sum 求和
-
divmod 求商和余数
-
# 实例:分页
def show_pige(data, pige_num, show_num=10):
pige, a = divmod(len(data),show_num)
max_page =pige + 1 if a > 0 else pige
if pige_num < 0 or pige_num > max_page:
print("输入的值超出范围0~%s" %max_page)
else:
start_pige_num = show_num*(pige_num - 1)
end_pige_num = start_pige_num + show_num
for i in range(start_pige_num,end_pige_num+1):
print(data[i])
if __name__ == '__main__':
list = []
for i in range(0, 856):
list.append("data%s" %i)
pige_num = int(input("请输入要查看的页数:"))
show_pige(list, pige_num, 20)
-
进制转换:
- bin 将10进制转换为2进制
- oct 将10进制转换为8进制
- int 将其他进制转换为10进制
- hex 将10进制转换为16进制
#1十进制转换二,八,十六进制
num = 100
print(bin(num))
print(oct(num))
print(hex(num))
#2 其他进制转换成10进制
num_0b = "0b1100100"
num_0o = "0o144"
num_0x = "64"
print(int(num_0b,base=2))
print(int(num_0o,base=8))
print(int(num_0x,base=16))
-
其他:map/filter/reduce第一个参数必须是一个函数,第二个参数是一个可以迭代的类型
- map() 遍历序列,对序列中每个元素进行操作,最终获取新的序列。
#1.map函数应用:
#需求:每个元素增加100
li = [11,22,33,44,55,66,77,88,99]
new_list = map(lambda x:x+100, li)
print(list(new_list))
- filter() 对于序列中的元素进行筛选,最终获取符合条件的序列
#2.获取列表中大于12的所有元素集合
li = [10, 15, 20, 25]
new_set = filter(lambda x : x > 12 ,li)
print(list(new_set))
- reduce() 对序列内的所有元素进行累计操作
#3.获取列表中所有元素的和
import functools
li = [1, 2, 3, 4, 5]
new_list = functools.reduce(lambda x, y : x+y, li)
print(new_list)
- 面试题:ip地址转换
#需求将一个ip地址转换成一个32位的二进制数,并将其转换成一个10进制数输出.
ip = "192.168.1.1"
list_ip = []
for i in ip.split('.'):
i_num = bin(int(i))
i_num = "{:0>8}".format(i_num[2:])
list_ip.append(i_num)
str_ip = "".join(list_ip)
print(str_ip)
print(int(str_ip,base=2))
4.6闭包:
4.6.1闭包的概念:
为函数创建一快区域并将其维护自己数据,以后执行是方便调用
4.6.2应用场景:
装饰器,SQL ALchemy源码
4.7装饰器:
4.7.1装饰器的目的
- 在不改变原函数内部代码的基础上,在函数执行之前和之后自动执行某个功能.
4.7.2普通装饰器的编写格式:
def 外层函数(参数):
def 内层函数(*args, **kwargs):
#执行函数之前的内容
return 参数(*args, **kwargs)
#执行函数之后的内容
return 内层函数
4.7.3普通装饰器应用格式:
@外层函数名
# 第一步:执行外层函数并将下面的函数参数传递,相当于:外层函数名(index)
#第二部:将fun的返回值从新赋值给下面的函数名,相当于index = 外层函数名(index)
def index():
pass
index()
4.7.4普通装饰器的应用:
# 普通写法
import time
def fun1():
time.sleep(1)
def fun2():
time.sleep(1)
def fun3():
time.sleep(1)
if __name__ == '__main__':
# 测量 fun1 的运行时间
start_time = time.time()
fun1()
end_time = time.time()
run_time = end_time - start_time
print(f'fun1 运行时间为: {run_time:.4f} 秒')
# 测量 fun2 的运行时间
start_time = time.time()
fun2()
end_time = time.time()
run_time = end_time - start_time
print(f'fun2 运行时间为: {run_time:.4f} 秒')
# 测量 fun3 的运行时间
start_time = time.time()
fun3()
end_time = time.time()
run_time = end_time - start_time
print(f'fun3 运行时间为: {run_time:.4f} 秒')
# 采用装饰器写法:
import time
def run_time(arg):
def index(*args,**kwargs):
start_time = time.time()
arg()
end_time = time.time()
run_time = end_time - start_time
print('运行时间为:%s' % run_time)
return index
@run_time
def fun1():
time.sleep(1)
pass
@run_time
def fun2():
time.sleep(1)
pass
@run_time
def fun3():
time.sleep(1)
pass
if __name__ == "__main__":
fun1()
fun2()
fun3()
4.7.5带参数的装饰器的编写格式:
def outer(data):
def wraper(func):
def inner(*args, **kwargs):
data = func(*args, **kwargs)
return data
return inner
return wraper
4.7.6带参数的装饰器的应用格式:
@outer(data)
# 1执行 v1 = outer(data)
# 2执行 ret = v1(func)
# 3执行 func = ret
def func(*args, **kwargs):
pass
4.7.7带参数装饰器的应用:
# 1需求通过装饰器传参,使某个函数运行多次
NUM = 1
def run_time(num):
def wrapper(arg):
def inner(*args, **kwargs):
for i in range(num):
arg()
return inner
return wrapper
@run_time(5)
def func():
global NUM
print(NUM)
NUM += 1
func()
4.8递归
- 递归效率低.默认的递归最大次数为1000,查看方法如下:
import sys
result = sys.getrecursionlimit()
print(result)
- 递归的应用
#计算n的阶乘
def a(n):
if n == 1:
return 1
else:
n = n * a(n - 1)
return n
print(a(10))
五.模块
5.1 hashlib:
5.1.1 md5加密
# md5加密
import hashlib
obj = hashlib.md5('醋'.encode('utf-8')) # 加盐
obj.update('xx'.encode('utf-8'))
result = obj.hexdigest()
print(result)
5.2getpass
5.2.1密码不显示
pycharm中能够显示,只能在终端中才能不显示.
#密码不显示
import getpass
pwd = getpass.getpass("请输入密码:")
print(pwd)
5.3random:
5.3.1随机生成整数:
import random
print(random.randint(0,10))
5.4 os
5.4.1判断路径是否存在
import os
print(os.path.exists('路径地址')) # 找到返回true,找不到返回false
5.4.2获取文件的大小
import os
path = './data.txt'
print(os.stat(path).st_size)
5.4.3 获取文件的决定路径
import os
print(os.path.abspath('./data.txt'))
5.4.4 获取路径的上级目录
import os
print(os.path.dirname('C:\\Users\\lingview\\Desktop\\test.txt'))
5.4.5目录的拼接(重点)
import os
print(os.path.join('C:\\Users\\lingview','Desktop\\test.txt'))
5.4.6 获取一个目录下的所有文件(只有一层)
import os
print(os.listdir('.'))
5.4.7 获取一个目录下的所有文件(重点+面试题)
import os
for a,b,c in os.walk('.'):
for item in c:
path = os.path.join(a,item)
print(path)
5.4.8 创建目录
import os
file_path = '.'
file_name = '123'
path = os.path.join(file_path,file_name)
if not os.path.exists(path):
os.mkdir('123') # 只能创建一层目录
os.makedirs('123/456') # 创建多层目录
5.4.9 重命名
import os
old_name = 'data.txt'
new_name = 'test.txt'
os.rename(old_name, new_name)
5.5 sys:
5.5.1 sys.argv 获取传参
import sys
print(sys.argv)
5.5.2 sys.getrefcount 获取内存变量的调用次数
import sys
a = [11,22]
print(a)
print(sys.getrefcount(a)) # 2
5.5.3 sys.getrecursionlimit 获取递归的最大值
import sys
print(sys.getrecursionlimit())
5.5.4 sys.path 编译器环境变量(重点)
import sys
# 获取编译器的环境变量
print("原始 sys.path:", sys.path)
# 添加环境变量
new_path = 'C:\\Users\\lingview'
sys.path.append(new_path)
print("添加路径后的 sys.path:", sys.path)
# 移除环境变量
try:
sys.path.remove(new_path)
print("移除路径后的 sys.path:", sys.path)
except ValueError:
print(f"路径 {new_path} 不存在于 sys.path 中")
5.5.5 sys.exit 退出程序
import sys
sys.exit()
5.6 shutil
5.6.1 删除目录
import shutil
path = './test'
shutil.rmtree(path)
5.6.2 重命名
import shutil
shutil.move('123','data')
5.6.3 压缩文件
import shutil
file_name = 'hello.txt'
format = 'zip'
shutil.make_archive(file_name, format=format)
5.6.4解压文件
import shutil
file_path = 'hello.zip'
shutil.unpack_archive(file_path, format='zip', extract_dir='world')
5.6.5 练习题
# 练习题:
# 压缩data文件夹 放到code文件夹中(默认不存在) 并将文件解压到桌面code文件中
import os
import shutil
if not os.path.exists('code'):
os.mkdir('code')
shutil.make_archive(base_name='./code/data',format='zip',root_dir='data')
shutil.unpack_archive(filename='./code/data.zip',format='zip',extract_dir='test')
5.7 json
5.7.1 json基础知识
- json 是一个特殊的字符串,字符串最外层必须是列表或字典,
- 字符串中的字符串必须用双引号
- 布尔值全部为小写否则报错
- json中不能出现集合
5.7.2 序列化
import json
stra = [123,{1:456},"hello",[445,5,3],True]
a = json.dumps(stra) # 将python数据转换为json数据,如果存在中文,或变成unicode编码的字节
# 序列化保留中文,需要传入一个关键字参数ensure_ascii=False
a = json.dumps(stra,ensure_ascii=False)
print(a)
5.7.3反序列化
import json
stra = '[123,{"1":456},"hello",[445,5,3],true]'
b = json.loads(stra) # 将json数据转换为python数据
print(b)
5.8 pickle模块
5.8.1 pickle与json的区别
- pickle 和 json 都是做序列化
- json:优:所有的语言通用,缺点:只能序列化基本的数据类型
- pickle:优:python中的所有的东西都可以被序列化(套接字对象除外),缺点:序列化的内容只有python能够识别.
5.8.2 序列化和反序列化
import pickle
def run():
print('hello word!')
# 序列化
v = pickle.dumps(run)
print(v)
# 反序列化
y = pickle.loads(v)
y()
5.9 datetime模块
import time
from datetime import datetime, timedelta, timezone
# 获取当前时间
time1 = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("当前时间 (本地):", time1)
# 获取UTC时间
time2 = datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S')
print("UTC时间:", time2)
# 获取某个时区的时间 (东7区)
t = timezone(timedelta(hours=8)) # 东是正 西是负
time3 = datetime.now(t).strftime('%Y-%m-%d %H:%M:%S')
print("东7区时间:", time3)
# 将datetime.datetime装换成字符串
time4 = datetime.now()
print("当前时间 (datetime对象):", type(time4))
time5 = time4.strftime('%Y-%m-%d %H:%M:%S')
print("当前时间 (字符串):", time5)
# 将str装换成datetime.datetime类型
str1 = '2019-11-30 14:52:33'
time6 = datetime.strptime(str1, '%Y-%m-%d %H:%M:%S')
print("字符串转换为datetime对象:", time6, type(time6))
# datetime的加减
time7 = datetime.now()
time8 = time7 + timedelta(days=50)
print("当前时间加上50天:", time8)
# 时间戳转换datetime
time_t1 = time.time()
time9 = datetime.fromtimestamp(time_t1)
print("时间戳转换为datetime对象:", time9)
# datetime转换时间戳
time_t2 = time9.timestamp()
print("datetime对象转换为时间戳:", time_t2)
5.自定义模块及包的知识:
1.自定义模块
- 定义模块时可以把一个py文件或一个文件夹(也叫作包)当作一个模块,以方便以后其他的py文件的调用
# 假设有一个包名称为haha 里面有一个hello.py文件 并且haha所在的路径已经添加到sys.path中
# 导入hello的方法1:
form cirrus import hello
#引用方法:
hello.xxx
# 方法2:
import cirrus.hello
#引用方法:
cirrus.hello.xxx
- 注意:在导入模块或者包的时候,模块或包中所有的值都会被导入到内存中.
2.包的定义
- py2中:文件夹里面必须有_ _ init _ _.py
- py3中:不需要_ _ init _ _ .py,但推荐加上
- _ _ file _ _变量可以直接获取到python运行时的文件路径参数
3.包的安装方法:
- pip包管理工具
- 源码安装
1. 下载源码包,是一个压缩文件
2. 解压文件
3. 终端进入解压的路径
4. 执行python setup.py build
5. 执行python setup.py install
4.导入包:
# 假设存在一个包名称为xxx,里面包含jd.py....
import xxx
from xxx import *
# 以上2种导入全部都是导入的包里面的__init__.py文件,并不能去导入其他的模块
import xxx.jd
from xxx import jd
# 这样可以导入包里面的某一个模块
六.异常处理及多任务相关内容
1.异常处理的基本写法
try:
v = 12 + "str"
except Exception as e:
print('异常处理')
2.迭代器
- 迭代器帮助你对某种对象中的元素进行逐一获取
2.1创建迭代器
list1 = [11,22,33,44]
# 方法1
list2 = list1.__iter__()
# 方法2
list3 = iter(list1)
2.2调用迭代器的值
v = [11,22,33,44].__iter__()
# 方法1
v.__next__() # 取值时取完最后一个再去取值时则会报错
# 方法2
for i in v:
pass
2.3可迭代对象
- 具有
__intr__
和__next__
或者能够能够语用于for循环
3.生成器
3.1创建生成器
# 如果一个函数中出现了yield关键字,该函数就是一个生成器的模板
def fun():
yield 1
v = fun() # 创建生成器
3.2调用生成器的值
# 如果一个函数中出现了yield关键字,该函数就是一个生成器的模板
def fun():
yield 1
yield 2
yield 3
# 创建生成器
v = fun()
# 迭代生成器并打印其值
for value in v:
print(value)
3.3调用生成器的值并获取return的结果
def fun():
a = yield 1
b = yield 2
c = yield 3
return a, b, c
v = fun()
i = 1
# 启动生成器
next(v)
while True:
try:
result = v.send(i)
print(result)
i += 1
except StopIteration as e:
print(e.value)
break
3.4生成器推导式
v1 = [lambda i=i: i for i in range(10)] # 列表推导式,每个lambda捕获当前的i值
v2 = (lambda i=i: i for i in range(10)) # 生成器推导式,每个lambda捕获当前的i值
for i in v1:
print(i()) # 输出0, 1, 2, 3, 4, 5, 6, 7, 8, 9
for i in v2:
print(i()) # 输出0, 1, 2, 3, 4, 5, 6, 7, 8, 9