笔记day02



上周内容回顾

  • typora软件相关操作

  • 计算机基础知识

  • 编程与编程语言

  • 编程语言发展史

  • 编程语言分类

  • python解释器

  • pycharm编辑器

  • python注释语法

  • 变量与常量基本使用

  • 名字的命名规范与风格

  • python基本数据类型

    整型int、浮点型float
    字符串str、列表list、字典dict
    元组tuple、集合set、布尔值bool
  • 与用户交互

  • 运算符

    数学运算符
    增量赋值、链式赋值、交叉赋值、解压赋值
    逻辑运算符、身份运算、成员运算
  • 流程控制

    1.代码缩进的含义
    2.分支结构之单if分支

本周内容概要

主题:python基础做核心的部分之一

  • 分支结构

  • 循环结构

  • 数据类型内置方法

  • 字符编码

  • 文件处理

本周内容详细

分支结构

"""
分支结构的使用场景 可以简单的从流程图的角度分析
什么时候流程需要分叉 什么时候就应该使用if分支
"""
1.if分支结构
"""
if 条件:
  条件成立之后执行的代码
"""

2.if...else...分支结构
"""
if 条件:
条件成立之后执行的代码
else:
    条件不成立执行的代码
"""
 ps:if跟else连用 一山不容二虎 走了其中一个另外一个肯定不走

3.if...elif...else...分支结构
"""
if 条件1:
条件1成立之后执行的代码
elif 条件2:
  条件1不成立条件2成立执行的代码
else:
上述所有的条件都不成立 执行的代码
"""
 ps:
  1.if、elif、else连用也只会走其中一个子代码
     2.中间的elif可以有多个
     
4.分支结构嵌套
height = 175
 weight = 100
 is_beautiful = True
 is_success = True
 if height > 160 and weight < 110 and is_beautiful:
     print('完全符合您的审美 上去要微信')
     if is_success:
         print('邀请去吃饭看电影')
         if is_success:
             print('逛街散步天黑了')
         else:
             print('不想逛街散步 天气太热了')
     else:
         print('不想吃饭看电影 没意思')
 else:
     print('太丑了 不符合我的审美')

循环结构之while循环

我们需要将一些python代码反复执行
拷贝肯定不可取 因为无法看至次数
 所以可以使用循环结构
ps:上述案例目的就是告诉你什么时候应该使用循环结构

语法结构
"""
while 条件:
  条件成立之后执行的子代码
1.先判断条件是否成立 如果成立则运行子代码
2.子代码运行结束之后 会再次回到条件处判断条件是否成立
3.如果成立 则继续执行子代码
4.子代码运行结束之后 再次回到条件处判断条件是否成立
依次反复执行上述的操作 直到条件不成立 退出循环
"""
1.while+break配合使用
break用于结束本层循环
如何理解本层循环?
  一个break只能结束它所在的那个while循环
     while True:
       print('我是第一层while循环')
       while True:
           print('我是第二层while循环')
           break
       break
       
2.while+continue配合使用
continue用于结束本次循环 直接开始下一次循环(直接跳到条件判断处 重新判断)
一个continue也是只能影响所在的那一层while
 count = 0
     while count < 11:  # 被动退出:不需要关键字 是条件不符合了!!!
         if count == 7:
             count += 1
             continue  # 结束本次循环 直接开始下一次循环(直接再次跳到条件判断处)
         print(count)
         count += 1
         
3.while+else配合使用
else当while没有被break主动结束的情况下 当while循环体代码运行结束之后就会走else的子代码
count = 0
   while count < 11:  # 被动退出:不需要关键字 是条件不符合了!!!
       if count == 7:
           count += 1
           # continue
           break  # 主动结束循环
       print(count)
       count += 1
   else:
       print("while没有被break主动结束的情况下 执行完循环体就会执行该子代码")

while补充说明

1.循环体代码中不要出现纯计算的死循环
while True:
   count *= 10  # 代码是纯计算 没有任何的间歇 不推荐编写 一旦出现应
2.全局标志位(了解即可)
flag = True
 while flag:
     username = input('username>>>:')
     while flag:
         password = input('password>>>:')
         while flag:
             res = input('res>>>:')
             if res == 'q':
                 flag = False

循环结构之for循环

"""
for循环能够做到的事情while循环其实都可以做到
但是for循环的语法结构更加简单 并且针对循环取值问题更加高效!!!
"""
前戏
name_list = ['jason', 'kevin', 'oscar', 'jerry']
 # 使用while循环打印出列表中所有的数据值
 # count = 0
 # while count < 4:
 #     print(name_list[count])
 #     count += 1
 # 使用for循环打印出列表中所有的数据值
 for i in name_list:
     print(i)
语法结构
"""
for 变量名 in 可迭代对象: # 字符串 列表 字典 元组 集合
  for循环体代码
ps:可迭代对象暂且不用考虑 直接等价于后面的几个数据类型即可
  1.每次循环都是将变量名临时绑定一个数据值
  2.每次循环结束之后重新绑定一个数据值
  3.能够自动识别是否已经没有数据可取 并且自动结束循环 不需要人为添加条件
针对变量名的命名尽量也做到见名知意 如果真的不知道起什么
可以使用常见的字母 i j k v item
如果明确的知道数据表示的意思 应该见名知意
for name in 学生名单
for addr in 学生地址
"""
常见循环的数据类型
for i in 'hello':
   print(i)  # 一次拿一个字符
for i in {'name': 'jason', 'pwd': 123}:
   print(i)  # 字典参与for循环之后key会被获取

1.for+break配合使用
break用于结束本层for循环
for i in [1, 2, 3, 4, 5, 6, 7, 8]:
     if i == 4:
         break
     print(i)
     
2.for+continue配合使用
continue用于结束本次for循环
for i in [1, 2, 3, 4, 5, 6, 7, 8]:
     if i == 4:
         continue
     print(i)
     
3.for+else配合使用
for循环没有被break主动打断 正常运行结束 最后会走else子代码
for i in [1, 2, 3, 4, 5, 6, 7, 8]:
     if i == 4:
         break
     print(i)
   else:
       print('哈哈哈')
ps:与while的配置使用一模一样

range关键字

用法1:括号内只写一个数字
range(100)  从0开始到99结束 顾头不顾尾
变相的理解为:[0,1,2,3,4,5,6......,99]
用法2:括号内写两个数字
 range(1, 10)  从1开始到9结束 顾头不顾尾
变相的理解为:[1,2,3,4,5,6,7,8,9]
用法3:括号内写三个数字
 range(1, 10, 2)  从1开始到9结束 并且中间间隔1 (等差数列)
"""
range在不同版本的解释器下本质有所改变
python2
range()
会立刻产生一个列表 当数据特别多的时候比较占用内存
xrange()
会产生一个迭代器:工厂 需要数据就造不需要就不造 节省空间
python3
range()
会产生一个迭代器:工厂 需要数据就造不需要就不造 节省空间
"""

range实战演练

网络爬虫:通过编写代码模拟浏览器发送请求获取数据并从数据中解析出所需资源
需求:爬取某个网站多页数据

第一页:https://sh.lianjia.com/ershoufang/
第二页:https://sh.lianjia.com/ershoufang/pg2/
第三页:https://sh.lianjia.com/ershoufang/pg3/
第四页:https://sh.lianjia.com/ershoufang/pg4/
ps:第一页应该也可以写成>>>https://sh.lianjia.com/ershoufang/pg1/
'''编写代码产生链家前一百页的网址'''
base_url = 'https://sh.lianjia.com/ershoufang/pg%s/'
for i in range(1, 100):
print(base_url % i)

需求:豆瓣top250网址特性
https://movie.douban.com/top250
https://movie.douban.com/top250?start=25&filter=
https://movie.douban.com/top250?start=50&filter=
https://movie.douban.com/top250?start=75&filter=
https://movie.douban.com/top250?start=0&filter=
'''编写代码产生豆瓣top250所有页的网址'''
base_url = 'https://movie.douban.com/top250?start=%s&filter='
for i in range(0, 250, 25):
print(base_url % i)

数据类型内置方法

1.如何理解内置方法
每个数据类型都自带一些各自独有的功能
2.如何调用内置方法
数据类型通过句点符即可调用
数据类型.内置方法
ps:数据类型可以是具体的某个数据值也可以是数据类型关键字
3.如何查看内置方法
在pycharm中会自动提示
在终端中需要按tab键 然后慢慢补全(等价于linux命令补全)

整型与浮点型的内置方法

1.int整型
1.1.类型转换:将某些数据类型转成整型
可以将字符串转成整型 但是需要注意 有特殊情况
s1 = '123'
print(type(s1), s1) # 字符串里面如果是纯数字 可以转
s2 = int(s1)
print(type(s2), s2) # 字符串里面如果是纯数字 可以转
如果不是纯数字则无法转换 会直接报错
int('hello')
1.2.进制数转换:将其他进制数转成十进制
# 十进制转其他进制数
# print(bin(100)) # 0b1100100 二进制
# print(oct(100)) # 0o144 八进制
# print(hex(100)) # 0x64 十六进制
# 其他进制转十进制数
print(int(0b1100100)) # 100
print(int(0o144)) # 100
print(int(0x64)) # 100

2.float浮点型
类型转换:将某些数据类型转成浮点型
# s1 = '123'
# print(type(s1), s1) # 字符串里面如果是纯数字 可以转自动添加.0
# s2 = float(s1)
# print(type(s2), s2) # 字符串里面如果是纯数字 可以转自动添加.0

s3 = '123.23'
print(type(s3), s3) # 字符串里面如果不是纯数字 那么只允许出现一个点号
s4 = float(s3)
print(type(s4), s4) # 字符串里面如果是纯数字 那么只允许出现一个点号

3.str字符串
3.1.类型转换:可以将所有其他数据类型转成字符串
str(任意数据类型)
3.2.常见操作
s1 = 'hello jason'
# 1.索引取值
# print(s1[0]) # h
# print(s1[-1]) # n
# 2.切片操作
# print(s1[2:5]) # llo 顾头不顾尾
# 3.间隔数\方向(默认是1 默认从左往右)
# print(s1[1:10:1])
# print(s1[:]) # hello jason
# print(s1[::]) # hello jason
# print(s1[::-1]) # nosaj olleh
# print(s1[-1:-4:-1]) # nos
# print(s1[-3:]) # son
# 4.统计字符串中字符的个数(空格也算字符)
# print(len(s1)) # 11
# 5.移除字符串首尾指定的字符
# ss = '$$jason$$'
# print(ss.strip('$')) # jason
# print(ss.lstrip('$')) # jason$$
# print(ss.rstrip('$')) # $$jason
# username = input('username>>>:')
# username = username.strip() # 括号内什么都不写 默认移除首尾的空格
'''两步合并'''
# username = input('username>>>:').strip()
# if username == 'jason':
# print('登录成功')
# else:
# print('登录失败')
# 6.按照指定的字符切割字符串
# ss = "jason|123|read"
# print(ss.split('|')) # ['jason', '123', 'read'] 结果是列表 默认全部切割
# print(ss.split('|', maxsplit=1)) # ['jason', '123|read'] 也可以自定义次数
# print(ss.rsplit('|', maxsplit=1)) # ['jason|123', 'read'] 也可以变方向
# 7.字母大小写
# res = 'JaSOn666'
# print(res.upper()) # JASON666
# print(res.lower()) # jason666
# print(res.isupper()) # False (回想之前讲的小规律 布尔值相关 变量名都会有is)
# print(res.islower()) # False
"""图片验证码忽略大小写:统一转大写或者小写 然后再比较!!!"""
# code = 'YumT8'
# print('展示给用户的看的验证码>>>:', code)
# confirm_code = input('请输入您看到的验证码>>>:').strip()
# if confirm_code.upper() == code.upper():
# print('验证码正确')
# else:
# print('验证码错误')
# 8.格式化输出 方式1 占位符 方式2 format
# format用法1:等同于占位符
# print('my name is {} my age is {}'.format('jason', 18))
# format用法2:通过索引值反复使用
# print('my name is {0} {0} my age is {1} {1}'.format('jason', 18))
# format用法3:通过关键字反复使用
# print('my name is {name} {name} my age is {age} {age}'.format(name='jason', age=18))
# format究极用法
# name = 'jason'
# age = 18
# print(f'my name is {name} my age is {age}')
# 9.判断字符串中是否是纯数字
# data = input('随便输>>>:').strip()
# print(data.isdigit())
# score = input('请输入您的成绩>>>:').strip()
# if score.isdigit():
# score = int(score)
# else:
# print('成绩只能是纯数字')
# 10.替换指定的字符
# ss = 'jason jason jason say python so easy!!! jason jason jason'
# print(ss.replace('jason', 'tony')) # tony tony tony say python so easy!!! tony tony tony
# print(ss.replace('jason', 'tony', 2)) # tony tony jason say python so easy!!! jason jason jason
# 11.拼接字符串
# print('hello' + 'world') # helloworld
# print('hello' * 2) # hellohello
# print('|'.join(['hello', 'world', 'jason'])) # hello|world|jason
# 12.标题相关
# ss = 'hello world jason JAsOn'
# print(ss.title()) # Hello World Jason 所有单词首字母变大写
# print(ss.swapcase()) # HELLO WORLD JASON jaSoN 大小写颠倒
# print(ss.capitalize()) # Hello world jason jason 首字母大写 其他全部小写
# 13.判断字符串开头或者结尾
print('jason say hello'.startswith('j')) # True
print('jason say hello'.startswith('ja')) # True
print('jason say hello'.startswith('jason')) # True
print('jason say hello'.endswith('o')) # True
print('jason say hello'.endswith('llo')) # True
print('jason say hello'.endswith('hello')) # True

4.列表list
4.1.类型转换:能够支持for循环的数据类型都可以
list('hello') # ['h', 'e', 'l', 'l', 'o']
list({'name': "jason", 'pwd': 123}) # ['name', 'pwd']
4.2.内置方法
name_list = ['jason', 'kevin', 'tony', 'jerry', 'oscar']
# 1.索引相关操作
# print(name_list[0]) # jason
# print(name_list[1:4]) # ['kevin', 'tony', 'jerry'] 顾头不顾尾(左包含右不包含)
# print(name_list[1:]) # ['kevin', 'tony', 'jerry', 'oscar']
# print(name_list[1:4:2]) # ['kevin', 'jerry']
# print(name_list[1:4:-1]) # []
# 2.统计列表中所有数据值的个数
# print(len(name_list)) # 5
# 3.增数据
# append:尾部追加(括号内无论传什么 都当成一个数据值追加)
# name_list.append('jack')
# print(name_list) # ['jason', 'kevin', 'tony', 'jerry', 'oscar', 'jack']
# name_list.append([111, 222, 333])
# print(name_list) # ['jason', 'kevin', 'tony', 'jerry', 'oscar', 'jack', [111, 222, 333]]
# insert:指定索引插入(括号内无论传什么 都当成一个数据值插入)
# name_list.insert(0, 'jasonNB')
# print(name_list)
# name_list.insert(1, [11, 22, 33, 44])
# print(name_list) # ['jasonNB', [11, 22, 33, 44], 'jason', 'kevin', 'tony', 'jerry', 'oscar']
# extend:扩展列表
# name_list.extend([11, 22, 33, 44, 55])
# print(name_list) # ['jason', 'kevin', 'tony', 'jerry', 'oscar', 11, 22, 33, 44, 55]
# res = name_list + [1, 2, 3, 4, 5, 6]
# print(res) # 不推荐使用加号扩展列表
# 4.修改数据
# name_list[0] = 'jasonNB'
# print(name_list)
# 5.移除数据
# del:关键字删除
# del name_list[0]
# print(name_list) # ['kevin', 'tony', 'jerry', 'oscar']
# pop:弹出数据
# res = name_list.pop(0)
# print(name_list) # ['kevin', 'tony', 'jerry', 'oscar']
# print(res) # jason
# remove:移除数据
# res = name_list.remove('tony')
# print(name_list) # ['jason', 'kevin', 'jerry', 'oscar']
# print(res) # None:意思是什么都没有
# 6.统计列表中某个数据值出现的次数
# l1 = [11, 22, 111, 11, 11, 11, 11, 11, 22, 11, 22, 111, 11]
# print(l1.count(11)) # 8
# 7.按照大写排序
# l1 = [22, 99, 44, 33, 11, 66, 77, 88]
# l1.sort()
# print(l1) # [11, 22, 33, 44, 66, 77, 88, 99] 默认升序
# l1.sort(reverse=True)
# print(l1) # [99, 88, 77, 66, 44, 33, 22, 11]
5.字典dict
5.1.类型转换
print(dict(name='jason', pwd=123))
5.2.常见操作
d1 = {
'name': 'jason',
'pwd': 123,
'hobby': [11, 22, 33]
}
# 1.统计键值对的个数
# print(len(d1)) # 3
# 2.按key取值(字典无法使用索引取值 因为字典是无序的!!!)
# print(d1['name']) # jason
# print(d1['xxx']) # 键不存在会直接报错 不推荐使用
# print(d1.get('name')) # jason
# print(d1.get('xxx')) # None意思是什么都没有 并且对应的布尔值时False
# print(d1.get('xxx','键不存在的情况下 可以自定义提示信息')) # 键不存在的情况下 可以自定义提示信息
# print(d1.get('pwd','键不存在的情况下 可以自定义提示信息')) # 123
# 3.修改数据(语法一致)
# d1['name'] = 'jasonNB'
# print(d1) # {'name': 'jasonNB', 'pwd': 123, 'hobby': [11, 22, 33]}
# 4.新增数据(语法一致)
# d1['age'] = 18
# print(d1) # {'name': 'jasonNB', 'pwd': 123, 'hobby': [11, 22, 33], 'age': 18}
'''3和4语法是一样的 但是有区别 如果键存在则是修改 如果键不存在则是新增'''
# 5.删除数据
# del d1['name'] # 删除键值对
# print(d1) # {'pwd': 123, 'hobby': [11, 22, 33]}
# res = d1.pop('pwd') # 弹出数据
# print(d1) # {'name': 'jason', 'hobby': [11, 22, 33]}
# print(res) # 123
# 6.常见三剑客
print(d1.keys()) # dict_keys(['name', 'pwd', 'hobby']) 一次性获取字典所有的键 结果可以看成是列表 支持for循环
print(d1.values()) # dict_values(['jason', 123, [11, 22, 33]]) 一次性获取字典所有的值 结果可以看成是列表 支持for循环
print(d1.items()) # dict_items([('name', 'jason'), ('pwd', 123), ('hobby', [11, 22, 33])]) 一次性获取键值对
6.元组
6.1.类型转换
与列表一致
6.2.常见操作
t1 = (11, 22, 33)
print(type(t1)) # <class 'tuple'>
t2 = (11)
print(type(t2)) # <class 'int'>
t3 = ('hello')
print(type(t3)) # <class 'str'>
"""
当元组内只有一个数据值的时候 逗号不能省略
小建议:以后我们在定义容器类型(内部可以存放多个数据值)的时候 如果只要一个元素 逗号加上
(11,)
[11,]
{'name':'jason',}
"""
t1 = (11, 22, 33, 44)
# 1.索引操作
# 2.统计数据值个数
# 3.元组内索引绑定值的绑定关系不能改
# t1[0] = 99 # 报错 索引绑定值的关系不能修改
"""
笔试题
t2 = (11, 22, [11, 22])
t2[-1].append(33)
上述代码运行完毕后 结果是什么???

"""
t2 = (11, 22, [11, 22])
t2[-1].append(33)
print(t2) # (11, 22, [11, 22, 33])
7.集合set
集合内数据值也是无序的!!!
去重
集合内不允许出现重复的数据 如果出现会自动去重
关系运算
共同好友 共同关注 共同点赞
f1 = {'jason', 'jerry', 'kevin', 'tony'} # 小明的好友列表
f2 = {'jack', 'jerry', 'tony', 'lili'} # 小李的好友列表
# 1.求两个人共同好友
# print(f1 & f2) # {'tony', 'jerry'}
# 2.求两个人所有的好友
# print(f1 | f2) # {'tony', 'lili', 'kevin', 'jack', 'jason', 'jerry'}
# 3.求独有好友
# print(f1 - f2) # {'jason', 'kevin'}
# print(f2 - f1) # {'jack', 'lili'}
# 4.求两个人各自独有的好友
# print(f1 ^ f2) # {'jason', 'kevin', 'jack', 'lili'}
# 5.求子集 父集(谁包含谁)
print(f1 > f2)
print(f1 < f2)
print({1, } < {1, 2, 3, 4, }) # True

可变类型与不可变类型

可变类型    列表 字典
值改变 内存地址可以不变
不可变类型 整型 浮点型 字符串 元组 布尔值
值改变 内存地址肯定改变

res = '$$jason$$'
print(res.strip('$')) # jason
print(res) # $$jason$$
'''字符串在调用内置方法之后并没有改变自己 而是产生了新的结果'''

l1 = [11, 22, 33]
print(l1.append(44)) # None
print(l1) # [11, 22, 33, 44]
'''列表在调用内置方法之后并没有产生新的结果 而是直接改变的自己'''
ps:重点理解课上图释

垃圾回收机制

"""有些编程语言针对内存空间的创建和释放 是需要程序员自己写代码的"""
但是在python中 不需要程序员考虑创建和释放 全部有python自动处理
1.引用计数
name = 'jason' # jason引用计数是1
n = name # jason引用计数是2
del n # jason引用计数是1
只要数据值身上的引用计数不为0则不会被删除表示还有用 如果为0则为垃圾
'''引用计数虽然很合理 但是有一个bug>>>:循环引用'''
2.标记清除
针对循环引用:当内存即将溢出的时候会自动停止程序的运行 然后核查程序中所有的数据身上的引用计数并且可以识别出来循环引用并打上标记之后一次性清除掉所有循环引用的数据
3.分代回收
为了减轻垃圾回收机制的压力(节省计算机资源)
根据数据值被检查存活周期的长短分类 越长的检测频率月底 越短的检测频率越高

字符编码

1.前提
字符编码的研究只针对文本文件
2.如何理解字符编码
计算机是基于电工作的 电信号只有高低电平两种状态 我人为的定义为0和1
也就意味着计算机的世界其实只认识二进制数字0和1
但是我们却可以使用计算机打出各种人类的字符
"""
人类字符 转换 二级制数
字符编码:记录了字符与数字的对应
"""
ps:课外扩展
比特位 bit 一个二进制位
8bit = 1bytes
1024bytes = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
3.字符编码发展史
一家独大
计算机是有美国人发明的 为了让计算机识别英文
ASCII码:记录了英文字符与数字的对应关系
1bytes表示英文(英文字母、英文符号)
ps:此时的计算机只能识别英文
群雄割据
中国人
为了让计算机识别中文
GBK码:记录了英文、中文与数字的对应关系
1bytes表示英文
2bytes表示中文(很多中文都是3以上)
日本人
为了让计算机识别日文
shift_JIS码:记录了英文、日文与数字的对应关系
韩国人
为了让计算机识别韩文
Euc_kr码:记录了英文、韩文与数字的对应关系
ps:各个国家的计算机使用的编码表不一样 彼此无法直接交互(数据乱码)
天下一统
unicode万国码
兼容所有国家的字符
所有的字符都是至少2bytes起步存储
utf家族(utf8)
为了优化unicode存储机制
1bytes存储英文
3bytes存储中文

字符编码实战

1.乱码问题如何解决
数据当初是以什么编码编的就以什么编码解
2.编码与解码的含义
'''只有字符串可以做编码处理 编码之后数据相当于是二进制 可以基于网络发送'''
编码
将人类的字符按照指定的编码编码成计算机能够读懂的语言

解码
将计算机能够读懂的语言按照指定的编码解码成人类的字符
res = '周末班 一天就很累'
ret1 = res.encode('utf8') # 编码
print(ret1) # b'\xe5\x91\xa8...'
ret2 = ret1.decode('utf8') # 解码
print(ret2) # 周末班 一天就很累
3.不同版本解释器字符编码有区别
python2默认编码是ASCII
3.1.文件头
# coding:utf8
3.2.定义字符串前面必须要加字母u
res = u'周末班 一天就很累'
python3默认编码是utf家族
不需要文件头和字母u
ps:有时候为了兼容 也可能在python3中使用文件头和字母u(以前是的)

文件处理

1.关键方法
open(文件路径,操作模式,字符编码) # 打开文件
close() # 关闭文件
"""
推荐编写路径的前面加字母r:斜杠跟字母的组合有时候会产生特殊含义 路径中不应该有这种现象
print('asda\n\a\tsadad')
print(r'asda\n\a\tsadad')
"""

2.推荐写法
"""
不推荐写法(原因是怕忘记close 量大了之后影响资源和效率)
变量名 = open()
变量名.close()
"""
with open() as 变量名:
子代码
ps:子代码运行结束自动调用close关闭资源(省事)

读写模式

"""
pass关键字
仅仅是用来补全代码结构 防止报错 本身没有任何含义
"""
r 只读模式 只能读不能写
'''r模式 文件路径不存在会直接报错'''
with open(r'b.txt','r',encoding='utf8') as f:
pass
'''r模式 文件路径存在等待读取文件'''
with open(r'a.txt','r',encoding='utf8') as f:
pass
w 只写模式 只能写不能读
'''w模式 文件路径不存在自动创建该文件'''
with open(r'b.txt','w',encoding='utf8') as f:
pass
'''w模式 文件路径存在会先清空该文件内容 之后再写入'''
with open(r'a.txt','w',encoding='utf8') as f:
f.write('哈哈哈')
a 追加模式 尾部追加写不能读
'''a模式 文件路径不存在自动创建该文件'''
with open(r'a.txt','w',encoding='utf8') as f:
pass
'''a模式 文件路径存则在文件末尾等待写入'''
with open(r'a.txt','w',encoding='utf8') as f:
pass
ps:除了上述三种模式之外其实还有其他模式 只不过很少用 可以不看

文件对象常见方法

1.read()
一次性读取文件中所有的内容
当文件特别大的时候 该方法不可取(内存溢出) 推荐使用for循环
########################################################
2.for循环文件内容(重要)
每次只读文件一行内容 肯定不会出现内存溢出的情况
########################################################
3.readline()
没执行一次只读一行内容
4.readlines()
一次性读取文件内容并按照行组织成列表中一个个数据值
5.readable()
判断文件是否可以执行读的操作
6.write()
朝文件中写数据
7.writable()
判断文件是否可执行写的操作
8.writelines()
括号内支持传列表
9.flush()
将内存中的文件数据立刻刷到硬盘(类似于主动按ctrl+s)
ps:文件内光标移动的概念
现象:执行完read操作之后 再次执行read不会有内容

操作模式

t	文本模式
默认的操作模式
r >>>: rt
w >>>: wt
a >>>: at
1.该模式只能操作文本文件
2.读写都是以字符串为单位
3.尽量要指定encoding参数(如果不指定则会采用当前计算机默认编码)


b 二进制模式
rb\wb\ab
1.该模式可以操作任意类型文件
2.读写都是以bytes类型为单位
3.千万不要指定encoding参数(如果指定了会直接报错)

ps:在python中bytes类型等同于二进制数据

文件内容的修改(了解)

"""
机器硬盘存储数据的原理
写数据类似于刻字 该数据其实叫复杂
1.覆盖原来的数据重新刻
2.换个位置重新刻 原来的位置删掉

删数据:艳照门事件(当前人修电脑之前是删了的)
简单的删除数据相当于把硬盘某块空间状态改变了 数据其实还在
只有当写入新的数据时候才有可能被覆盖掉
ps:如何确保自己的硬盘数据不会被泄露 先格式化 然后找无效的数据下载满之后再删除 就算回复那也是无效的数据 徒劳无或
"""
张一蛋 山东 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422

with open(r'c.txt', 'r+', encoding='utf8') as f:
f.seek(9)
f.write('<妇女主任>')
# 强调:
# 1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容
# 2、内存中的数据是可以修改的

# 修改文件内容的方式1>>>:覆盖写
# with open(r'b.txt', 'r', encoding='utf8') as f:
# data = f.read()
# with open(r'b.txt', 'w', encoding='utf8') as f:
# f.write(data.replace('jason', 'tony'))
# 修改文件内容的方式2>>>:备份写
import os
with open('b.txt', 'r', encoding='utf-8') as read_f, open('b.txt.swap', 'w', encoding='utf-8') as write_f:
for line in read_f:
write_f.write(line.replace('tony', 'jasonNB'))
os.remove(r'b.txt')
os.rename(r'b.txt.swap', r'b.txt')

文件内光标的移动

1.文本模式下read括号内可以写数字意思是读取几个字符
f.read(8) jason说你好
2.二进制模式下read括号内可以写数字意思是读取几个字节
f.read(8) jason说

seek() 控制光标移动
第一个参数是位移量
字节数
第二个参数是模式
0:t和b都可以用
基于文件开头移动多少字节
1:只能用于b模式
基于光标当前位置移动字节
2:只能用于b模式
基于文件末尾移动多少字节

光标的移动其实也很少见 但是也有应用场景>>>:监控文件内容是否有新增

作业

1.根据用户输入内容打印其权限
'''
jason --> 超级管理员
tom --> 普通管理员
jack,rain --> 业务主管
其他 --> 普通用户
'''
2.编写用户登录程序
要求:有用户黑名单 如果用户名在黑名单内 则拒绝登录
eg:black_user_list = ['jason','kevin','tony']
如果用户名是黑名单以外的用户则允许登录(判断用户名和密码>>>:自定义)
eg: oscar 123
3.编写一个用户登录程序
用户如果登录失败 则只能尝试三次
用户如果登录成功 则直接结束程序
4.编写一个用户登录程序
用户如果登录失败 可以无限制尝试
用户如果登录成功 则进入内层循环 获取用户输入的指令 并打印该指令
eg: 用户输入cmd指令 则程序打印'正在执行您的指令:cmd'
给用户提供一个退出命令 用户一旦输入则退出整个程序
eg: 用户输入q指令 则程序先打印该指令再结束
5.编写猜年龄的游戏
代码提前定义出真实的年龄 之后获取用户猜测的年龄判断
用户有三次猜测的机会 如果用完则提示用户是否继续尝试
用户输入y则继续给三次机会 如果用户输入q则直接结束程序
6.计算1-100所有的数之和
7.编写代码打印出下列图形(ps:for循环嵌套)
*****
*****
*****
*****
8.基于字符串充当数据库完成用户登录(基础练习)
data_source = 'jason|123' # 一个用户数据
获取用户用户名和密码 将上述数据拆分校验用户信息是否正确

9.基于列表充当数据库完成用户登录(拔高练习) # 多个用户数据
data_source = ['jason|123', 'kevin|321','oscar|222']
10.2.编写员工管理系统
1.添加员工信息
2.修改员工薪资
3.查看指定员工
4.查看所有员工
5.删除员工数据
提示:用户数据有编号、姓名、年龄、岗位、薪资
数据格式采用字典:思考如何精准定位具体数据>>>:用户编号的作用
11.去重下列列表并保留数据值原来的顺序
eg: [1,2,3,2,1] 去重之后 [1,2,3]
l1 = [2,3,2,1,2,3,2,3,4,3,4,3,2,3,5,6,5]
12.统计列表中每个数据值出现的次数并组织成字典展示
eg: l1 = ['jason','jason','kevin','oscar']
结果:{'jason':2,'kevin':1,'oscar':1}
真实数据
l1 = ['jason','jason','kevin','oscar','kevin','tony','kevin']
13.编写简易版本的拷贝工具
自己输入想要拷贝的数据路径 自己输入拷贝到哪个地方的目标路径
任何类型数据皆可拷贝
ps:个别电脑C盘文件由于权限问题可能无法拷贝 换其他盘尝试即可
14.利用文件充当数据库编写用户登录、注册功能
文件名称:userinfo.txt
基础要求:
用户注册功能>>>:文件内添加用户数据(用户名、密码等)
用户登录功能>>>:读取文件内用户数据做校验
ps:上述功能只需要实现一次就算过关(单用户) 文件内始终就一个用户信息
拔高要求:
用户可以连续注册
用户可以多账号切换登录(多用户) 文件内有多个用户信息
ps:思考多用户数据情况下如何组织文件内数据结构较为简单
提示:本质其实就是昨天作业的第二道题 只不过数据库由数据类型变成文件
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2022-08-15 21:09  呼长喜  阅读(25)  评论(0编辑  收藏  举报