一 编码操作

1 编码 enconde()

英文字符编码为"utf-8"时,一个字符占一个字节。

s1='abcdef'
b1=s1.encode('utf-8')
print(b1)
结果为:b'abcdef'

汉字编码为"utf-8"时,一个汉字占三个字节。

汉字编码为"gbk"时,一个汉字占两个字节。

s2='中国'
b2=s2.encode('utf-8')
b3=s2.encode('gbk')
print(b2)
print(b3)
结果为:
b'\xe4\xb8\xad\xe5\x9b\xbd'
b'\xd6\xd0\xb9\xfa'

2 解码 deconde()

s4="你好"
b4=s4.encode('utf-8')
b5=b4.decode('utf-8')
print("'你好'编码为'utf-8'后为:",b4)
print("解码后为:",b5)
b6=s4.encode('gbk')
b7=b6.decode('gbk')
print("'你好'编码为'gbk'后为:",b6)
print("解码后为:",b7)
结果为:
'你好'编码为'utf-8'后为: b'\xe4\xbd\xa0\xe5\xa5\xbd'
解码后为: 你好
'你好'编码为'gbk'后为: b'\xc4\xe3\xba\xc3'
解码后为: 你好

二 深浅copy

定义:

在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。

浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制

深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。

1 浅copy

(1)浅copy 第一层各自独立,从第二层开始,共用一个内存地址。

s1=[1,2,3]
s2=s1
print(s1,s2)
s1.append(666)
print(s1)
print(s2)
print(id(s1))
print(id(s2))

结果为:

[1, 2, 3] [1, 2, 3]
[1, 2, 3, 666]
[1, 2, 3, 666]
2670563612488
2670563612488

可以看到s1、s2的内存地址是一样的,既就是s2为s1的一个引用而已。

(2)

s3=[1,2,3,[44,55]]
s4=s3.copy()
s3[-1].append(666)
print(s3)
print(s4)
print(id(s3[-1]))
print(id(s4[-1]))

结果为:

[1, 2, 3, [44, 55, 666]]
[1, 2, 3, [44, 55, 666]]
1781567379272
1781567379272

2深copy

import copy
s5=[1,2,3,[44,55]]
s6=copy.deepcopy(s5)
s5.append(666)
print(s5)
print(s6)
print(id(s5))
print(id(s6))

结果为:

[1, 2, 3, [44, 55], 666]
[1, 2, 3, [44, 55]]
1774773104968
1774773106248

可以看到s5、s6的内存地址是不一样的。

对于深copy来说,两个是完全独立的,改变任意一个的元素(无论是多少层),另一个绝不会改变。

总结:

(1)深浅拷贝都是对源对象的复制,占用不同的内存空间。

(2)不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。

(3)可变类型:

=浅拷贝: 值相等,地址相等

copy浅拷贝:值相等,地址不相等

deepcopy深拷贝:值相等,地址不相

三 文件操作

操作系统读写文件的一般流程:

(1)打开文件,产生文件句柄。

(2)对文件句柄进行操作。

(3)关闭文件句柄

文件句柄

在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄(file handle),该文件句柄对于打开的文件是唯一的识别依据。要从文件中读取一块数据,应用程序需要调用函数ReadFile,并将文件句柄在内存中的地址和要拷贝的字节数传送给操作系统。当完成任务后,再通过调用系统函数来关闭该文件。

1 读 r

(1)全部读出来read()

f1=open('log.txt',encoding='utf-8')
content=f1.read()
print(content)
f1.close()
结果为:

abcde
fghigk
lmnopq

(2)读一部分 read(n)

f2=open('test.txt',encoding='utf-8')
print(f2.read(3))
f2.close()
结果为:你好五
f3=open('test.txt','rb')
print(f3.read(3).decode('utf-8'))
f3.close()
结果为:你

说明:

r 模式 read(n) n 按照字符读取。

rb 模式 read(n) n 按照字节读取

(3)按行读取 readline()

f4=open('test.txt',encoding='utf-8')
print(f4.readline())
print(f4.readline())
f4.close()
结果为:
你好五月
第二行1abcdefghijklmnopqrstuvwxyz

(4)readlines() 读取所有行,并存入列表中

f5=open('test.txt',encoding='utf-8')
print(f5.readlines())
f5.close()
结果为:
['你好五月\n', '第二行1abcdefghijklmnopqrstuvwxyz\n', '']

(5)for 循环逐行读取

f6=open('test.txt',encoding='utf-8')
for line in f6:
print(line)
f6.close()

结果为:

你好五月

第二行1abcdefghijklmnopqrstuvwxyz

2345

(6)读写 r+ ,先读后写

f7=open('test.txt','r+',encoding='utf-8')
print("原始文件为:",f7.read())
f7.write('aaaa')
f7.seek(0)
print("修改后文件为:",f7.read())
f7.close()

结果为:

原始文件为: 你好五月
第二行1abcdefghijklmnopqrstuvwxyz
2345
修改后文件为: 你好五月
第二行1abcdefghijklmnopqrstuvwxyz
2345aaaa

注意:

如果是Windows系统文件,加路径读取方式如下

f1=open(r'D:\Python\python\day03\test.txt',,encoding='utf-8')

2 写 w

(1)w 如没有文件,新建文件写入内容

有原文件,先清空内容,在写入新内容

f1=open('test2.txt','w',encoding='utf-8')
f1.write('这个世界很疯狂')
f1.close()

写入完毕,下来读取文件

f1=open('test2.txt',encoding='utf-8')
print(f1.read())
f1.close()
结果为:这个世界很疯狂

(2)图片的读取及写入

原图如下

先来读取图片、目前读取二进制文件内容

p1=open('girl.jpg','rb')
content = p1.read()
print(content)
p1.close()
结果为:b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xdb\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\x08\x06\x06\x05\x06\t\x08\n\n\t\x08\t\t\n\x0c\x0f\x0c\n\x0b\x0e\x0b\t\t\r\x11\r\x0e\x0f\x10\x10\x11\x10\n\x0c\x12\x13\x12\x10\x13\x0f\x10\x10\x10\xff\xdb\x00C\x01\x03\x03\x03\x04\x03\x04\x08\x04\x04\x08\x10\x0b\t\x0b\x10\x10
\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x………………….

写入,也是用二进制编码写入

p1=open('girl.jpg','rb')
content = p1.read()
print(content)
p2 = open('girl2.jpg', 'wb')
p2.write(content)
p1.close()
p2.close()

(3)w+先写后读

f2=open('log2.txt','w+',encoding='utf-8')
f2.write('我在测试先写后读')
f2.seek(0)
print(f2.read())
f2.close()
结果为:我在测试先写后读

(4)a 没有文件则新建文件并写入,有的话直接追加

a附加写方式打开,不可读

先追加

f3=open('log3.txt','a',encoding='utf-8')
f3.write('今天是周一\n')
f3.seek(0)
f3.close()

在读取

f4=open('log3.txt',encoding='utf-8')
print(f4.read())
f4.close()
结果为:今天是周一

(5)a+: 附加读写方式打开

f5=open('log4.txt','a+',encoding='utf-8',)
f5.write('我在测试a+模式')
f5.seek(0)
print(f5.read())
f5.close()
结果为:我在测试a+模式

(6)其他操作方法

# readable 是否可读

# writable 是否可写

# f1.seek(12) # 任意调整

# f1.seek(0,2) #光标调整到最后

# f1.seek(0) #光标调整到开头

# f1.tell() # 告诉光标的位置

# f1.truncate(3) # 按照字节对原文件进行截取 必须在a 或 a+ 模式

(7)不用主动关闭文件句柄

with open('log.txt',encoding='utf-8') as f6:
print(f6.read())
结果为:
abcde
fghigk
lmnopq
rstuvwxy

当然也可一次操作多个文件

with open('log.txt',encoding='utf-8') as f6,\
open('log3.txt','a+',encoding='utf-8') as f7:
print(f6.read())
f7.write('文件句柄测试')
f7.seek(0)
print(f7.read())

结果为:

abcde
fghigk
lmnopq
rstuvwxy 今天是周一
今天是周一
文件句柄测试

3 改

(1)以读模式打开原文件。

(2)以写的模式打开一个新文件。

(3)将原文件读出按照要求修改将修改后的内容写入新文件。

(4)删除原文件。

(5)将新文件重命名原文件。

import os
with open('file', encoding='utf-8') as f1,\
open('file.bak', encoding='utf-8', mode='w') as f2:
old_content = f1.read()
new_content = old_content.replace('abc', 'hhh')
f2.write(new_content) os.remove('file')
os.rename('file.bak', 'file')

#升级版本

import os
with open('file', encoding='utf-8') as f1,\
open('file.bak', encoding='utf-8', mode='w') as f2:
for line in f1:
new_line = line.replace('abc','hhh')
f2.write(new_line) os.remove('file')
os.rename('file.bak', 'file')

四 初识函数

1 函数的定义

(1)什么是函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。

你已经知道Python提供了许多内建函数,比如print()。

但你也可以自己创建函数,这被叫做用户自定义函数。

(2)定义函数:

def 关键字 函数名():
函数体
函数执行:函数名()
函数:以功能为导向
s = 'asdgagsgadsgag'
def my_len():
count = 0
for i in s:
count += 1
print(count)
print(my_len())

2 函数的终止与返回值

(1)终止函数。

(2)给函数的执行者返回值。

return 或者 return None

return 单个值

return 多个值 会将多个值放到一个元组中,将元组返回个函数的执行者

3 函数的传参

(1)认识实参、形参

def my_len(argv): # 形式参数 ,形参
count = 0
for i in argv:
count += 1
return count s = 'lkfjsjulkjdgjdsf'
l1 = [1, 2, 3, 4, 5]
my_len(s) # 实际参数, 实参
print(my_len(l1))
  1. 实参角度

    位置参数 按照顺序一一对应

    关键字传参 一一对应

    混合参数,(位置参数,关键字参数) 关键字参数必须在位置参数后面。

  2. 形参角度

    位置参数,按顺序一一对应。

    默认参数, 默认参数在位置参数的后面。

    动态参数, *args, **kwargs 万能参数。

    所有的位置参数,放在一个元组中。

    所有的关键字参数,放在一个字典中。

  3. 形参的顺序

    位置参数 *args, 默认参数,**kwargs