python编程二编码在使用_Python编程-编码、文件处理、函数

一、字符编码补充知识点

1.文本编辑器存取文件的原理(nodepad++,pycharm,word)

打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失

因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。

在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

2.python解释器执行py文件的原理 ,例如python test.py

第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器

第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中

第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码

755f5c50993ce850917f0ca902066222.png

总结:

(1)python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样

(2)与文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内容

3.python2和python3的区别

(1)在python2中有两种字符串类型str和unicode

(2)在python三种也有两种字符串类型str和bytes

4.encode和decode

字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。

decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。

encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。

二、文件处理

1.文件处理流程

(1)打开文件,得到文件句柄并赋值给一个变量

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

(3)关闭文件

示例:

f = open('chenli.txt') #打开文件

first_line = f.readline()

print('first line:',first_line) #读一行

print('我是分隔线'.center(50,'-'))

data = f.read()# 读取剩下的所有内容,文件大时不要用

print(data) #打印读取内容

f.close() #关闭文件

正确的打开方式

不指定打开编码,默认使用操作系统的编码,windows为gbk,linux为utf-8,与解释器编码无关

f=open('chenli.txt',encoding='gbk') #在windows中默认使用的也是gbk编码,此时不指定编码也行

f.read()

2.文件打开方式

语法:

文件句柄 = open('文件路径', mode='模式')

打开文件的模式有:

r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】

w,只写模式【不可读;不存在则创建;存在则清空内容】

a, 追加模式【可读; 不存在则创建;存在则只追加内容】

"+" 表示可以同时读写某个文件

r+, 读写【可读,可写】

w+,写读【可读,可写】

a+, 写读【可读,可写】

"b"表示以字节的方式操作

rb 或 r+b

wb 或 w+b

ab 或 a+b

注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

3.文件处理示例

(1)上下文管理

with open('a.txt','r',encoding='utf-8') as f,open('b.txt') as b_f:

print(f.read())

print('====>')

(2)以字节码方式打开文件时的操作

with open('a.txt','rb') as f:

print(f.read().decode('utf-8'))

with open('c.txt','wb') as f:

f.write('哈哈哈'.encode('utf-8'))

(3)文本的方式读不了二进制文件

f=open('sb.jpg','r',encoding='utf-8')

print(f.read())

(4)读取多个文件时的书写格式

with open('sb.jpg','rb') as read_f,\

open('sb_alex.jpg','wb') as write_f:

data=read_f.read()

write_f.write(data)

(5)文件操作技巧

seek(offset,where): where=0从起始位置移动,1从当前位置移动,2从结束位置移动。当有换行时,会被换行截断。seek()无返回值,故值为None。

tell(): 文件的当前位置,即tell是获得文件指针位置,受seek、readline、read、readlines影响,不受truncate影响

truncate(n): 从文件的首行首字符开始截断,截断文件为n个字符;无n表示从当前位置起截断;截断之后n后面的所有字符被删除。其中win下的换行代表2个字符大小。

readline(n):读入若干行,n表示读入的最长字节数。其中读取的开始位置为tell()+1。当n为空时,默认只读当前行的内容

readlines读入所有行内容

read读入所有行内容

数字指的是读的是字符

with open('a.txt','r',encoding='utf-8') as f:

print(f.read(4))

with open('a.txt','rb') as f:

print(f.read(1))

seek内指定的数字代表字节

tell指定当前光标所在的位置

with open('a.txt','r',encoding='utf-8') as f:

f.seek(3)

print(f.tell())

print(f.read())

with open('aa.txt','r+',encoding='utf-8') as f:

# f.seek(3)

# print(f.read())

f.truncate(1) #从文件的首行首字符开始截断,截断文件为n个字符

seek的使用方式

with open('b.txt','rb') as f:

f.read()

f.seek(3) #默认情况,是以文件起始位置作为开始,往后移动3个bytes

f.read(1)

print(f.tell())

f.seek(2,1) # 1 代表以当前光标所在的位置为开始,往后移动2个bytes

print(f.tell())

f.seek(-1,2) # 2 代表以结束光标所在的位置为开始,往后移动2个bytes

print(f.tell())

f.seek(0,2)

with open('c.txt','r',encoding='utf-8') as f:

f.seek(0,2)

print('====>',f.read())

补充知识:

(1)tail命令的输出方式

tail -f access.log

import time

with open('access.log','r',encoding='utf-8') as f:

f.seek(0,2)

while True:

line=f.readline().strip()

if line:

print('新增一行日志',line)

time.sleep(0.5)

(2)for循环结合else的用法

当for循环不被break打断,就会执行else的代码

for i in range(3):

print(i)

# continue

if i == 1:

break

else:

print('=============>')

with open('a.txt','r',encoding='utf-8') as read_f,\

open('aa.txt','w',encoding='utf-8') as write_f:

for line in read_f:

write_f.write(line)

else:

print('write successfull')

i=0

while i< 5:

print(i)

i+=1

if i == 3:

break

else:

print('------>')

三、函数

1.没有函数会有什么问题?

(1)无组织无结构,代码冗余

(2)可读性差

(3)无法统一管理且维护成本高

2.函数和过程

过程定义:过程就是简单特殊没有返回值的函数

当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,所以在python中即便是过程也可以算作函数。

def test01():

pass

def test02():

return 0

def test03():

return 0, 10, 'hello', ['alex', 'lb'], {'WuDaLang': 'lb'}

t1 = test01()

t2 = test02()

t3 = test03()

print('from test01 return is [%s]: ' % type(t1), t1)

print('from test02 return is [%s]: ' % type(t2), t2)

print('from test03 return is [%s]: ' % type(t3), t3)

运行结果:

from test01 return is []: None

from test02 return is []: 0

from test03 return is []: (0, 10, 'hello', ['alex', 'lb'], {'WuDaLang': 'lb'})

3.函数分类

(1)内置函数

sum

max

min

a=len('hello')

print(a)

b=max([1,2,3])

print(b)

(2)自定义函数

def print_star():

print('#'*6)

def print_msg():

print('hello world')

print_star()

print_msg()

print_star()

运行结果:

######

hello world

######

4.定义函数

(1)为什么要定义函数?

先定义后使用,如果没有定义而直接使用,就相当于引用了一个不存在的变量名。

foo()

def foo():

print('from foo')

print(foo)

函数定义阶段到底干了什么事情:只检测函数体的语法,并不会执行

(2)函数的使用

函数的使用包含两个阶段:定义阶段和使用阶段

def 函数名(参数1,参数2,...):

"""文档注释"""

函数体

return 值

x=len('hello')

print(x)

(3)定义函数的三种形式

无参数函数

如果函数的功能仅仅只是执行一些操作而已,就定义成无参函数,无参函数通常都有返回值

def print_star():

print('#'*6)

有参函数

函数的功能的执行依赖于外部传入的参数,有参函数通常都有返回值

def my_max(x,y):

res=x if x >y else y

return res

空函数

def auth():

"""认证功能"""

pass

auth()

5.函数参数

(1)函数的参数分类

形参(变量名),实参(值)

形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

(2)详细的区分函数的参数(五类)

1)位置参数

def foo(x,y,z): #位置形参:必须被传值的参数

print(x,y,z)

foo(1,2,3) #位置实参数:与形参一一对应

2)关键字参数:key=value

def foo(x,y,z):

print(x,y,z)

foo(z=3,x=1,y=2)

关键字参数需要注意的问题:

1:关键字实参必须在位置实参后面

foo(1,x=1,y=2,z=3)

2: 不能重复对一个形参数传值

foo(1,z=3,y=2) #正确

foo(x=1,2,z=3) #错误

3)默认参数

def register(name,age,sex='male'): #形参:默认参数

print(name,age,sex)

register('asb',age=40)

register('a1sb',39)

register('a2sb',30)

register('a3sb',29)

register('钢蛋',20,'female')

register('钢蛋',sex='female',age=19)

默认参数需要注意的问题:

默认参数必须跟在非默认参数后

def register(sex='male',name,age): #在定义阶段就会报错

print(name,age,sex)

默认参数在定义阶段就已经赋值了,而且只在定义阶段赋值一次

a=100000000

def foo(x,y=a):

print(x,y)

a=0

foo(1)

默认参数的值通常定义成不可变类型

4)可变长参数

第一种:*args

*会把溢出的按位置定义的实参都接收,以元组的形式赋值给args

def foo(x,y,*args):

print(x,y)

print(args)

foo(1,2,3,4,5)

运行结果:

1 2

(3, 4, 5)

def add(*args):

res=0

for i in args:

res+=i

return res

print(add(1,2,3,4))

print(add(1,2))

运行结果:

10

3

第二种:**kwargs

**会把溢出的按关键字定义的实参都接收,以字典的形式赋值给kwargs

def foo(x, y, **kwargs):

print(x, y)

print(kwargs)

foo(1,2,a=1,name='egon',age=18)

运行结果:

1 2

{'a': 1, 'name': 'egon', 'age': 18}

def foo(name,age,**kwargs):

print(name,age)

if 'sex' in kwargs:

print(kwargs['sex'])

if 'height' in kwargs:

print(kwargs['height'])

foo('egon',18,sex='male',height='185')

foo('egon',18,sex='male')

运行结果:

egon 18

male

185

egon 18

male

5)命名关键字参数

*后定义的参数为命名关键字参数,这类参数,必须被传值,而且必须以关键字实参的形式去传值

def foo(name,age,*,sex='male',height):

print(name,age)

print(sex)

print(height)

foo('egon',17,height='185')

运行结果:

egon 17

male

185

6.综合使用

def foo(name,age=10,*args,sex='male',height,**kwargs):

print(name)

print(age)

print(args)

print(sex)

print(height)

print(kwargs)

foo('alex',1,2,3,4,5,sex='female',height='150',a=1,b=2,c=3)

运行结果:

alex

1

(2, 3, 4, 5)

female

150

{'a': 1, 'c': 3, 'b': 2}

def foo(*args):

print(args)

foo(1,2,3,4)

*['A','B','C','D'],=====>'A','B','C','D'

foo(*['A','B','C','D']) #foo('A','B','C','D')

foo(['A','B','C','D'])

def foo(x,y,z):

print(x,y,z)

# foo(*[1,2,3]) #foo(1,2,3)

foo(*[1,2]) #foo(1,2)

def foo(**kwargs):

print(kwargs)

#x=1,y=2 <====>**{'y': 2, 'x': 1}

# foo(x=1,y=2)

foo(**{'y': 2, 'x': 1,'a':1}) #foo(a=1,y=2,x=1)

def foo(x,y,z):

print(x,y,z)

# foo(**{'z':3,'x':1,'y':2}) #foo(x=1,z=3,y=2)

foo(**{'z':3,'x':1}) #foo(x=1,z=3)

def foo(x,y,z):

print('from foo',x,y,z)

def wrapper(*args,**kwargs):

print(args)

print(kwargs)

wrapper(1,2,3,a=1,b=2)

def foo(x,y,z):

print('from foo',x,y,z)

def wrapper(*args,**kwargs):

print(args) #args=(1,2,3)

print(kwargs) #kwargs={'a':1,'b':2}

foo(*args,**kwargs) #foo(*(1,2,3),**{'a':1,'b':2}) #foo(1,2,3,b=2,a=1)

# wrapper(1,2,3,a=1,b=2)

wrapper(1,z=2,y=3)

def foo(x,y,z):

print('from foo',x,y,z)

def wrapper(*args,**kwargs):

# print(args) #args=(1,)

# print(kwargs) #kwargs={'y':3,'z':2}

foo(*args,**kwargs) #foo(*(1,),**{'y':3,'z':2}) #foo(1,z=2,y=3)

# wrapper(1,2,3,a=1,b=2)

wrapper(1,z=2,y=3)

7.函数的返回值

def foo():

print('from foo')

return None

res=foo()

print(res)

运行结果:

from foo

None

以下三种情况返回值都为None:

(1)没有return

(2)return 什么都不写

(3)return None

return为一个值时,函数调用返回的结果就是这个值

def foo():

print('from foo')

x=1

return x

res=foo()

print(res)

运行结果:

from foo

1

return 值1,值2,值3,... 返回结果:(值1,值2,值3,...)

def foo():

print('from foo')

x=1

return 1,[2,3],(4,5),{}

res=foo()

print(res)

a,b,c,d=foo()

print(d)

运行结果:

from foo

(1, [2, 3], (4, 5), {})

from foo

{}

参数取值

t=(1,2,3)

a,_,_=t

print(a)

t=(1,2,3,4,5,6,7,8,9)

a,*_,c=t

print(a)

print(c)

运行结果:

1

1

9

8.函数调用

按照有参和无参可以将函数调用分两种

foo() #定义时无参,调用时也无需传入参数

bar('egon') #定义时有参,调用时也必须有参数

def foo():

print('from foo')

def bar(name):

print('bar===>',name)

按照函数的调用形式和出现的位置,分三种

#调用函数的语句形式

foo()

#调用函数的表达式形式

def my_max(x,y):

res=x if x >y else y

return res

res=my_max(1,2)*10000000

print(res)

#把函数调用当中另外一个函数的参数

res=my_max(my_max(10,20),30)

print(res)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
费诺编码(Huffman coding)是一种无损数据压缩算法,它利用每个字符出现的频率来生成一种最优的前缀编码。下面是一个简单的Python实现: ```python import heapq from collections import defaultdict def huffman_encoding(data): # 统计字符出现频率 freq = defaultdict(int) for c in data: freq[c] += 1 # 构建 Huffman 树 heap = [[f, [c, ""]] for c, f in freq.items()] heapq.heapify(heap) while len(heap) > 1: lo = heapq.heappop(heap) hi = heapq.heappop(heap) for pair in lo[1:]: pair[1] = '0' + pair[1] for pair in hi[1:]: pair[1] = '1' + pair[1] heapq.heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:]) # 生成编码表 code_table = dict(heapq.heappop(heap)[1:]) # 生成编码结果 encoded_data = ''.join([code_table[c] for c in data]) return encoded_data, code_table def huffman_decoding(encoded_data, code_table): # 反转编码表 inverse_table = {v: k for k, v in code_table.items()} # 解码 decoded_data = "" code = "" for bit in encoded_data: code += bit if code in inverse_table: decoded_data += inverse_table[code] code = "" return decoded_data ``` 在上面的代码中,`huffman_encoding()` 函数用于对输入的 `data` 进行编码,返回编码后的数据和编码表;`huffman_decoding()` 函数用于对编码后的数据进行解码,需要传入编码表。这两个函数使用了一个辅助函数 `heapq` 进行最小堆的操作。 下面是一个使用示例: ```python data = "hello world" encoded_data, code_table = huffman_encoding(data) decoded_data = huffman_decoding(encoded_data, code_table) print("原始数据:", data) print("编码结果:", encoded_data) print("编码表:", code_table) print("解码结果:", decoded_data) ``` 输出结果为: ``` 原始数据: hello world 编码结果: 101111001001010010110100011011100100 编码表: {'h': '1010', 'e': '111', 'l': '01', 'o': '001', ' ': '0011', 'w': '1001', 'r': '000', 'd': '1101'} 解码结果: hello world ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值