第四周总结

python基本知识

字符编码

计算机是基于电工作,由于电信号只有高电频和低电频两种状态,人为将其定义为1和0

因此为了让计算机和人能够交互,需要设计出人类字符和计算机信息语言能够互通,这就需要字符编码

1.由于计算机是由美国发明的,所以最早的字符编码记录的是英文和计算机信息的对应关系:英文ASCII码

2.之后才有了各个国家的字符和计算机信息的对应关系:中文GBK码,韩文Euc_kr码,日文shift_JIS码

3.因为不同国家的字符编码之间不能互通,很麻烦,因此又出现了了能让所有字符互通的字符编码:unicode码(万国码),以及优化版本:utf8(万国码优化版本)

(如果代码变成乱码大概率就是字符不同的问题)

编码与解码

编码 按照指定的编码本将人类的字符编程成计算机能够识别的二进制数据

res1 = res.encode('gbk') print(res1)

解码 按照指定的编码本将计算机的二进制数据解析成人类能够读懂的字符

res2 = res1.decode('gbk') print(res2)

文件路径

相对路径
  文件的相对位置,需要有一个参考系才可以,直接使用用不了

绝对路径
  文件的具体位置,不需要有参考系,但输入比较烦

转义符

在计算机的世界里斜杠与很多符号的组合有特殊的含义
  \n换行符
  \t制表符

有时候不想产生特殊含义我们可以取消转义
  r

文件操作

with open(文件路径,读写模式,字符编码) as 变量名:
    with子代码
文件路径:一般要加r,去除特殊含义

读写模式:r  (读取内容,文件不存在的话会报错)
     w  (写入内容,文件不存在会自动创建,每次写入会覆盖内容)
     a  (追加写入内容,文件不存在会自动创建,会在文件本来的内容后面写入)

(如果对象是文件,在后面+b,改为rb,wb,ab)

字符编码:一般用:encoding='utf8'

文件操作补充

1.flush()
    将内存中的数据立刻刷到硬盘 相当于ctrl+s
2.readable() writeable()
    判断文件是否可读可写
with open(r'userinfo.txt','a',encoding='utf8') as f:
    print(f.readable())  # True
    print(f.writable())  # False
3.writelines()
    括号内放列表 多个元素都会被依次写入

光标移动

seek可以控制光标移动

  seek(offset,whence)

    offset用来控制移动的位数(可以是负数,正数表示向后移动后几位,负数表示向前移动几位)

    whence是操作模式:

      0:从文件开头开始移动

      (既可以用在文本模式也可以用在二进制模式)

      1:从光标当前位置开始移动

      (只可以在二进制模式下使用)

      2:从文件末尾开始移动

      (只可以在二进制模式下使用)

    二进制状态下移动的是字节数,utf8状态下:英文1字节,中文3字节

文件修改

方法一:用新的内容把原来的内容覆盖掉
with open(r'a.txt','r',encoding='utf8') as f:
    data = f.read()
with open(r'a.txt','w',encoding='utf8') as f:
    f.write(data.replace('jason','tony'))

方法二:创建一个新文件 将老文件内容写入新文件 过程中完成修改
之后将老文件删除 将新文件命名成老文件 从而达到修改的效果
import os
with open(r'a.txt','r',encoding='utf8') as f,open(r'a.txt.backend','w',encoding='utf8') as f1:
    for line in f:
        f1.write(line.replace('tony','jason'))
os.remove(r'a.txt')
os.rename(r'a.txt.backend',r'a.txt')

列表生成式

l1 = [11, 22, 33, 44, 55, 66, 77, 88]
# 将列表中每个元素加一
new_list = []
for i in l1:
    new_list.append(i+1)
print(new_list)
# 列表生成式
new_list = [i + 1 for i in l1]
print(new_list)

name_list = ['jason', 'kevin', 'tony', 'oscar']
# 将列表每个元素后面加上_NB的后缀
new_list = []
for name in name_list:
    new_list.append(name + '_NB')
print(new_list)
# 列表生成式
new_list1 = [name+'_NB' for name in name_list]
print(new_list1)
l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99]
# 筛选出加一之后大于60的元素
new_list = []
for i in l1:
    if i+1 > 60:
        new_list.append(i)
print(new_list)
# 列表生成式
new_list1 = [i for i in l1 if i+1 > 60]
print(new_list1)

三元表达式

"""
小知识补充
    name = 'jason'
    if name == 'jason': print('jason登录成功')    
当if子代码只有一行的情况下可以整体写在一行 但是不推荐
"""
# while True:
#     name = input('username>>>:')
#     if name == 'jason':
#         print('NB')
#     else:
#         print('SB')
# 当if判断仅仅是二选一的情况下 可以使用三元表达式
name = input('username>>>:')
res = 'NB' if name == 'jason' else 'SB'
print(res)
# 语法结构
  A    if 条件 else B
    当if后面的条件为True的时候使用A
    为False使用else后面的B

函数

函数就相当于是工具
    提前定义好后续可以反复使用,避免了代码冗余的情况
        eg:修理工需要用扳手,买了扳手之后就可以一直用,不用每次都买一把
函数的语法结构
    def 函数名(参数1,参数2):
        '''函数的注释'''
        函数体代码
        return 函数的返回值
1.def
    定义函数的关键字
2.函数名
    函数名的命名与变量名保持一致 见名知意
3.参数
    函数在使用之前还可以接收外部传入的参数
4.函数的注释
    类似于产品说明书
5.函数体代码
    整个函数主要功能逻辑 是整个函数的核心
6.return
    执行完函数之后可以给调用者一个反馈结果

函数的基本使用
    函数的使用一定要先定义后使用!!!
如果在函数的代码前使用了该函数会报错
def get_info():
        print(123)

get_info()

(get_info()就等于def get_info():后面的代码,即print(123))

强调

1.定义与调用
定义函数使用关键字def
调用函数需要使用
函数名加括号(如果函数需要参数那么则额外传递参数)

2.定义阶段
函数在定义阶段只检测函数体语法不执行函数体代码

(只要函数体代码本身没错就不会报错,但可能会有下划线)

3.调用阶段
函数名加括号调用函数的时候才会执行函数体代码

函数的返回值

index()
什么是返回值?
返回值即执行完某个方法该方法反馈出来的结果
(根据需要可以使用return自己选择反馈出来的内容)
如何获取返回值?
通过变量名与赋值符号即可
变量名 = 方法/函数()
比如:
res = index()
print(res)

1.当函数体没有return关键字的时候 默认返回None
def index():
    print('from index')
res = index()
print(res)  # None即空 表示没有
2.return关键字后面写什么函数就返回什么
def index():
    print('from index')
    return 123
res = index()
print(res)  # 123
3.return后面跟多个值默认会组织成元组的形式返回
def index():
    print('from index')
    return 123, 555, 66, 5, 4, 5, 4
res = index()
print(res)  # (123, 555, 66, 5, 4, 5, 4)
4.函数体代码遇到return立刻结束整个函数的运行
def index():
    print('from index')
    return 123, 555, 66, 5, 4, 5, 4
    print('from index')

index()

函数的类型

# 1.无参函数:函数在定义阶段没有参数调用阶段也不需要参数
def index():
    print('from index')
index()

# 2.有参函数:函数在定义阶段括号内填写了变量名即需要参数
def index(x):
    print('from index', x)
index(1)

# 3.空函数(没有具体的函数体代码)
"""一般用于前期的架构搭建"""
def run():
    pass  # 补全语法结构 本身没有任何含义
def fight():
    pass
def talk():
    pass

函数的参数

"""
函数在定义阶段括号内书写的变量名称之为函数的形式参数
    简称为形参
        函数的形参相当于变量名
函数在调用阶段括号内书写的值称之为函数的实际参数
    简称为实参
        函数的实参相当于变量值
两者在调用函数的时候临时绑定 函数运行结束分开
def index(name):    形参  name = 'jason'中的name
    print(name)
index('jason'):     实参  name = 'jason'中的jason
  print('jason')
"""


# 1.位置参数:按照位置一一对应传值 多一个不行少一个也不行
def index(x, y):
    print(x, y)

index(1,2)  '''使用时,填写的参数数量必须保持和函数中一致,多了少了没有都会报错'''

# 2.关键字参数:指名道姓的给形参传值  可以打破位置限制
def index(x, y):
    print(x, y)
index(y=111, x=222)
index(111, y=222)
index(111, x=222)  #报错
print(y=111,222)  #报错
'''使用关键字参数也必须保证原函数中每个参数都有对应值,默认从左往右
而且使用关键字参数时,关键字参数必须在位置参数的后面'''
# 3.默认参数:函数在定义阶段就给形参赋值了
def register(name, age, gender='male'):
    print(name, age, gender)
register('jason', 18)
register('tony', 28)
register('kevin', 38)
register('huahua', 18, 'female')
'''通过在原函数中加默认值,可以让之后使用时,不填写有默认值的参数位子,自动使用默认的内容
如果填写了有默认值的参数格子,则填写的内容直接覆盖默认值'''
# 4.可变长参数(使用频率最高)
'''函数如何做到无论接收多少个位置参数都可以正常运行
*在形参中使用 
    会接收多余的位置参数组织成元组的形式赋值给*后面的变量名
'''
def func(a, *b):
    print(a, b)
func(1,2,3,4,5,6,7,8,9,10)  #1 (2, 3, 4, 5, 6, 7, 8, 9, 10)
func(1) #1 ()
"""函数如何做到无论接收多少个关键字参数都可以正常运行
**在形参中使用
    会接收多余的关键字参数组织成字典的形式赋值给**后面的变量名
"""
def func(a,**b):
    print(a,b)
func(a=1,b=2,c=3,d=4,e=5)   #1 {'b': 2, 'c': 3, 'd': 4, 'e': 5}
func(a=1)   #func(a=1)

# 小练习  定义一个函数 该函数无论接收多少个位置参数还是关键字参数都可以正常运行
def func(*a, **b):
    print(a, b)
func(1, 2, 3, a=1, b=2, c=3)    #(1, 2, 3) {'a': 1, 'b': 2, 'c': 3}

"""
约定俗成
    针对形参中的可变长参数 变量名推荐使用
        *args  **kwargs
def login(*args, **kwargs):
    pass
"""

*与**在实参中的作用

l = [11, 22, 33, 44, 55]
d = {'username': 'jason', 'pwd': 123, 'hobby': 'read'}
def func(*args, **kwargs):
    print(args, kwargs)
"""
*在实参中使用
    会将列表/元组内的元素打散成一个个位置参数传递给函数
"""
func(*l)  # func(11,22,33,44,55)
"""
**在实参中使用
    会将字典内的元素打散成一个个关键字参数传递给函数
"""
func(**d)  # func(username='jason',pwd=123,hobby='read')

内置函数

绝对值:print(abs(-111))
相当于and:print(all([1, 2, 3, 4, 0]))
相当于and:print(any([1, 2, 3, 4, 0]))
二进制:print(bin(100))
八进制:print(oct(100))
十六进制:print(hex(100))
判断变量是否可以调用
print(callable(name))  # False
print(callable(index))  # True
返回ASCII码中数字对应的字符
print(chr(65))  # A     65-90
print(chr(122))  # z    97-122
format字符串格式化输出
print('my name is {} and my age is {}'.format('jason',18))
print('my name is {0} {1} {1} and my age is {1} {0}'.format('jason',18))
print('my name is {name} {name} {age} and my age is {age}'.format(name='jason',age=18))
增加加依次递增的数字前标
l = ['jason', 'kevin', 'tony', 'jerry', 'tom']
count = 1
for name in l:
    print(count,name)
    count += 1

for i, name in enumerate(l, 10):  #10表示第一个的数值,默认是0
    print(i, name)


l = [11, 22, 33, 44, 55, 66, 77, 88, 99]
最大值:print(max(l))
最小值:print(min(l))
求和:print(sum(l))

python模块

名称空间
    存放变量与值绑定关系的地方
 
1.内置名称空间
    python解释器启动立刻创建结束立刻销毁
2.全局名称空间
    伴随python文件的开始执行/执行完毕而产生/回收
3.局部名称空间
    函数体代码运行产生结束销毁
# 加载顺序:内置名称空间 > 全局名称空间 > 局部名称空间



'''作用域'''
全局作用域
    内置名称空间 全局名称空间
局部作用域
    局部名称空间
   
作用域的查找顺序一定要先明确你当前在哪
    如果当前在局部名称空间
        局部名称空间 全局名称空间 内置名称空间
    如果当前在全局名称空间
        全局名称空间 内置名称空间
    如果当前在内置名称空间
        内置名称空间
    # 顺序只能从内往外 不能反向
  

如果想在局部修改全局名称空间中的名字对应的值可以使用global关键字
count = 1
def index():
    global count
    count += 1
index()

匿名函数

匿名函数
    即没有函数名的函数

语法结构
    lambda 形参:返回值
       
# 匿名函数一般不单独使用 需要结合内置函数/自定义函数等一起使用

l = [1, 2, 3, 4, 5, 6, 7]
res = map(lambda x: x + 10, l)
print(list(res))  #[11, 12, 13, 14, 15, 16, 17]

l = [1, 2, 3, 4, 5, 6, 7]
def index(x):
    return  x + 10
res1 = map(index,l)
print(list(res1))  #[11, 12, 13, 14, 15, 16, 17]
"""匿名函数主要用于一些比较简单的业务逻辑中 减少代码量"""

模块的使用

# 什么是模块与包
    具有一定功能的代码集合
        可以是py文件 也可以是多个py文件的组合即文件夹(包)
    

# 导入模块的本质
    会执行模块内代码并产生一个该模块的名称空间 
    将代码执行过程中的名字存放该名称空间中
    然后给导入模块的语句一个模块名 该模块指向模块的名称空间
    '''重复导入相同的模块 只会执行一次'''
    b.py
        import aaa
    aaa.py
        name = 'jason'
        def index():
            pass
     
# 导入模块的两种句式
    import 模块名
        可以通过模块名点出所有的名字

    from 模块名 import 子名1,子名2
        只能指名道姓的使用import后导入的子名并且还存在冲突的风险
        # from句式主要用于模块与当前文件不在同一级目录下使用
       
  # 英文和中文模块名可以,数字因为有别的含义会报错
# 如果模块名较长或者不符合你的看法 可以起别名
    import asjdkjkasdjaskdkasdasdjsjdksadksajdkasjd as ad
    from d1.d2 import f1 as fff

内置模块之时间模块

import time
print(time.time())  # 1629346116.5301917
"""时间戳:是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒"""
print(time.strftime('%Y-%m-%d'))  # 2021-08-19
print(time.strftime('%Y-%m-%d %H:%M:%S'))  # 2021-08-19 12:11:32
print('该睡了')
time.sleep(3)
print('睡醒了')    # 延时执行
def index():
    print('123')
    time.sleep(3)
    print('哈哈哈')
# 统计index函数执行的时间
start_time = time.time()
index()
end_time = time.time()
print(end_time - start_time)    # 结束时间-开始时间


import datetime
print(datetime.date.today())  # 2021-08-19
print(datetime.datetime.today())  # 2021-08-19 12:18:44.564270
# 获得本地日期 年月日
tday = datetime.date.today()
# 定义操作时间 day=7 也就是可以对另一个时间对象加7天或者减少7点
tdelta = datetime.timedelta(days=7)     # 7 day
tdelta1 = datetime.timedelta(days=-7)   # -7 day
print(tday + tdelta1)

强调

在创建py文件的时候文件名一定不能跟模块名冲突

os模块

系统模块

import os

创建文件夹

os.mkdir(r'文件夹01')  # 只能创建单级目录
os.makedirs(r'文件夹02\文件夹03')  # 可以创建多级目录
os.makedirs(r'文件夹03')
删除文件夹
os.rmdir(r'文件夹01')
os.rmdir(r'文件夹02\文件夹03')  # 默认只能删一级空目录
os.removedirs(r'文件夹02\文件夹03\文件夹04')  # 可以删除多级空目录
查看
print(os.listdir())  # 查看指定路径下所有的文件及文件夹
print(os.listdir('D:\\'))  # 查看指定路径下所有的文件及文件夹
print(os.getcwd())  # 查看当前所在的路径
os.chdir(r'文件夹03')  # 切换当前操作路径
print(os.getcwd())  # 查看当前所在的路径
判别
print(os.path.isdir(r'a.txt'))  # 判断是否是文件夹
print(os.path.isdir(r'文件夹03'))
print(os.path.isfile(r'a.txt'))  # 判断是否是文件
print(os.path.isfile(r'文件夹03'))
print(os.path.exists(r'a.txt'))  # 判断当前路径是否存在
print(os.path.exists(r'文件夹03'))
路径拼接
"""
不同的操作系统路径分隔符是不一样的
    windows是 \
    mac是 /
"""
res = os.path.join('D:\\','a.txt')  # 该方法可以针对不同的操作系统自动切换分隔符
文件大小
print(os.path.getsize(r'a.txt'))  # 字节数

hashlib模块

加密模块
将明文数据按照一定的逻辑变成密文数据
一般情况下密文都是由数字字母随机组合而成

加密算法
将明文数据按照一定的逻辑(每个算法内部逻辑都不一样)
加密之后的密文不能反解密出明文

常见加密算法:md5 base64 hmac sha系列
(算法生成的密文越长表示该算法越复杂)

import hashlib

普通加密

md5 = hashlib.md5()
将待加密的数据传入算法中
md5.update(b'hello')  # 数据必须是bytes类型(二进制),也可以通过:需要加密的内容.encode()来转换
获取加密之后的密文
res = md5.hexdigest()
print(res)

加盐加密

加盐处理:在对用户真实数据加密之前再往里添加额外的干扰数据
选择加密算法:一般情况下采用md5即可
md5 = hashlib.md5()
# 将待加密的数据传入算法中
# 加盐
md5.update('自己定制的盐'.encode('utf8'))
md5.update(b'hello')  # 数据必须是bytes类型(二进制)
# 获取加密之后的密文
res = md5.hexdigest()
print(res)
动态加盐
# 选择加密算法:一般情况下采用md5即可
md5 = hashlib.md5()
# 将待加密的数据传入算法中
# 加盐
md5.update('不固定 随机改变'.encode('utf8'))
md5.update(b'hello')  # 数据必须是bytes类型(二进制)
# 获取加密之后的密文
res = md5.hexdigest()
print(res)

random模块

随机数模块

import random

随机返回0-1之间的小数
print(random.random())
随机返回指定区间的整数 包含首尾
print(random.randint(1,6))  # 掷色子
随机抽取一个
print(random.choices(['一等奖','二等奖','谢谢回顾']))  # 抽奖
print(random.choice(['一等奖','二等奖','谢谢回顾']))
随机抽取指定样本个数
print(random.sample([111, 222, 333, 444, 555, 666, 777], 2))
随机打乱元素
l = [2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K", "A", "小王", "大王"]
random.shuffle(l)  # 洗牌
print(l)
随机验证码
"""
产生一个五位数随机验证码(搜狗笔试题)
    每一位都可以是数字\小写字母\大写字母
"""
def get_code(n):
    code = ''
    for i in range(n):  # 循环五次决定是几位验证码
        # 每一次循环都应该是三选一
        # 随机的数字
        random_int = str(random.randint(0, 9))
        # 随机的小写字母
        random_lower = chr(random.randint(97, 122))
        # 随机的大写字母
        random_upper = chr(random.randint(65, 90))
        # 随机选择一个作为一位验证码
        temp = random.choice([random_int, random_lower, random_upper])
        code += temp
    return code
print(get_code(4))

logging模块

日志模块

import logging

日志级别
logging.debug('debug message')      #调试信息
logging.info('info message')       #正常信息
logging.warning('warning message')    #警告
logging.error('error message')      #出错
logging.critical('critical message')   #重大失误

越来越严重
debug和info没影响

 模板(用的时候复制黏贴就行)

import logging

file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
'''输出到某个文件'''
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
'''       时间      某个人  触发了什么登记的日志  模式      日志的信息'''
    datefmt='%Y-%m-%d %H:%M:%S %p',
    handlers=[file_handler,],
    level=logging.ERROR
)

logging.error('你好')


import time
import logging
from logging import handlers

sh = logging.StreamHandler()
rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5)
fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8')
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    handlers=[fh,sh,rh],
    level=logging.ERROR
)

for i in range(1,100000):
    time.sleep(1)
    logging.error('KeyboardInterrupt error %s'%str(i))


import logging

logger = logging.getLogger()
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log',encoding='utf-8')

# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setLevel(logging.DEBUG)

fh.setFormatter(formatter)
ch.setFormatter(formatter)
logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
logger.addHandler(ch)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

json模块

import json

简单的理解为
可以将其他数据类型转换成字符串
也可以将字符串转换成其他数据类型
序列化:将其他数据类型转换成json格式的字符串
d = {'username': 'jason', 'pwd': 123}
res = json.dumps(d)  #序列化
print(res, type(res)) # {"username": "jason", "pwd": 123} <class 'str'> d1 = {"username": "jason", "pwd": 123} print(d1) 只有json格式字符串才会是双引号 双引号就是判断json格式字符串的重要依据
反序列化:将json格式字符串转换成对应的数据类型
d = {'username': 'jason', 'pwd': 123}
res = json.dumps(d)
res1 = json.loads(res)  #反序列化
print(res1, type(res1))  # {'username': 'jason', 'pwd': 123} <class 'dict'>
文件序列化
d = {'username': 'jason', 'pwd': 123}
with open(r'a.txt','w',encoding='utf8') as f:
    json.dump(d,f)  #自动先序列化再写入
文件反序列化
d = {'username': 'jason', 'pwd': 123}
with open(r'a.txt','r',encoding='utf8') as f:
    res = json.load(f)  #自动变回字典导出  一个对一个,如果目标有多行字符串会报错,所以需要建个文件夹,把每条信息创一个文件
print(res,type(res))
并不是所有的python数据都可以转json格式字符串
转换表:
并不是所有的python数据都可以转json格式字符串
转换表:
Python          JSON
ict             object
list, tuple     array
str             string
int, float      number
True            true
False           false
None            null

 

posted @ 2021-08-22 21:40  雾雨黑白  阅读(40)  评论(0编辑  收藏  举报