Day 03 :字符编码详解和文件详解

1. is == id

1.1 is:比较的是内存地址

1.2 == :比较的是值

1.3 id:测试对象内存地址

a = 'abc'

b = 'abc'

print(a == b) # True

print(a is b) # True

print(id(a),id(b))

 

1.4 小数据池 int str

小数据池存在的意义就是节省空间

1.4.1 int:-5 -- 256
a = 123 b = 123 c = 123

print)(id(a),id(b),id(c)) # id一样
1.4.2 str:

1. 不能含有特殊字符

2. 单个因素*int不能超过21

 

2. 字符编码

2.1 了解字符编码的知识储备

2.1.1 计算机基础知识

 

 

 

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

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

2)要想永久保存,需要点击保存按钮:编辑器把内存的数据刷到了硬盘上。

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

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

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

第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中(小复习:pyhon的解释性,决定了解释器只关心文件内容,不关心文件后缀名)

第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码( ps:在该阶段,即真正执行代码时,才会识别python的语法,执行文件内代码,当执行到name="egon"时,会开辟内存空间存放字符串"egon")

2.1.4 总结python解释器与文件本编辑的异同

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

不同点:文本编辑器将文件内容读入内存后,是为了显示或者编辑,根本不去理会python的语法,而python解释器将文件内容读入内存后,可不是为了给你瞅一眼python代码写的啥,而是为了执行python代码、会识别python语法。

2.2 字符编码

2.2.1 ASCII

ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,其最多只能用 8 位来表示(一个字节),即:2**8 = 256,所以,ASCII码最多只能表示 256 个符号。

 

 

 

2.2.2 Unicode

显然ASCII码无法将世界上的各种文字和符号全部表示,所以,就需要新出一种可以代表所有字符和符号的编码,即:Unicode

Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,规定虽有的字符和符号最少由 16 位来表示(2个字节),即:2 **16 = 65536,

注:改版前由16位表示一个字符,改变后由32位表示一个字符,非常浪费资源。

2.2.3 UTF-8

UTF-8,是对Unicode编码的压缩和优化,他不再使用最少使用2个字节,而是将所有的字符和符号进行分类:ascii码中的内容用1个字节保存、欧洲的字符用2个字节保存,东亚的字符用3个字节保存。目前公认最好的编码方式就是UTF-8。

2.2.4 GBK

GBK是国标,只识别中文和英文,采用单双字节编码,英文使用单字节编码,完全兼容ASCII,中文部分采用双字节编码。

2.2.5 单位转化

8bit  = 1bytes

1024bytes = 1kb

1024kb = 1mb

1024mb = 1GB

1024GB = 1TB

2.3 Python3下的编码转化

2.3.1 python3环境下

1、不同编码之间的二进制是不能互相识别的;

2、python3,str内部编码方式(内存)为unicode。

3、对于文件的存贮和传输不能用unicode,bytes类型内部编码方式,为非unicode

2.3.2 str与bytes的表现形式

# str表现形式,内部编码方式:unicode

s1 = 'hello'

# bytes表现形式,内部编码方式:非unicode(utf-8,gbk....)

s2 = b'hello'

# 对于英文

s1 = 'hello'

print(s1, type(s1)) # hello <class 'str'>

s2 = b'hello'

print(s2, type(s2)) # b'hello' <class 'bytes'>

# 对于中文

s = '你好'

print(s, type(s)) # 你好 <class 'str'>

print(s.encode('utf-8')) # b'\xe4\xbd\xa0\xe5\xa5\xbd'

# s1=b'\xe4\xbd\xa0\xe5\xa5\xbd'

print(s1, type(s1)) # b'\xe4\xbd\xa0\xe5\xa5\xbd' <class 'bytes'>

 

2.3.4 编码转化:str 转化成 bytes
# str(英文)转化 bytes

s = 'hello'

s2 = s.encode('utf-8')

s3 = s.encode('gbk')

print(s2, type(s2)) # >>>b'hello' <class 'bytes'>

print(s3, type(s3)) # >>>b'hello' <class 'bytes'>

# str(中文)转化 bytes

s = '你好'

s2 = s.encode('utf-8') # 一个中文三个字节

s3 = s.encode('gbk') # 一个中文两个字节

print(s2, type(s2)) # b'\xe4\xbd\xa0\xe5\xa5\xbd' <class 'bytes'>

print(s3, type(s3)) # b'\xc4\xe3\xba\xc3' <class 'bytes'>

 

2.3.5 解码:bytes 转化成str
s = '你好'

s1 = s.encode('utf-8') # 一个中文三个字节

s2 = s.encode('gbk') # 一个中文两个字节

s3 = s1.decode('utf-8')

s4 = s2.decode('gbk')

print(s3, type(s3)) # >>>你好 <class 'str'>

print(s4, type(s4)) # >>>你好 <class 'str'>

 

2.3.6 编码方式补充:
unicode - --> bytes

encode()

bytes - --> unicode

decode()

# 将gbk的bytes类型转化为utf-8的bytes类型

s1 = b'\xd6\xd0\xb9\xfa'

s2 = s1.decode('gbk')

s3 = s2.encode('utf-8')

print(s2) # 中国

print(s3) # b'\xe4\xb8\xad\xe5\x9b\xbd'

# 简化

s1 = b'\xd6\xd0\xb9\xfa'.decode('gbk').encode('utf-8')

print(s1) # b'\xe4\xb8\xad\xe5\x9b\xbd'

3. 集合

集合里面的元素无序,不重复,可哈希类型,本身是不可哈希类型。

集合是无序的,没有索引,不能改,只能‘增删查’

1. 关系测试,交集,并集,子集,差集

2. set 列表自动去重

3.1 集合的增

3.1.1 直接增加 无序 add()
set1 = {'lily', 'Lucy'}

set1.add('lucas')

print(set1) # {'Lucy', 'Lily', 'Lucas'}

3.1.2 迭代的增 update()

set1 = {'lily', 'Lucy'}

set1.update('Lucas')

print(set1) # {'c', 'L', 'lily', 'Lucy', 'a', 's', 'u'}

3.2 集合的删

3.2.1 pop() # 随机删除
set1 = {'lily', 'Lucy'}

set1.pop() # 随机删除

print(set1) # {'lily'}
3.2.2 remove # 按元素删除,不存在会报错
set1 = {'lily', 'Lucy'}

set1.remove('Lucy')

print(set1) # {'lily'}
3.2.3 clear() #清空
set1 = {'lily', 'Lucy'}

set1.clear()

print(set1) # set()
3.2.4 del() # 整个集合
set1 = {'lily', 'Lucy'}

del(set1)

print(set1) # NameError: name 'set1' is not defined

3.3 集合的查

# for循环

set1 = {'lily', 'Lucy'}

for i in set1:

print(i)

3.4 关系测试

3.5.1 交集 & intersection
set1 = {1,2,3,4,5}

set2 = {5,6,7,8,9}

print(set1 & set2) # {5}

print(set1.intersection(set2)) # {5}
3.5.2 并集 | union
set1 = {1,2,3,4,5}

set2 = {5,6,7,8,9}

print(set1 | set2) # {1, 2, 3, 4, 5, 6, 7, 8, 9} 自动去重 5

print(set1.union(set2)) # {1, 2, 3, 4, 5, 6, 7, 8, 9} 自动去重 5
3.5.3 差集 -:减号 different
set1 = {1,2,3,4,5}

set2 = {5,6,7,8,9}

print(set1 - set2) # {1, 2, 3, 4}

print(set1.difference(set2)) # {1, 2, 3, 4}
3.5.4 反交集 ^ symmetric_difference
set1 = {1,2,3,4,5}

set2 = {5,6,7,8,9}

print(set1 ^ set2) # {1, 2, 3, 4, 6, 7, 8, 9}

print(set1.symmetric_difference(set2)) # {1, 2, 3, 4, 6, 7, 8, 9}
3.5.5 子集 > issubset
set1 = {1,2,3,4,5}

set2 = {1,2}

print(set2 < set1) # True

print(set2.issubset(set1)) # True # set1 是 set2 的子集
3.5.6 超集 > issuperset
set1 = {1,2,3,4,5}

set2 = {1,2}

print(set1 > set2) # True

print(set1.issuperset(set2)) # True # set1 是 set2 的超集
3.6 frozenset 不可变集合,让集合变成不可变类型
s = frozenset('abc')

s1 = frozenset({4,5,6,7,8})

print(s,type(s)) # frozenset({'b', 'a', 'c'}) <class 'frozenset'>

print(s1,type(s1)) # frozenset({4, 5, 6, 7, 8}) <class 'frozenset'>

4. 深浅copy

4.1 先看赋值运算

l1 = [1, 2, 3, ['barry', 'alex']


l2 = l1

l1[0] = 111

print(l1) # [111, 2, 3, ['barry', 'alex']]

print(l2) # [111, 2, 3, ['barry', 'alex']]


l1[3][0] = 'wusir'

print(l1) # [111, 2, 3, ['wusir', 'alex']]

print(l2) # [111, 2, 3, ['wusir', 'alex']]

# 对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的。

4.2 浅拷贝 copy

4.2.1 浅拷贝 copy
l1 = [1, 2, 3, ['barry', 'alex']]


l2 = l1.copy()

print(l1, id(l1)) # [1, 2, 3, ['barry', 'alex']] 2380296895816

print(l2, id(l2)) # [1, 2, 3, ['barry', 'alex']] 2380296895048

l1[1] = 222

print(l1, id(l1)) # [1, 222, 3, ['barry', 'alex']] 2593038941128

print(l2, id(l2)) # [1, 2, 3, ['barry', 'alex']] 2593038941896


l1[3][0] = 'wusir'

print(l1, id(l1[3])) # [1, 2, 3, ['wusir', 'alex']] 1732315659016

print(l2, id(l2[3])) # [1, 2, 3, ['wusir', 'alex']] 1732315659016


# 对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以,对于第二层以及更深的层数来说,保持一致性。
4.2.2 切片 浅copy
s1 = [1, 2, 3, [11, 22]]

s2 = s1[:]

# s1.append(666)

s1[-1].append(666)

print(s1) # [1, 2, 3, [11, 22, 666]]

print(s2) # [1, 2, 3, [11, 22, 666]]

 

4.3 深拷贝 deepcopy

import copy
 

l1 = [1, 2, 3, ['barry', 'alex']]

l2 = copy.deepcopy(l1)
print(l1, id(l1)) # [1, 2, 3, ['barry', 'alex']] 2915377167816 print(l2, id(l2)) # [1, 2, 3, ['barry', 'alex']] 2915377167048 l1[1] = 222 print(l1, id(l1)) # [1, 222, 3, ['barry', 'alex']] 2915377167816 print(l2, id(l2)) # [1, 2, 3, ['barry', 'alex']] 2915377167048 l1[3][0] = 'wusir' print(l1, id(l1[3])) # [1, 222, 3, ['wusir', 'alex']] 2915377167240 print(l2, id(l2[3])) # [1, 2, 3, ['barry', 'alex']] 2915377167304 # 无论多少层,都是各自独立

5. 文件操作

计算机系统分为:计算机硬件,操作系统,应用程序三部分。

我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知,应用程序是无法直接操作硬件的,这就用到了操作系统。操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的数据永久保存下来。

有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程:

文件路径path: d:...

编码方式encoding: gbk、utf-8

操作方式mode:读、写、读写、写读、追加、改

open函数中模式参数的常用值:

open('文件路径')    默认的打开方式‘r’,默认的打开的编码是操作系统的默认编码

r  :读模式

w :写模式

a :追加模式

b :二进制模式(可添加到其他模式中使用)

+ :读/写模式((可添加到其他模式中使用)

备注:

1)一般来说,python默认处理的是文本文件。但是处理一些其他类型的文件(二进制文件),比如声音剪辑或者图像,那么可以使用‘b’模式来改变处理文件的方法。参数‘rb’可以用来读取一个二进制文件。

2)在实际工作过程中,很少遇到又读又写的事情,尽量不要使用‘+’模式,在python3里的文件指针非常乱,读写的时候占用两个不同的指针,所以很容易产生问题

文件操作过程:

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

f1 = open(r'D:\Python\Day 03 字符编码&文件操作&函数\test.txt', encoding = 'gbk', mode = 'r') # 开头‘r’代表元素字符串的意思,代表‘\’

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

data = f1.read()

3.关闭文件

f1.close()

f1为python的变量,保存的文件内容,程序结束才能又python自动回收,文件关闭后不能在对文件进行读写

f1为文件句柄或文件对象,可以设置变量名:file,f_handle,file_handle,f_obj

open():调用的内置函数,内置函数调用的系统内部的open

一切对文件进行的操作都是基于文件句柄f1

close():关闭文件,回收操作系统资源(不关闭会在内存中一直存在,切记)

windows 的默认编码方式gbk,linux默认编码方式utf-8,max系统为utf-8

报错原因:

1、编码错误。

编码不一致:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 0: invalid continuation byte

2、路径错误。

SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

解决办法:

1、路径前加r,对路径中“\”进行转义

2、路径中“\”,前加“\”进行转义

 

5.1 文件的读

pycharm 创建的文件默认都是utf-8 notepad++默认也是utf-8,但是可以修改编码方式,在格式菜单下修改

EncodeDecodeErrot:编码错误

读操作:r模式:默认是rt文本读

rb模式:二进制模式,非文字类的文件操作

f1 = open(r'd:\test.txt', encoding = 'gbk',)

print(f1.read())

f1.close()
5.11:read()   文件内容全部读出

read()  不传参数 意味着读所有

      传参,如果是r方式打开的,参数指的是读多少个字符

      传参,如果是rb方式打开的,参数指的是读多少个字节

f1 = open('1.jpg', mode = 'rb') # rb 模式不用谢encoding,它是以bytes类型进行读取

tada1 = f1.read()

print(tada1) # b'\xe6\x88\x91\xe7\x88'

tada2 = f1.read() # 因为读文件有光标移动,第一次读之后,光标移动到最后,第二次读的时候读不到任何内容

print(tada2)

f1.close() # b''
5.12 read(n) 读一部分

r模式,按照字符读取 ; rb模式,按照字节读取

f1 = open(r'test', encoding = 'utf-8') # r 模式,按照字符读取

print(f1.read(5)) # 我爱北京天

f1.close()

f1 = open('test', mode = 'rb') # rb模式,按照字节读取

print(f1.read(5)) # b'\xe6\x88\x91\xe7\x88'

f1.close()

 

unicode - --> bytes encode()

bytes - --> unicode decode()

f1 = open('test', mode = 'rb')

data = f1.read(6) # 写2个字节报错,必须与中文对应位数

print(data.decode('utf-8')) # 我爱 # rb模式,按照字节读取

f1.close()
5.13 readline() 一行一行的读
readline()   一行一行读 每次只读一行,不会自动停止

f1 = open('test', encoding ='utf-8')

print(f1.readline(), end = '') # end可以取消print的换行效果

print(f1.readline())

print(f1.readline())

f1.close()
5.1.4 readlines()  将每一行作为列表的元素,并返回这个列表(不常用)

readlines() 将每一行作为列表的元素,并返回这个列表

在文件比较小的时候可以用read和readlines读取,文件过大时,不建议使用这两种方式

f1 = open('test', encoding= 'utf-8', )

print(f1.readlines())

f1.close()

  f1 = open('1.jpg', mode = 'rb')


  print(f1.readline())


  f1.close()


5.15 for循环

for循环 一行一行读 从第一行开始 每次读一行 读到没有之后就停止

f1 = open('test', encoding= 'utf-8') # f1 这个文件句柄是迭代器,在内存当中只占一行的内存,for循环读取时,永远只在内存当中占一行

for line in f1:

print(line)

f1.close()

 

f1 = open('test', mode = 'rb')

for line in f1:

print(line)

f1.close()
5.16 while循环
with open(b'test', 'r', encoding='utf-8') as f:

while True:

line = f.readline()

if len(line) == 0: break

print(line)

5.2 文件的写

写操作:只能写字符串格式的,不能写数字

W模式:默认是WT文本写

如果文件不存在,新建文件写入内容;

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

5.2.1 write()

# 没有文件,新建文件,创建内容

f1 = open('test2', encoding = 'utf-8', mode = 'w')

f1.write('我在中国,北京,沙河')

f1.close() # 我在中国,北京,沙河

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

f1 = open('test2', encoding = 'utf-8', mode = 'w')

f1.write('我是女生,可爱的女生')

f1.close() # 我是女生,可爱的女生

# 图片的读取及写入

f1 = open('1.jpg', mode = 'rb')

content = f1.read() # 将f1 读出来的内容赋给 content

f2 = open('2.jpg', mode = 'wb')

f2.write(content) # 在f2 中写入content(f1中读取出来的内容 )

f1.close()

f2.close()
5.2.2 writeline()
f=open('a.txt','w',encoding='utf-8')

f.writelines(['哈哈哈\n','hello','world']) # 哈哈哈 helloworld

f.close()
5.2.3 writable 判断文件是否可写
f = open('test', 'w', encoding = 'utf-8')

print(f.writable()) # True

f.close()
5.2.4 文件的追加:a

没有原文件,创建新文件,写入内容

有原文件,在原文件最后追加,写入内容

# 没有原文件,创建新文件,写入内容

f1 = open('test3', encoding = 'utf-8', mode = 'a')

f1.write('我爱北京天安门')

f1.close()

 

# 有原文件,在文件最后追加新内容

f1 = open('test3', encoding = 'utf-8', mode = 'a')

f1.write('\n我是女生,漂亮的女生')

f1.close()
5.2.5 b模式

b模式 bytes 可以读文本、图片、视频,文件不存在报错

# rb模式不能指定字符编码,否则报错

with open(b'1.jpg','rb') as f: print(f.read())#输出图片的二进制编码 with open(b'1.txt','rb') as f: print(f.read().decode('utf-8')) # rt 以文本形式读取 with open(b'a.txt','rt',encoding='utf-8') as f: print(f.read()) # wb with open(b'a.txt','wb') as f: res='你好'.encode('utf-8') print(res,type(res)) f.write(res) # ab 追加写 with open(b'a.txt','ab') as f: res='你好'.encode('utf-8') print(res,type(res)) f.write(res)
5.2.6 其他操作方法

# readable:是否可读

f1 = open('test', encoding = 'utf-8', mode = 'a+' )

print(f1.readable()) 

# writeable:是否可写

f1 = open('test', encoding = 'utf-8', mode = 'a+' )

print(f1.writable())

tell:光标位置 (字节)

f1 = open('test', encoding = 'utf-8',mode = 'r')

print(f1.read(3))

print(f1.tell()) # 9 # 按字节为单位输出位置

f1.close()

seek:调整光标位置 seek(0,2):将光标调整到最后 seek(0):将光标调整到最前面

f1 = open('test', encoding= 'utf-8', mode = 'r')

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

print(f1.tell)

f1.close()

 

f1 = open('test', encoding= 'utf-8', mode = 'r')

print(f1.seek(0)) # 将光标调整到最前面

print(f1.tell) # 0

f1.close()

truncate:按照字节对原文件截取,必须在a或a+模式下

f1 = open('test', encoding='utf-8',mode = 'a')

f1.truncate(3)

f1.close()
5.2.7 with open

1. 不用主动关闭文件句柄

2. with 可以操作多个文件句柄

3. with 同时操作一个文件,出现共用一个文件句柄报错,可以主动关闭开始的操作

with open('test', encoding= 'utf-8',) as f1:

print(f1.read()) # 打印完之后不用手动关闭文件句柄

 

with open('test', encoding='utf-8') as f1, open('test1',encoding='utf-8',mode = 'w') as f2:

print(f1.read()) # with 可以操作多个文件句柄

f2.write('我在中国,北京,沙河')

 

with open('test', encoding='utf-8') as f1:

print(f1.read()) # 主动关闭文件句柄f1

f1.close()

pass

with open('test',encoding='utf-8',mode = 'w') as f2:

f2.write('我是女生,可爱的女生')

5.3 文件的改

1. 以读模式打开原文件

2. 以写的模式打开一个新文件

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

4. 删除原文件

5. 将新文件重命名原文件

# 将“我”全部替换成“小白”

import os

with open('file', encoding= 'utf-8', mode = 'r') as f1,\

open('file.bak', encoding='utf-8', mode = 'w') as f2:

old_content = f1.read()

new_content = old_content.replace('', '小白')

f2.write(new_content)

os.remove('file')

os.rename('file.bak', 'file')


# 将“小白”替换成“我”

import os

with open('file', encoding= 'utf-8', mode = 'r') as f1,\

open('file.bak', encoding='utf-8', mode = 'w') as f2:

for line in f1:

new_line = line.replace('小白','')

f2.write(new_line)

os.remove('file')

os.rename('file.bak', 'file'

6. 函数

6.1 函数初识

写一个计算字符串或列表等长度的方法,方法类似len()方法,发现实现的代码几乎相同:

s = 'Hello World!'

def my_len():

count = 0

for i in s:

count += 1

print(count)

my_len()

print(len(s))

首先,之前只要我们执行len方法就可以直接拿到一个字符串的长度了,现在为了实现相同的功能我们把相同的代码写了好多遍 —— 代码冗余

其次,之前我们只写两句话读起来也很简单,一看就知道这两句代码是在计算长度,但是刚刚的代码却不那么容易读懂 —— 可读性差

使用函数可以解决以上问题:

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

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print(),len()等。但你也可以自己创建函数,这被叫做用户自定义函数。

函数是以功能为导向的。

6.1.1 函数的格式

del 关键字 函数名(设定与变量相同):

函数体

return:函数的返回值

函数名(): 执行函数

函数名会加载到内存,函数体不会执行

():调用运算符

6.2 函数的返回值: return

1. 终止函数

2. 给函数的执行者返回值(单个值和多个值)

return 或 return None:终止函数

def func1():

print('111')

print('222')

return

print('333')

func1()

return: 给函数的执行者返回单个值

def func1():

print('111')

print('222')

return 666 # 给 func1 返回 int型 666

return '小白' # 给 func1 返回 字符串 ‘小白’

print('333')

ret = func1()

print(ret)

return:给函数的执行者返回多个值

def func1():

print('111')

print('222')

return 666, '小白', [1,2,3] # 给 func1 返回多个值,把多个值放在一个元组中

print('333')

ret = func1()

print(ret) # (666, '小白', [1, 2, 3])
# 例:计算字符串或列表等长度

s = 'Hello World!'

def my_len():

count = 0

for i in s:

count += 1

return count

print(my_len())

6.3 函数的参数 

# 以下函数实现了len()计算元素长度的功能,但是不能动态的计算

s = 'Hello World!'

def my_len(): # 函数的定义(形式参数,形参)

count = 0

for i in s:

count += 1

return count

print(my_len()) # 函数执行(实际参数,实参)

print(len(s))

# 修改如下,通过函数的参数,可以动态的计算元素的长度

def my_len(argv): # 函数的定义(形式参数,形参)

count = 0

for i in argv:

count += 1

return count

s = 'sdagkl;jsakd fhaskdhfka'

l = [1, 2, 3, 4, 5, 6, 7, 8]

print(my_len(s)) # #函数执行(实际参数,实参)

print(my_len(l)) # #函数执行(实际参数,实参)

6.31 实参角度

位置参数:必须按照顺序一一对应

def func1(a,b,c):

print(a,b,c)

func1(1, 2, 'xiaobai')

关键字参数:必须一一对应,不分顺序

def max(a, b):

print(a,b)

max(a = 1, b = 2) 

混合参数: 一一对应 并且关键字参数必须在位置参数后面

def max(a, b, c, d):

print(a,b,c,d)

max(7, d = 1, c = 2, b = 6,)
6.3.2 形参角度

位置参数:必须按照顺序一一对应

def func(a,b):

print(a,b)

func(1,2)

默认参数:在位置参数的后面

def login(name,sex = ''): # sex 默认为男

with open('register', encoding= 'utf-8', mode = 'a') as f1:

f1.write('{},{}\n'.format(name,sex))

while True:

name = input('请输入姓名:').strip()

if '1' in name: # 姓名中带1的,默认sex为男

login(name)

else:

sex = input('请输入性别:').strip()

login(name,sex)

动态参数:*args **kwargs (万能参数)

当参数不固定时,可以用万能参数

# args:所有的位置参数,放在一个元组中

# kwargs:所有的关键字参数,放在一个字典中

def func3(*args, **kwargs): #函数定义时,* 代表聚合

print(args) # args:所有的位置参数,放在一个元组中 (1, 2, 3, 'hello')

print(kwargs) # kwargs:所有的关键字参数,放在一个字典中 {'c': 1, 'name': 'xiaobai', 'age': 18}

func3(1,2,3,'hello',c= 1, name = 'xiaobai', age = 18)

# 函数定义中的* ** 和函数执行中* ** 的含义

#函数定义时,* 代表聚合

# 函数执行的时候,* 代表打散

# 函数执行的时候,字典类型用**代表打散

def func3(*args, **kwargs): #函数定义时,* 代表聚合

print(args) # (1, 2, 3, 'hello')

print(kwargs) # {'c': 1, 'name': 'xiaobai', 'age': 18}

func3(*[1,2,3],*(22,33)) # 函数执行的时候,* 代表打散

 

def func3(*args, **kwargs): #函数定义时,* 代表聚合

print(args) #

print(kwargs) # {'name': 'xiaobai', 'age': 18}

func3(**{'name':'xiaobai'}, **{'age':18}) # 函数执行的时候,字典类型用**代表打散 

# 形参的顺序: 位置参数 args 默认参数 kwargs

def func5(a,b,*args,sex='',**kwargs):

print(a,b) # 1 2

print(args) # ('hello', 'world', '你好')

print(sex) #

print(kwargs) # {'name': 'Lucy', 'age': 18}

func5(1,2,'hello','world','你好',sex='',name='Lucy',age=18)

 

 

posted @ 2018-05-24 19:51  牛小白  阅读(273)  评论(0编辑  收藏  举报