"""
1、可变与不可变类型:*****
2、set类型:*
3、字符编码:****
4、文件处理:****
5、函数:******
"""
"""
2、数据类型
字符串:
-- 拼接(重复)
-- 常用方法
列表:
-- 拼接(重复)
-- 常用方法
-- 删
字典:
-- 定义 成员运算 拼接(重复) 迭代 for k, v in dic.items()
-- 常用方法
-- 删查 dic[key]
"""
# 一、判断一个类型是否是可变与不可变
# 总结:hash算法计算的结果不可变,导致参与哈希运算的值不能变化
# => 不可变类型才可以hash
# 二、可变与不可变的本质
# 1、不可变类型:堆区空间开辟赋值后,该空间值不能发生改变
# -- 一个变量存放一个值,如果值改变,id(变量) 值改变
# 2、可变类型:堆区空间开辟赋值后,空间内部的值可以发生改变
# -- 一个变量存放一个值,如果内部值改变,id(变量) 值不变
# 3、不可变的容器:
# 不可变的容器存放可变容器,可变的容器依然可以发生内部改变,但不可变容器存放的值是可变容器的地址,可变容器发生内容改变时自身地址不发生改变,所以不可变容器本质没有发生改变
# 三、可变与不可变都有哪些
# 可变:list、dict、set
# 不可变:str int float bool tuple None
"""
# 根据keys产生字典,每一个遍历的key的值一致,默认为None,也可以自定义
res = {}.fromkeys(['n1', 'n2', 'n3'], 0) # iterable | iterable, default
print(res)
dic = {'name': '张三'}
# 如果key不存在,就添加key并设置默认值(默认值默认为None),如果key已存在,啥事不干
dic.setdefault('name', '默认值')
print(dic)
"""
# setdefault应用
# phone_book = {
# 'O': [
# ('owen', 16656789900),
# ('open', 19900000021)
# ]
# }
phone_book = {
# 'O': [],
# 'Z': []
}
name = input('name:')
phone = input('phone:')
group = name[0].upper()
# if group in phone_book: # 有分组直接添加
# phone_book[group].append((name, phone))
# else: # 没有分组创建分组添加
# phone_book[group] = []
# phone_book[group].append((name, phone))
phone_book.setdefault(group, [])
phone_book[group].append((name, phone))
# why:set容器没有索引、没有key、无序存储,但存储的数据不能重复,所以用set来完成数据的去重
# 一、定义
s1 = {1}
print(s1, type(s1))
# 空set
s2 = set()
print(s2, type(s1))
# set是无序存储 => 没有索引,所以不能用索引取值
# set是单例集合 => 没有key,索引不能用key取值
# 结论:set没有自身取值方式,只能借助迭代器(for循环取值) | 方法
s3 = set('123')
print(s3)
# 二、增删
s5 = {'1', '2', '3'}
# 删:remove | pop
# res = s5.pop()
# print(s5, res)
# 增:add | update
# s5.update('345')
# print(s5)
# 三、运算
# 运算
python = {'p1', 'p2', 'Nick'}
linux = {'l1', 'l2', 'Nick'}
# 交集 &:报了两门课
res = python & linux
print(res)
res = python.intersection(linux)
print(res)
# python.intersection_update(linux)
# print(python)
# 合集 |:报了课程的所有人
res = python | linux
print(res)
res = python.union(linux)
print(res)
# 对称差集 ^:只报了一门课的人
res = python ^ linux
print(res)
res = python.symmetric_difference(linux)
print(res)
# 差集 -:只报了某门课的人
p_res = python - linux
print(p_res)
l_res = linux - python
print(l_res)
p_res = python.difference(linux)
print(p_res)
# 四、比较(看一个set是否是另一个的子集,或者两者是否是相同的)
s6 = {1, 2, 3}
s7 = {1, 2, 3}
print(s6 > s7) # s7是s6的子级
# 一、编码表
# 编码表:人能识别的标记 与 计算机能识别的指令(01组成) 的映射关系 形成的表
# 二、字节的概念
# 1个字符占1个字节,1个字节占8个二进制位
# a、1、$ => 字符 => 字节 => 00000000
# ord(字符) => 编码的10进制表示 => bin(十进制) => 十进制数对应的二进制数 => 编码表中的指令
# A => 01000001
# print(bin(65))
# print('A', ord('A'), bin(ord('A')))
# 三、乱码
# 中文字符、小和民族、棒子民族 => GBK、Shift_JIS、Euc-kr => 乱码
# 什么是乱码:输入的信息与输出的信息不一致
# 什么导致乱码:输入与输出采用的编码表不一致
# 四、万国码
# 2个字节 => 16个二进制位 => 65535个对应关系 => 足够表示所有映射关系 => Unicode编码表
# 万国码 => Unicode => 16个二进制位
# 五、UTF-8
# 万国码Unicode => 2个字节 => 编程大量为英文 => 费存储空间 =>
# 解决方案 => 变长存储 => 存储字符所占字节长度与字符本身含义两种信息
# 英文 => 1个字节 中文 => 3个或6个
# 文本内容:123好的
# 六、实际运用:
# 内存 => Unicode
# 传输 => UTF-8 => 计算机的输入输出传输过程、数据的网络传输过程
# 七、拓展:
# ASCII 有 DBCS => 用双字节表示中日韩文字
# ord(): ASCII 字符=>字节
print('①', ord('①'), bin(ord('①')))
# chr():ASCII 字节=>字符
print(chr(9322))
# 八、字节与字符的转换:
# 本机存取:编辑器帮我们完成的字节与字符的转换
# 跨机存储:需要手动调用传输功能,传输的数据由必须是字节(二进制),用来传输的原始数据是人能看得懂的:字符
# 所以需要掌握 字符转换字节然后传输。反过来作为数据的接收方,所以需要掌握 字节转换字符然后显示
# 九、编码与解码
source = 'a原始数据'
# 编码:字符转换字节 source.encode('编码表的名')
byte_data = source.encode('utf-8') # 通过用utf-8,但是也可以使用其他编码如 gbk、ascii(默认)
print(byte_data)
# 解码:字节转换字符
str_data = byte_data.decode('utf-8')
print(str_data)
# -- * -- coding: utf-8 -- * --
# 文件头:在文件首行出现 coding 关键字,用 : 引出的编码名可以作为解释器解释该文件的 编码规则
# 问题点:编辑器:pycharm、nodepad++,都可以用文件存储的编码读取文件,但是将内容
# 以utf-8读取到内存中,交给python解释器来解释执行内存中的代码,会采用解释器默认的编码语言
# python2默认编码:ASCII => py2环境编程一定要设置文件头
# python3默认编码:UTF-8 => py3环境编程一般都省略设置文件头
# 解决:在文件首行设置文件头
# 什么是文件:电脑硬盘的一块存储空间
# 什么是文件处理:管理数据与硬盘存储空间的交互
# 文件操作的步骤
# 第一步:向操作系统发送 打开文件的指令 - 让操作系统对硬盘的一块空间具有持有权
# 内容从 硬盘 到 内存
# 第二步:python编程语言定义持有内存空间的变量,进而来操作内存的数据
f = open('gbk.txt', 'r', encoding='gbk')
# 重点:open()操作是操作系统来完成,使用编码规则与操作系统有关,windows - gbk | macOS - utf-8
# open()操作一定要规定编码规则(后期有变化)
# 第三步:python编程语言根据具体语法完成对内存数据的具体操作(业务逻辑)
content = f.read()
print(content)
# 第四步:向操作系统发送 关闭文件的指令 - 让操作系统释放对硬盘空间的持有权
f.close() # 文件的关闭是必须的
# 第五步:python释放对内存空间的持有权
del f # 变量的释放回收系统会自动完成,不需要写
# 1、打开文件
f = open(r'文件的绝对或相对路径', 'r', encoding='utf-8')
# 2、操作文件
content = f.read()
print(content)
# 3、关闭文件
f.close()
# with语法:简化文件操作的三步骤
# 1)省略close()关闭步骤,当缩进内的代码执行完毕,会自动close()
# with open('gbk.txt', 'r', encoding='gbk') as f:
# content = f.read()
# print(content)
# 2)多文件操作是
# 用with管理多个open();with也可以形成嵌套
with open('gbk.txt', 'r', encoding='gbk') as f1, open('0、作业.py', 'r', encoding='utf-8') as f2:
c1 = f1.read()
print(c1)
c2 = f2.read()
print(c2)
with open('target.txt', 'w', encoding='utf-8') as w:
w.write(c1 + c2)
# 写
with open(r'txt/test.txt', 'w', encoding='utf-8') as f:
print(f.writable()) # 是否可写
f.write('123\n')
f.write('456\n')
f.writelines(['aaa\n', 'bbb\n'])
# 两种写法都不自带换行
# 当要书写的数据是一条条来的,用write()一次次写
# 当要书写的数据是多条来的(用单列容器存储),用writelines()一次性写
# 重中之重:慢慢的将文件读完
with open(r'txt/test.txt', 'r', encoding='utf-8') as f:
for line in f: # for的in后跟读的文件对象,会自动一行一行取内容
print(line, end='')
# 语法讲解
with open(r'txt/test.txt', 'r', encoding='utf-8') as f:
# print(f.readable()) # 是否可读
# 了解:将所有信息读取,存放在list中,换行符用\n表示
# res = f.readlines()
# print(res)
# 重点:
# line1 = f.readline()
# print(line1, end='')
# line2 = f.readline()
# print(line2, end='')
# 了解:将所有信息读取,放在一个字符串中
# res = f.read()
# print(res)
# 重点:规定读取的最大单位,内容不够就全部读出
# r1 = f.read(2)
# print(r1)
# r2 = f.read(2)
# print(r2)
# r3 = f.read(2)
# print(r3)
# 文件的复制
with open(r'txt/test.txt', 'r', encoding='utf-8') as rf:
with open(r'txt/test_copy.txt', 'w', encoding='utf-8') as wf:
for line in rf: # 一行行读
wf.write(line) # 读多少写多少
'''
主模式:
r:文件必须存在,不存在保存的读(默认)
w:文件不存在创建写,存在清空写
a:文件不存在创建追加写,存在追加写
从模式:
t:以文本字符模式来操作文件内容(默认),open必须规定encoding
b:以字节模式来操作文件内容(可以操作所有类型文件),open不能规定encoding
+:可读可写
'''
# 7.可读可写
# rt+(r+ | r+t):文件必须存在的可读可写,采用文本方式,要加encoding
# wt+(w+ | w+t):文件不存在创建,存在清空,采用文本方式,要加encoding
# at+(a+ | a+t):文件不存在创建,存在追加,采用文本方式,要加encoding
# rb+(r+b):文件必须存在的可读可写,采用进制方式,不能加encoding
# wb+(w+b):文件不存在创建,存在清空,采用二进制方式,不能加encoding
# ab+(a+b):文件不存在创建,存在追加,采用进制方式,不能加encoding
with open('txt/test_copy.txt', 'ab+') as f:
print(f.writable())
print(f.readable())
f.write('好'.encode('utf-8'))
f.write(b'1a\xe5\x91\xb5\xe5\x91\xb5\xe5\x91\xb5')
# 6.ab
# with open('txt/test_copy.txt', 'ab') as f:
# f.write('好'.encode('utf-8'))
# f.write(b'1a\xe5\x91\xb5\xe5\x91\xb5\xe5\x91\xb5')
# 5.wb
# with open('txt/test_copy.txt', 'wb') as f:
# f.write('好'.encode('utf-8'))
# f.write(b'1a\xe5\x91\xb5\xe5\x91\xb5\xe5\x91\xb5')
# 4.rb
# with open('txt/test.txt', 'rb') as f:
# data = f.read(3)
# print(data.decode('utf-8'))
# 1.rt
# with open('txt/test.txt', encoding='utf-8') as f:
# print(f.read(1))
# 2.wt
# with open('txt/test_copy.txt', 'w', encoding='utf-8') as f:
# f.write('11111\n')
# 3.at
# with open('txt/test_copy.txt', 'a', encoding='utf-8') as f:
# f.write('11111\n')
with open('img/001.png', 'rb') as rf:
with open('img/002.png', 'wb') as wf:
for line in rf:
# 只是将内容写入到内存中
wf.write(line)
# 将内存中的数据刷新到硬盘中
wf.flush()
# 内存小的时候,建议添加flush()
# 内存大的时候,不建议使用flush(),因为最后的文件关闭close()内部有flush()