欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

我的Python之旅第三天

程序员文章站 2022-05-04 15:34:13
一 编码操作 1 编码 enconde() 英文字符编码为"utf-8"时,一个字符占一个字节。 汉字编码为"utf-8"时,一个汉字占三个字节。 汉字编码为"gbk"时,一个汉字占两个字节。 2 解码 deconde() 二 深浅copy 定义: 在Python中对象的赋值其实就是对象的引用。当创 ......

一 编码操作

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', '2345']

(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)图片的读取及写入

原图如下

我的Python之旅第三天

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

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