1、赋值运算

a = 10
print(a)

py没有定义常量的语法,但可以用全大写变量名来约定俗成常量

PI = 3.14
print(PI)
PI = 5.21
print(PI)

需求:交换两个整型数的值
a = 10
b = 20

方法一:借助第三种方法
a = 20 | b = 10
c = a
a = b
b = c
print(a, b)

方法二:交叉赋值
a, b = b, a
print(a, b)

运算赋值

+ -...
num = 100
num += 1  # num = num + 1
print(num)

num **= 2
print(num)

解压赋值

list = [1, 2, 3, 4, 5]
a = list[0]
b = list[1]
print(a, b)

a, b, c, d, e = list  # 按位赋值
print(a, b, e)

x, _, _, _, y = list  # 只想得到首尾两个(1,5)
print(x, y)

2、if分支结构

判断分支:根据不同的实际情况选择执行分支

age = int(input('请输入你的年纪:'))
print(age)
print("去相亲!")
print("阿姨好,打扰了!")

语法:

if 条件表达式:
    逻辑语句1  # 利用缩减表示附属关系
    ...
    逻辑语句n
逻辑语句n+1
...
    逻辑语句m  # 报错

part1

if age <= 18:
    print("去相亲!")

print('if分支执行完毕')

if age > 18:
    print("阿姨好,打扰了!")

part2

if 条件表达式1:
    逻辑语句块1
else:
    逻辑语句块2

if age <= 18:
    print("去相亲!")
else:
    print("阿姨好,打扰了!")

part3

if 条件表达式1:
    逻辑语句块1
elif 条件表达式2:
    逻辑语句块2
else:
    逻辑语句块3

price = int(input("phone price: "))
if price > 15000:
    print("不考虑!")
elif price > 10000:  # 该分支可以有0~n个
    print('观望!')
else:  # 该分支也可以省略
    print('入手!')

案例:登录

username = input("请输入账号:")

if username == 'owen':
    pwd = input("请输入密码:")
    # 账号成立后,要进一步都密码进行验证:形成if的嵌套
    if pwd == '123':
        print('登录成功')
    else:
        print('密码错误')
else:
    print("账号不存在!")

3、while循环

大呼:engo最衰
print('engo最衰')
喊五次
print('engo最衰')
print('engo最衰')
print('engo最衰')
print('engo最衰')
喊100次:代码量过大,买复读机

循环语法

while 条件:
    代码块

原理:当条件为真,执行代码块,到条件为假,结束该循环

计数器

count = 1
while count <= 5:
    print('engo最衰')
    count += 1

找1~100之间是7的倍数的最大数

res = 1
num = 1
while num <= 100:
    if num % 7 == 0:
        res = num
    num += 1
print(res)

从大到小循环,可以快速找到98

res = 100
num = 100
while num >= 1:
    print('====')
    # 如何达到找到第一个,就结束循环
    if num % 7 == 0:
        res = num
        break  # break当次循环的逻辑下方代码被中断屏蔽
    num -= 1
print(res)

ages = [18, 32, 20, 35, 27, 25]
需求:打印所有30岁以下的年龄

count = 0
while count < 6:
    if ages[count] < 30:
        print(ages[count])
    count += 1
count = 0
while count < 6:
    if ages[count] >= 30:
        count += 1
        continue  #continue:结束本次循环(中断屏蔽当次循环的逻辑下方代码),进入下一次循环
    else:
        print(ages[count])
    count += 1

break:用来结束所属的最近的一层循环
continue:结束本次循环(中断屏蔽当次循环的逻辑下方代码),进入下一次循环

while…else…: else为循环合理结束之后的分支(不合理:循环被break中断了)

count = 0
while count < 5:
    if count == 3:
        # count += 1
        # continue
        break
    count += 1
else:
    print("循环合理结束")

4、数字类型

整型int 长整型long 浮点型 复数

a = 10  # int(10)
a = int(10)
print(a, type(a))

py3不支持long

a1 = long(10)
print(a1, type(a1))

py3用int表示所有整型(包括天文数字(不存在越界溢出))
原因:当数据过大,底层采用字符串存储

a2 = 12345678901234567890123456789012345678901234567890
print(a2, type(a2))

小数

b = float(3.14)
print(b, type(b))

复数:实数 + 虚数j

c = 5 + 4j
c = complex(5, 4)
print(c, type(c))

5、字符串类型

5.1、声明

s1 = ‘字符串’
ss1 = “字符串”
sss1 = “””字符串””” # 多行字符串

小张是个"好学生"
print('小张是个"好学生"')  # 利用字符串嵌套来完成有引号的字符串输出
print("小张是个'好学生'")
#\' | \" 该单、双引号只有在输出时才会被转化为' | "
print("""'小张'是个"好学生\"""")


ssss1 = str('字符串')
print(ssss1)

5.2、字符串索引(从0开始编号)取值

s2 = 'abc123嘿嘿'

# 正向索引,从0开始编号
print(s2[3])
# 反向索引,从-1开始编号
print(s2[-3])

5.3、切片(获取子字符串): 语法[开始索引:结束索引:步长]

# 顾头不顾尾[6:8],从索引6截取到索引8之前
ss2 = 'hello world'
new_ss2 = ss2[6:8:]
print(new_ss2)
# 结束索引:-1代表截取到最后一位之前,省略代表截取到最后
# 开始索引省略代表从头开始截取
print(ss2[6:-1:])
# 截取一次只截取一个字符,但是截取后迈2步截取下一个hlowrd
print(ss2[::2])
# 打印'dlrow olleh',翻转字符串
# 步长为负数时,从后往前截取(开始索引建议使用负值)
print(ss2[-1::-1])

重点:s[开始索引:结束索引]

5.4、长度

s3 = 'abcdef'
print(s3.__len__())
print(len(s3))  # len(s) 获取s的字符长度

5.5、拆分

s4 = "D:\\pathon36\\python3.exe"
# 需求:1.获取python的安装盘符;2.获取python的执行文件
s4_list = s4.split('\\')  # 拆分:就是将字符串转化为列表
print(s4_list)
print(s4_list[0])
print(s4_list[-1])

# 完成以上需求还要保证拆分得到的结果尽可能短
# 注:拆分的依据,拆分的次数
s4_list = s4.split('\\', 1)
print(s4_list[0])

5.6、成员判断

s5 = 'abc123嘿嘿'
# in | not in: 子字符串 in 父字符串
print('abcd' in s5)
print('abc' not in s5)
print('呵呵' not in s5)
# not in要同步出现
print('>>>', '呵呵' not in s5)

5.7、首尾去白

s6 = "  hello  world  "
print(s6.strip())

5.8、数字判断

num = input("请输入:")
if num.isdigit():
    num = int(num)
    print(num)
else:
    print("请输入数字")

需求:只有输入数字才允许通过,否则要重复输入

reStr = ''
while True:
    num = input("请%s输入:" % reStr)
    if num.isdigit():
        num = int(num)
        print(num)
        break
    else:
        print("请输入数字")
        reStr = "再次"

需求:错误三次也退出

reStr = ''
count = 1
while True:
    num = input("请%s输入:" % reStr)
    if num.isdigit():
        num = int(num)
        print(num)
        break
    elif count >= 3:
        print("错误次数过多")
        break
    else:
        print("请输入数字")
        reStr = "再次"
        count += 1

6、字符串循环

字符串循环(遍历)

s = 'hello world'
i = 0
while i < len(s):
    print(s[i])
    i += 1

迭代

s = 'hello world'
for c in s:
    print(c)

1.循环迭代s,一次在s中取出一个字符,存放到c中
2.下一次取出会覆盖上一次c
3.当s中所有字符取出后,循环自动停止

# 哪些变量是可以被迭代的:str、list、dict、tuple、set、range生产的对象
print(range(5))
# 从什么数字开始,到什么数字前结束,步长是多少
for i in range(1, 5, 2):
    print(i)

for i in range(10, 16):
    print(i)

7、字符串了解

  1. lstrip | rstrip:左 | 右 去留白

    s1 = "  hello  world  "
    print(s1.rstrip())
    ss1 = "===hello  world***"
    print(ss1.rstrip("*"))
  2. rsplit:从右开始拆分

    s4 = "D:\\pathon36\\python3.exe"
    s4_list = s4.rsplit('\\', 1)
    print(s4_list)
  3. lower | upper:全小 | 大写

    print("AbCd".lower())
    print("AbCd".upper())
  1. startswith | endswith:以某某开头 | 结尾:返回值为bool类型

    print("http://www.baidu.com".startswith('https://'))
    print("http://www.baidu.com".endswith('com'))  # 思考:自学正则:re
  2. format:格式化

    print('name:%s,age:%s' % ('owen', 18))
    # 占位与实际数据要进行个数与位置的匹配
    print('name:{},age:{}'.format('Liuxx', 8))
    # 指定位置要数据:{0}要0号位数据
    print('name:{0},age:{1}, name:{0}'.format('Linoo', 58))
    # 指定名字要数据
    print('name:{usr},age:{age}, name:{usr}'.format(age=58, usr='Linoo'))
  3. replace:替换

    # 语法:replace(oldS, newS, count)
    s6 = 'abcabcabc'
    newS6 = s6.replace('a', 'A', 2)
    print(newS6)

扩展


  1. find | rfind:查找子字符串索引,无结果返回-1

    s1 = 'abcabc'
    print(s1.rfind('ab'))  # 返回第一次查询到的(目标字符串首位)正向索引
  2. index | rindex:查找子字符串索引,无结果抛出异常

    s1 = 'abcabc'
    print(s1.index('cb'))  # 没有匹配的就崩溃
  3. count:计算子字符串个数

    s1 = 'abcabc'
    print(s1.count('abc'))
  4. center | ljust | rjust | zfill:按位填充
    语法:center(所占位数, ‘填充符号’)
    使用: 调用者.center(参数)

    print("华丽分割线".center(30, '-'))
    print("华丽分割线".ljust(30, '-'))
    print("1240".zfill(5))
    print("9010".zfill(5))
    print("59000".zfill(5))
  5. expandtabs:规定\t所占空格数

    print('hello\tworld'.expandtabs(8))
  6. captialize | title | swapcase:首字母大写 | 单词首字母大写 | 大小写反转

    print("hello world".capitalize())
    print("hello world".title())
    print("hello WORLD".swapcase())
  7. isdigit | isdecimal | isnumeric:数字判断

    s7 = b'123'  # isdigit来判断是否可以转换为数字
    print(b'123'.isdigit())

    #三个方法均有
    print(u'123'.isdigit())
    print(u'123'.isdecimal())
    print(u'123'.isnumeric())

    print('肆'.isdigit())
    print('肆'.isdecimal())
    print('肆'.isnumeric())  # 可以判断中文数字
    print('Ⅳ'.isdigit())
    print('Ⅳ'.isdecimal())  # 不用管
    print('Ⅳ'.isnumeric())  # 可以判断罗马数字
  1. isalnum | isalpha:是否由字母数字组成 | 由字母组成

    print('abc123_'.isalnum())
    print('abc'.isalpha())
  2. isidentifier:是否为合法变量名

    print('>>>', 'a_123'.isidentifier())
  3. islower | isupper:是否全小 | 大写

    print("aBc".islower())
  4. isspace:是否是空白字符

    print(" ".isspace())
  5. istitle:是否为单词首字母大写格式

    print("Hello World".istitle())

list tuple dict set

int = 10
print(int)

s = '10'
print(int(s))

8、可变与不可变数据类型

数字

1.只能存放一个值
2.数字为不可变类型: 值改变了id一定改变(值一旦确定,就不能再修改)

a = 10
print(id(a))
# a = 11
a += 1
print(id(a))

字符串

1.只能存放一个值
2.字符串为不可变类型

s = '123'
print(id(s))
s = s * 2
print(id(s))

列表

1、为可变类型,在id不改变的情况下,还可以修改内部数据

l = [1, 2, 3]
print(id(l))
print(l[0])

l[0] = 10
print(id(l))

l.append(20)
print(id(l))

9、列表类型

9.1、定义列表

l1 = [1, 3.14, 5 + 4j, True, 'abc', [[1]]]
print(l1)

l2 = list([1, 3.14, 5 + 4j, True, 'abc', [[1]]])
print(l2)

l3 = list('abc')
print(l3)

9.2、字符串 <=> 列表
将字符串转换为列表: 字符串方法

l4 = 'hello world'.split(' ')
print(l4)

将列表转换为字符串: 字符串方法,调用方法的字符串为拼接字符串的依据
将列表中的所有数据,从前往后,安装拼接符进行拼接

newStr = '@'.join(l4)  # hello@world
print(newStr)

9.3、切片

list3 = [1, 2, 3, 4, 5]
print(list3[1:-1:2])  # [2, 4]

9.4、增删改查
删除普通变量

a = 10
del a
print(a)

增:append(obj) 在末尾添加对象

list4 = []
print(id(list4))
list4.append(1)
list4.append(5)
list4.append(2)
print(list4)

插入

list4.insert(0, 10)    #这里的0指的是索引
print(list4)
print(id(list4))

删除指定索引
del list4[0]
print(list4)

删除指定对象
list4.remove(5)
print(list4)

改:

list4[0] = 10000   #这里的0是索引
print(list4)

查:

print(list4[1])

9.5、长度

list4.append(88888)
print(len(list4))  # list4: [10000, 2, 88888]

9.6、成员运算

print(2 in list4)

9.7、循环:迭代
list7 = [1, 3, 5, 7, 0]
需求:打印1,3,5,7,0

for obj in list7:
    print(obj, end=',')
sss = ""
for obj in list7:
    sss += str(obj) + ','  # obj是int类型,不能直接做字符串拼接,转化成字符串
print('>>>', sss[:-1])

翻转

a = [1, 3, 2]
a.reverse()
print(a)

排序: 前提:1.数据之间全部具有可比性;2:数据要统一类型

b = [1, 3, 2, 5, 4]
b.sort()
print(b)

倒序

b.reverse()
print(b)

b.sort(reverse=True)
print(b)
  1. copy:复制
  2. clear:清空
  3. count:计算成员个数
  4. extend:添加多个值(参数为可迭代对象)
  5. index:查找索引
x = [1, 3, 5, 3]
y = x
print(x, id(x))
print(y, id(y))

z = x.copy()
print(z, id(z))

x[0] = 10000
print(x[0])
print(y[0])
print(z[0])

z.clear()
print(z)

[10000, 3, 5, 3]
print(x.count(3))  # 2

list1 = []
list1.extend('abc')
print(list1)

list2 = ['abc', 'xyz']
list1.extend(list2)
print(list1)

总结

  1. 列表中可以存放多个值
  2. 列表为可变类型:id不变的情况下,可以发生值变化
  3. 列表为有序存储结构:可以通过索引取值

10、元祖类型

空列表,只含一个值(元素,成员)的列表

l1 = []
l2 = [1]
print(l1, l2)

元组:可以理解为,不可变的列表
1.元组的长度不可以变化
2.元组中的值可以变化,但是变化其实是存放了可变的数据类型,元组本质没有改变

定义

t1 = (1, 2, 3, 4, 5)
print(t1)

t2 = tuple((1, 2, 3, 4, 5))
print(t2)

空元组

t3 = ()
print(t3)

t4 = tuple()
print(t4)

含义一个值的元组

t5 = (1, )
print(t5)

t6 = tuple((1, ))
print(t6)

t7 = (5, 3, 2, 1, 6)
print(t7[0])
print(t7[-1])

不可改变: 但一个列表需要对其进行限制,让其无法发生改变,可以将其转化为元组

list1 = [1, 2, 3]
tuple1 = tuple(list1)
print(tuple1)

如果重新想更改,可以转化回去

list2 = list(tuple1)
print(list2)

注:元组中存放了可变类型数据,可以发生形式上的值改变,本质值未发生改变

t1 = (1, 'abc', [10, 'xyz'])
print(t1, id(t1))

成立:元组中列表值发生改变,列表自身id不变,所以元组中的中未发生改变

t1 = (1, 'abc', [10, 'xyz'])
t1[2][1] = 'XYZ'
print(t1, id(t1))

t1[1] = 'ABC'  # 报错:元组中的值不能发生变化(id需要改变)
print(t1, id(t1))

总结

  1. 可以存放多个值:t = (1, 2, 3)
  2. 为不可变类型
  3. 有序存储:按索引取值

11、字典类型

dic1 = {'name': 'Owen', 'age': 18}
dic1 = {'name': None, 'age': None}
print(dic1)

dic2 = dict([('name', 'Egon'), ('age', 58)])
print(dic2)

dic3 = dict(name='Zero', age=18)
print(dic3)

dic4 = {}.fromkeys(['name', 'age'], None)
print(dic4)

11.1、get:有默认值的取值

dic = {'name': 'Owen', 'age': 18}
print(dic.get('name', "该key不存在"))  # 存在就会打印实际的值
print(dic.get('name123', "该key不存在"))  # 不存在,未规定默认值,打印None,规定就打印规定的默认值

11.2、字典的key可以为所以不可变类型,value可以为任意类型
原因:字典的key是取值的唯一途径,所以一定要保证唯一性(一旦确定值,就不会再更改)

d1 = {}.fromkeys([1, 3.14, (1,), '123', True], None)
print(d1)

11.3、增删改查

dic = {'name': 'Hou', 'age': 3}
print(dic)
# 增
dic['gender'] = '哇塞'
print(dic)
# 删
del dic['age']
print(dic)
# 改
dic['name'] = 'DaHou'
print(dic)
# 查
print(dic['name'])

总结

  1. 字典可以存放多个值
  2. 字典为可变类型
  3. 字典是无序存储,用key进行取值
print(1 or 1 and 2)

12、数据类型总结

int
py2存放长整型:long
py3环境,所以整型均由int存储

num1 = -10
num2 = 100000000000000000000000000000000000000000888
print(num1, type(num1))
print(num2, type(num2))

complex

cp = complex(4, 5)
print(cp, type(cp))

float

f = float(3)
print(f, type(f))

bool: 在内存中就是存储0、1

print(True, type(True))  # True 'bool'

isinstance(obj, type) # 判断某对象是否是某类型

print(isinstance(3.14, int))
print(isinstance(True, bool))  # True
print(isinstance(True, int))  # True


res = True
print(type(res) == int)  # False

字符串

# '' ""  """ """
print('good "boy"')

s = ‘hello world!!!’
索引取字符 *

print(s[1])  # 正向索引从0开始
print(s[-4])  # 反向索引从-1开始

切片 *

res = s[6:-3:]  # 顾头不顾尾
print(res)

列表与字符串相互转换 *

res = s.split(' ')
print(res)  # 按空格拆分为list
res = '-'.join(res)
print(res)

替换 ****

ns = s.replace('!', '.')
print(ns)
print(s)
ns = s.replace('!', '.', 1)
print(ns)
ns = s.replace('!!!', '.')
print(ns)

查找子字符串的出现次数 ***

ct = s.count('o', 0, 6)  # sub starIndex endIndex
print(ct, )

字符串的长度 *

print(len(s))

判断是否能转换为int *

print('12'.isdigit())

大小写切换

print('abc'.upper())
print('ABC'.lower())

list: 可变
自身指向的内存空间(地址)不发生改变时,可以改变地址指向的内存空间中的内容
ls = []
print(id(ls))

增删改查

ls.append(1)
ls.append(2)
ls.append(3)
print(ls)
print(id(ls))

插入

ls.insert(len(ls), 4)
print(ls)
ls.insert(0, 0)
print(ls)

del ls[2]
print(ls)
ls = [0, 1, 3, 4, 0, 0]
ls.remove(0)
print(ls)
res = ls.pop(4)
print(ls, res)

翻转

ls.reverse()
print(ls)

排序

ls.sort(reverse=True)
print(ls)

多值添加

ls = [0, 1, 2]
ls.extend('abc')
print(ls)
ls.extend([1, 10, 20, 30])
print(ls)

可以被for循环的类型就叫可迭代类型

for v in 'abc':
    print(v)

for o in [10, 20, 30]:
    print(o)

嵌套

ls = [
    [1, 2, 3],
    [4, 5, 6, [10]],
    'xyz'
]
print(ls)
# 取[1, 2, 3]子list
print(ls[0])
# 取数字5
print(ls[1][1])
print(ls[1][3][0])
# 取字母z
print(ls[2][2])

元组:不可变的list
元组(不可变)与列表(可变)的转化

print(tuple([1, 2, 3]))
print(list((1, 2, 3)))

字典: 没有索引(无序存储),按key取值

dic = {}
print(dic, type(dic))

增删改查

dic['name'] = 'Bob'
print(dic)
dic['name'] = 'Jerry'
print(dic)
del dic['name']
print(dic)
# 按[key]查
# print(dic['name'])  # key不存在就抛异常
# 带默认值取值 *****
dic['name'] = 'Bob'
print(dic.get('name', 'key不存在'))

删除

dic = {
    'name': 'Owen',
    'age': 18,
    'gender': 'God'
}
res = dic.pop('age')
print(res)
print(dic)

从最后删除,返回(k, v)
k, v = dic.popitem()
print(k, v)

dic = {‘name’: ‘Owen’, ‘salary’: ‘66666’, ‘height’: 180}
设置默认值:没有该key添加并设置默认值,如果有,不做操作

dic.setdefault('salary', '88888')
print(dic)
dic['height'] = 185
print(dic)

通过keys初始化字典

dic = dic.fromkeys(('name', 'age', 'gender'), None)  # 通过默认值给None一般省略
print(dic)

13、字典循环

多值更新

dic = {'name': 'Engo', 'salary': 100}
dic.update({'name': "Egon", 'age': 58, 'gender': '未知'})
print(dic)

类列表类型,不能直接通过index取值,但可以被for循环迭代取值

print(dic.keys())
print(dic.values())
print(dic.items())

for k in dic.keys():
    print(k, ":", dic[k])
print('------------------------------------')
for v in dic.values():
    print(v)

print('------------------------------------')
for k, v in dic.items():  # *****
    print(k, v)

a, b, c = [1, 2, 3]
print(c)
a, b, _ = (1, 2, 3)
print(a)

嵌套: JSON

dic = {
    'students': [
        {
            'name': 'Bob',
            'id': 1,
            'gender': '男'
        },
        {
            'name': 'Tom',
            'id': 2,
            'gender': '女'
        }
    ],
    'teachers': []
}
stus = dic['students']  # list
tom_stu = stus[1]  # dic
name = tom_stu['name']
print(name)
print(dic['students'][1]['name'])
print('======================')
for k, v in dic.items():
    # 只遍历学生
    if k == 'students':
        for stu in v:
            for s_k, s_v in stu.items():
                print(s_k, ":", s_v)
            print('--------------')
    if k == 'teachers':
        pass

14、set 集合

无序、无key、无索引集合

set特定:存放数据具有唯一性:去重
应用场景:处理大量有重复信息的数据,对其去重,如果需要取值,将其转化为list

s = set()
print(type(s), s)

s.add('a')
s.add('b')
s.add('a')
s.add('b')
s.add('c')
print(s)

取值, 遍历(set也提供了自身遍历)

ls = list(s)
print(ls)

遍历

for v in s:
    print(v)

多个关系set完成关系运算

py = {'a', 'b', 'c', 'egon'}
ln = {'x', 'y', 'z', 'egon'}

只报python, 反过来Linux

res = py - ln
print(res)
res = ln.difference(py)
print(res)

两个都报了的

res = py & ln
res = py.intersection(ln)
print(res)

只报一门

res = py ^ ln
res = py.symmetric_difference(ln)
print(res)

报名的学生

res = py | ln
res = py.union(ln)
print(res)

15、字符编码

乱码:存和取所采用的编码不一致
编码:ascii,unicode, gbk, gb2312, utf-8
电脑组成:硬盘 - 内存 -(二级缓存、一级缓存、cpu寄存器)- cpu

cpu交互的是用户能识别的数据:字符
硬盘中最终存储的数据:0,1的二进制数据(可以直接转化为电脑能识别的高低电频)

什么是字符编码:将人识别的字符转换计算机能识别的01,转换的规则就是字符编码表

编码表 对应关系

你好 <=> 000010001001010101
好的 <=> 001010001001010000

最早期对应关系:ascii编码表 - 存放的是英文数字与机器二进制的对应关系
数字70对应ascii表,指向的是字母’F’

print(chr(70))  # 'F'
print(ord('f'))  # 102

字符所占字节数

1字节 = 8个二进制位 00000000 ~ 11111111 256个数字 -128 ~ 127

ascii中一个字母或数字占一个字节

中文
GBK: 16个二进制位 15个0到15个1
兼容ascii,一个字母或数字占一个字节
2w多汉字,用两个字节进行存储

你好 <=> 00000101010101001011 <=> 콱봤

日文/韩文:Shift_JIS、Euc-kr

国际上交流:

一条信息中,可能同时出现英文/中文/日文/韩文,将所有信息存储,且不乱码
万国编码表:unicode
unicode采用两个字节存放数据:utf-8,utf-16
utf-8采用变长存储:1字节存放数字与英文,3字节存放汉字
utf-16采用定长存储:均以2字节存放数字,英文,汉字

内存中用utf-16存取数据:定长存取效率高(变长需要计算后才存取)
cpu中与硬盘中,采用utf-8存放数据(utf-8传输更快)

16、三种字符串

原文本字符串数据

# s1 = 'abc123你好'
s1 = u'abc123你好'
print(s1)

二进制字符串数据: 数据传输是以字节为单位,要将原文字符串转换为二进制字符串机械能传输

编码

res = s1.encode('utf-8')
print(res)

解码

s2 = res.decode('utf-8')
print(s2)

ss2 = b'abc123\xe4\xbd\xa0\xe5\xa5\xbd\xe5\xa5\xbd\xe5\xa5\xbd'
print('>>', ss2.decode('utf-8'))

原义字符串数据

s3 = r'你好\n好的'
print(s3)
# s4 = 'D:\\nbpython周末四期\\day03\\代码\\4.三种字符串.py'
# print(s4)
s4 = r'D:\nbpython周末四期\day03\代码\4.三种字符串.py'
print(s4)

17、文件操作基础读写

操作文件的三步骤
1、打开文件

f被程序持有,文件被操作系统持有
f = open('file.txt', 'r', encoding='utf-8')  # r读文件,文件一定要提前存在
del f
f.close()

2、操作文件

data = f.read()  # 读所有内容
print(data)

data = f.read(2)  # 读指定字节数或字符数
print(data)
d1 = f.read(1)  # 在当前位置接着再读1个字节或字符
print(d1)

line = f.readline()  # 读取一行
print(line)

lines = f.readlines()  # 按行,将所有行一次一次读出到list中
print(lines)

3、关闭文件

f.close()  # 操作系统对文件的持有权一定要在文件操作完毕后释放
del f

例子:

w = open(r'file.txt', 'w', encoding='utf-8')
w.write('123\n')
w.flush()  # 数据量过大时,可以手动将内存中的数据刷新到硬盘中
w.write('456\n')
w.writelines(['000\n', '111\n', '222\n'])

是否可读可写

print(w.readable())
print(w.writable())

w.close()

print('end')

18、操作模式

主模式:
r:  文件必须存在的读
w:  文件无需存在的写,无创建,有清空再写
a:  文件无需存在的写,无创建,有在文件最后追加写

从模式:
t:  按文本字符操作数据(默认模式)
b:  按文本字节操作数据
+:  可读可写

了解:
x:新建文件写,如果文件已存在,抛异常

with open语法

with open('file.txt', 'x', encoding='utf-8') as f:  # 不需要明文书写f.close()
    # data = f.read()
    # print(data)
    print(f.readable())
    print(f.writable())

追加模式

with open('file.txt', 'a', encoding='utf-8') as f:
    f.write('123\n')
    print(123)
    print(123)
    f.write('456\n')
    f.flush()
    f.write('789\n')

字节方式操作文件
注:b操作模式下不需要指定encoding,
原因,因为b可以对所有类型数据进行操作,包含文本/视频/音频等各种文件
而utf-8只是文本文件的编码方式
数据在硬盘中本就以二进制进行存储的,所有b默认操作就是对数据从硬盘到内存的拷贝

with open('file.txt', 'rb') as f:
    data = f.read()
    print(data)
    # 但如果数据要展现给用户,文本文件就要涉及解码,其他文件需要通过专业工具打开
    print(data.decode('utf-8'))

with open('file.txt', 'ab') as f:
    f.write(b'\n\xe5\x91\xb5\xe5\x91\xb5')

r+: 从头开始写, a+:从尾开始写, w+:清空写

with open('file.txt', 'rb+') as f:
    print(f.readable())
    print(f.writable())
    # print(f.read())
    f.write(b'999')

19、游标操作

123
你好
456

with open('file.txt', 'w', encoding='utf-8') as f:
    f.write('123\n你好\n456\n')

大前提: 游标操作一定要在b模式下进行操作,因为游标一定按字节进行偏移
seek(偏移量, 操作位置)
操作位置:0,从头开始 1,从当前位置开始 2,从最后开始

with open('file.txt', 'rt', encoding='utf-8') as f:
    d1 = f.read(7)
    print(d1)
    f.seek(1, 0)
    d2 = f.read(1)
    print(d2)

seek()在操作位置为0时,可以兼容t模式,但任然按字节进行偏移

with open('file.txt', 'rb') as f:
    d1 = f.read(14)
    print(d1)
    # f.seek(1, 1)  # 在当前位置往后偏移1个字节
    # f.seek(-1, 1)  # 在当前位置往前偏移1个字节

    f.seek(-3, 2)  # 将鼠标移至到文件末尾,往前偏移3个字节

    d2 = f.read(1)
    print(d2)

20、文件的修改

rb+:在当前位置进行覆盖书写

with open('change.txt', 'rb+') as f:
    f.seek(14, 0)
    print(f.read(2))
    f.seek(-2, 1)
    f.write(b'16')

ab+:可以操作游标,但只对读起作用,写任然是最后追加

with open('change.txt', 'ab+') as f:
    f.seek(14, 0)
    print(f.read(2))
    f.seek(-2, 1)
    print(f.read(2))
    f.write(b'18')
with open('change.txt', 'rb+') as f:
    data = f.read()
    newData = data.decode('utf-8').replace('16', '016')

    f.seek(0, 0)
    f.write(newData.encode('utf-8'))

21、复制文件

with open('old.txt', 'r', encoding='utf-8') as f1, open('new.txt', 'w', encoding='utf-8') as f2:
    # 文件的循环
    for line in f1:  # 对可读文件对象直接遍历循环,得到的是一行行内容
        print(line)
        f2.write(line)

import os
with open('001.png', 'rb') as f1, open('002.png', 'wb') as f2:
    for line in f1:
        f2.write(line)
# 按指定路径将文件删除
os.remove(r'D:\python周末四期\day03\代码\001.png')

22、秒传文件

mk = b""
# 计算得到秒传依据
with open('002.png', 'rb') as f:
    data = f.read()
    # print(data)
    length = len(data)
    print(length)
    # 设置秒传算法:1.截取的部分字节,2.加密字节的算法

    # 1.从头开始读10个字节,中间读10个字节,末尾读10个字节
    # 2.将所有数据进行拼接
    f.seek(0, 0)
    d1 = f.read(10)
    f.seek(length // 2, 0)
    d2 = f.read(10)
    f.seek(-10, 2)
    d3 = f.read(10)
    mk = d1 + d2 + d3

print(mk)

# 实现秒传
with open('200.png', 'rb') as f:
    new_mk = b''
    f.seek(0, 0)
    new_mk += f.read(10)
    f.seek(length // 2, 0)
    new_mk += f.read(10)
    f.seek(-10, 2)
    new_mk += f.read(10)
    if new_mk == mk:
        print('秒传')
    else:
        print('调用上传方法,进行龟速上传')

# with open('200.png', 'rb+') as f:
#     f.seek(-7, 2)
#     f.write(b'12')
文档更新时间: 2019-04-01 17:47   作者:李延召