day3-Python集合、函数、文件操作,python包的概念

本节大纲:

 

1 python程序由包(package)、模块(module)和函数组成。包是由一系列模块组成的集合。模块是处理某一类问题的函数和类的集合。

2 包就是一个完成特定任务的工具箱。

3 包必须含有一个__init__.py文件,它用于标识当前文件夹是一个包。

4 python的程序是由一个个模块组成的。模块把一组相关的函数或代码组织到一个文件中,一个文件即是一个模块。模块由代码、函数和类组成。导入模块使用import语句。

5 包的作用是实现程序的重用

一:在执行list()函数或者dict()函数首先是调用list()函数或者dict()方法会自动调用该函数的__init__方法进行数据的初始化,list()函数通过一个可迭代的对象,用for循环进行遍历插值。

 

1 list_test=list((1,2,3,))
2 print(list_test)
3 [1, 2, 3]

 

 上述的过程:首先list()函数调用本身的__init__方法进行数据的初始化,通过for循环,把元组(1,2,3,) 遍历插入列表[1,2,3,]

二:集合

集合是无序数据类型,元素不可以重合。如果集合内元素重复会自动去重。用大括号表示和字典表示一样,字典是无序的数据类型,但是key-value的映射。

1 set_a=set([1,2,2,3,])
2 print(set_a)
3 
4 {1, 2, 3}

可以通过内部函数set()对集合进行转换。字典、字符串、列表都可以转换成集合。

1 set_b=set({'name':'evil',})
2 set_c=set('evil')
3 set_d=set([1,2,3,])
4 print(set_b,set_c,set_d)
5 
6 {'name'} {'i', 'l', 'e', 'v'} {1, 2, 3}

1、操作集合

 1)add()函数。添加元素给集合。

1 s_tets=set()
2 s_tets.add(456)
3 s_tets.add(456)
4 s_tets.add(456)
5 print(s_tets)
6 {456}

应用场景:爬虫。在返回url保存的时候可以用集合操作,默认去除重复的元素。

2)difference()函数。比如a.difference(b)表示a存在元素b不存在元素。但是a和b本身的集合不发生改变。

1 s1_testa={1,2,3,}
2 s2_testb={2,5,6,}
3 print(s1_testa.difference(s2_testb))
4 print(s2_testb.difference(s1_testa))
5 print(s2_testb,s1_testa)
6 
7 {1, 3}
8 {5, 6}
9 {2, 5, 6} {1, 2, 3}
3、symmetric_difference()函数,比如a.symmetric_difference(b)表示a和b集合去掉交集部分的结合。并不能改变集合a和b的值。
s1_testa={1,2,3,}
s2_testb={2,5,6,}
print(s1_testa.symmetric_difference(s2_testb))
print(s2_testb,s1_testa)
{1, 3, 5, 6}
{2, 5, 6} {1, 2, 3}
3)上述的操作不能修改原集合的值。如果想修改原集合的值。用如下函数:a.difference_update(b)函数。会修改集合a的值。b值不变。a值会变成。a存在的元素且b不存在的元素的值。
1 set_a={1,2,3,4,}
2 set_b={'c',6,3,5,}
3 set_a.difference_update(set_b)
4 print(set_a)
5 print(set_b)
6 {1, 2, 4}
7 {'c', 3, 5, 6}
4)同样a.symmetric_difference_update(b)函数也会修改a的值,使a的值变为,a、b集合的去除公共元素的集合。
1 set_a={1,2,3,4,}
2 set_b={'c',6,3,5,}
3 set_a.symmetric_difference_update(set_b)
4 print(set_a)
5 print(set_b)
6 {1, 2, 4, 5, 6, 'c'}
7 {3, 5, 6, 'c'}

5)删除集合指定元素。discard()函数。如果该元素不存在不会报错。

 

1 set_a={1,2,3,4,}
2 set_a.discard(1)
3 print(set_a)
4 set_a.discard(111)
5 print(set_a)
6 {2, 3, 4}
7 {2, 3, 4}

 

同样也可以用remove()函数,但是不存在元素会报错。KeyError: 111

 1 set_a={1,2,3,4,}
 2 set_a.remove(111)
 3 print(set_a)
 4    set_a.remove(111)
 5 KeyError: 111
 6 
 7 set_a={1,2,3,4,}
 8 set_a.remove(4)
 9 print(set_a)
10 {1, 2, 3}

也可以用pop()函数删除元素。但是随即删除一个元素。

1 set_a={1,2,3,4,5,6,7,8}
2 set_a.pop()
3 print(set_a)
4 
5 {2, 3, 4, 5, 6, 7, 8}

6)批量添加元素。用update()函数。通过for循环对迭代的对象(比如说列表,字符串,字典的keys以及字典的value值),进行add()操作添加。

 1 1 set_a=set()
 2 2 list_a=[1,2,3,4,5,4]
 3 3 set_a.update(list_a)
 4 4 print(set_a)
 5 5 {1, 2, 3, 4, 5}
 6 
 7 set_a=set()
 8 set_b=set()
 9 list_a={'name':'evil','age':22}
10 list_b={'name':'evil','age':22}
11 set_a.update(list_a)##默认对key值进行迭代。
12 print(set_a)
13 set_b.update(list_b.values())
14 print(set_b)
15 {'name', 'age'}
16 {'evil', 22}

7)当我们在执行一些列表或者其他操作的时候,会调用list()函数的一些方法。比如:

1 list_a=[1,2,3] ##调用list的__init__方法
2 print(list_a[0])##调用list的__getitem__方法
3 list_a[0]=44##调用list的__setitem__方法
4 del list_a[2]##调用list的__delitem__方法

 

8)在写列表或者字典、集合、元组的时候,进行最后元素加个逗号,在以后django学习的过程中不加逗号有时候会报错。

1 list_a=[1,2,3,]
2 dict_a={'a':2,'b':3,}
3 tuple_a=(1,2,3,)
9)集合的并集、交集。

交集函数:a.intersection(b)和a.intersection_update(b)前一个函数不改变原先集合(a,b)的值,后一个更新被交集的集合(a)。

 1 s1_testa={1,2,3,}
 2 s2_testb={2,5,6,}
 3 s3=s1_testa.intersection(s2_testb)
 4 print(s3,s1_testa,s2_testb)
 5 {2} {1, 2, 3} {2, 5, 6}
 6 s1_testa={1,2,3,}
 7 s2_testb={2,5,6,}
 8 s1_testa.intersection_update(s2_testb)
 9 print(s1_testa,s2_testb)
10 {2} {2, 5, 6}

并集函数:a.union(b)

1 s1_testa={1,2,3,}
2 s2_testb={2,5,6,}
3 s3=s1_testa.union(s2_testb)
4 print(s3,s1_testa,s2_testb)
5 {1, 2, 3, 5, 6} {1, 2, 3} {2, 5, 6}

10)练习:

 在cmdb日常资产管理的时候,日常服务器检测硬件信息收集中,如果一个服务器4个内存插槽,#1、#2、#4插槽分别插,4G、8G、16G。如果现在变化#1插槽变为16G,#2不变,3#插槽插4G的,#4不插。该如何更新信息呢?

1、该删除那个元素?

2、该更新那个元素?

3、那个元素变了,需要更新?

 1 dict_old={
 2     '#1':4,
 3     '#2':8,
 4     '#4':16,
 5 }
 6 dict_new={
 7     '#1':4,
 8     '#2':8,
 9     '#3':4,
10 }

答案:

 1 set_old=set(dict_old.keys())##生成keys值得集合
 2 set_new=set(dict_new.keys())
 3 del_item=set_old.difference(set_new)##old有的new没有的
 4 print('delete item %s'%del_item)
 5 up_item=set_new.difference(set_old)##new有的old没有
 6 print('add item %s'%up_item)
 7 a=set_old.intersection(set_new)## old和new的集合
 8 for i in a:
 9     if dict_new[i]!=dict_old[i]:
10         print('update item: %s'%i)##交集的元素value值不相当,需要更新的。

 三:函数:函数组成:

def functionname(parameter):###由关键字def进行定义,然后函数名字(functionname)和函数参数。

 #function description ###函数的描述,作用;参数作用;

  function body ##函数体,执行代码

 return value## 函数返回值。缺省值是None。

 以下是发邮件代码:

 1 def sendmail():
 2     try:
 3         import smtplib
 4         from email.mime.text import MIMEText
 5         from email.utils import formataddr
 6         msg = MIMEText('邮件内容', 'plain', 'utf-8')
 7         msg['From'] = formataddr(["xxx",'xx@126.com'])
 8         msg['To'] = formataddr(["走人",'xx@qq.com'])
 9         msg['Subject'] = "主题"
10 
11         server = smtplib.SMTP("smtp.126.com", 25)
12         server.login("username", "password")
13         server.sendmail('xxx@126.com', ['xxx@qq.com',], msg.as_string())
14         server.quit()
15     except:
16         # 发送失败
17         return "失败"
18     else:
19         # 发送成功
20         return "cc"
21 
22 ret = sendmail()
23 print(ret)
24 if ret == "cc":
25     print('发送成功')
26 else:
27     print("发送失败")

 执行顺序:

 python在执行py文件的时候从上到下依次执行。上面的sendmail.py文件,首先执行1:定义一个函数sendmail() 并不执行函数体。而是往下执行,遇到函数依然这样执行,首先让解释器知道定义这个函数,到第2部分的时候,也就是函数的调用部分的时候,
解释器会跳到该程序sendmail()函数部分,并给sendmail的形参传入相应的参数值。执行函数体,也就是标记的3部分。当函数体执行完之后,返回函数值赋值给ret值。然后程序往下执行,第4部分。
1)函数一旦执行return语句的时候,函数立即终止。不会执行函数体下面的代码。
1 def  test():
2     print(1+1)
3     return True
4     print(222)
5 
6 if __name__=='__main__':
7     test()
8 2

 

2)函数的参数:
1、普通参数(严格按照顺序,讲实际参数赋值给形式参数)
2、默认参数(必须放置在参数列表的最后)
3、指定参数(将实际参数赋值给指定形式参数)
4、动态参数:
  * 默认传入的参数。全部放在元组中。
  ** 默认传入的参数。全部放在字典中。
1、有限的形参。
1 def mon(x,y):###其中x,y是形参。
2     a=x+y
3     return a
4 res=mon(1,2)##给函数mon()传入实参。并执行函数体a=1+2 并返回a的值。赋值给res
5 print(res)
6 3

 

执行顺序:

1)首先读取程序定义函数mon()部分。
2)然后执行mon(1,2)函数调用部分并给函数mon(x,y)的形参传入实参(1,2)再执行3部分的函数体,执行函数体并函数返回a的值 。
3)返回a的值 并赋值给res变量,这是执行第4步。
4)然后执行第5部分打印输出res变量。

 需要注意的是:

1)在有限的形参的函数,在给传入实参的时候,实参的个数和形参的个数必须一致。

2)实参和形参 是一一对应的。如果没有默认参数的情况下,数目必须一致。

否则会报错:TypeError: mon() missing 1 required positional argument: 'y'。

2、默认参数:

在函数的定义的过程中,可以给形参定义缺省值。如果该形参没有传入实参的时候会用缺省值。如果传入的实参个数和形参的个数一致的时候,不会使用缺省值。

1 def mon(x,y=9):
2     a=x+y
3     return a
4 res=mon(1)
5 res1=mon(1,4)
6 print(res)
7 print(res1)
8 10
9 5

 

默认情况未指定实参数位置,实参传入会从左到右 一次匹配形参。如果你指定默认参数位置的时候,未指定参数按默认形式匹配,指定的参数会按指定匹配。如下所示。

 1 def mn(a,b=2,c=2):
 2     SUM=a+b+c
 3     return SUM
 4 
 5 res=mn(1,2)
 6 res1=mn(1)
 7 res2=mn(1,c=3)####默认是从形参的开头从左到右一次匹配。
 8 print(res,res1,res2)
 9 
10 5 5 6

 

需要注意:

默认参数的位置必须在最后,比如上面的 不可以这么写:def mon(y=9,x)这样会报错!!

3)指定参数:

当我们用形参的时候,在传入实参的时候不指定位置的时候,会依次对应。如果在传入实参的指定参数的时候,实参的位置的可以无序的。比如:

 1 def mon(x,y=9):
 2     a=x+y
 3     return a
 4 res=mon(x=1)
 5 res1=mon(x=1,y=4)
 6 res2=mon(y=2,x=4)
 7 print(res)
 8 print(res1)
 9 print(res2)
10 10
11 5
12 6

 

4)不固定参数。*args

 1 def mn(*args):
 2     print(args,type(args))
 3 mn(1,2,3,4,)
 4 mn([1,2,3,4,])
 5 
 6 
 7 def mn_1(args):
 8     print(args,type(args))
 9 mn_1([1,2,3,])
10 
11 (1, 2, 3, 4) <class 'tuple'>
12 ([1, 2, 3, 4],) <class 'tuple'>
13 [1, 2, 3] <class 'list'>

 如果想传入的参数是字典。该怎么办呢???

1 def mn(*args):
2     return args
3 
4 dic={'a':2,'b':3}
5 res=mn(*dic)
6 print(res)
7 
8 ('b', 'a') ###这种情况 只能传入字典的key值 形式元组。

 

同样如果这么处理的话,传入的列表。不在是由传入列表组成的元组。而是把列表中的元素 变为元组的元素。

1 def mn(*args):
2     return args
3 
4 list_1=[1,2,3,4,]####传入的是列表的实参 直接转成元组的。而不是([1,2,3,4,])
5 res=mn(*list_1)
6 print(res)
7 
8 (1, 2, 3, 4)

 

也就是说,在形参不带*和不带*区别:

  1)args:不带*的参数,在传入实参的时候 ,传入的实参的个数也是一个。需要数目一致。传入的实参的数据类型是什么,赋值之后数据类型就不会改变。

  2)*args:带*的参数,在传入实参的时候,实参的个数可以是一个,多个。没有个数的限制。但是传入的实参,最后赋值之后,会形式一个元组形式的元素组成,,无论你传入是字符串、数字、列表还是字典。元素保持传入实参的数据类型,比如是列表,传入时候元组是由列表元素组成。

 1 def mn(*args):
 2     print(args,type(args))
 3 mn(1,2,3,4,)
 4 mn([1,2,3,4,],2)
 5 mn({
 6     'name':'evil',
 7     'age':22,
 8 })
 9 
10 
11 (1, 2, 3, 4) <class 'tuple'>
12 ([1, 2, 3, 4], 2) <class 'tuple'>
13 ({'age': 22, 'name': 'evil'},) <class 'tuple'>

 

5)带**形参形式。
这种形式的参数必须要传入这种形式的:key=value。否则报错。形参赋值之后是由元素的组成的字典。
 1 def mk(**args):
 2     return args
 3 
 4 res=mk(a=2,)
 5 res1=mk(op={
 6     'age':21,
 7     'name':'tom',
 8 })
 9 print(res,type(res))
10 print(res1,type(res1))
11 {'a': 2} <class 'dict'>
12 {'op': {'name': 'tom', 'age': 21}} <class 'dict'>

 如果传入的实参是字典,不是key=value  该如何处理呢???

1 def mn(**kwargs):
2     return kwargs
3 
4 dic={'a':2,'b':3}
5 res=mn(**dic)#####需要注意进行调用的时候进行**形式进行形参的赋值。
6 print(res)
7 
8 
9 {'a': 2, 'b': 3}

 

6)万能参数:(格式*在**前面)

 1 def mn(*args,**kwargs):
 2     return args
 3 def mn1(*args,**kwargs):
 4     return kwargs
 5 
 6 res=mn(1,2,3,)
 7 print(res,type(res))
 8 res_1=mn1(a=2)
 9 print(res_1,type(res_1))
10 
11 (1, 2, 3) <class 'tuple'>
12 {'a': 2} <class 'dict'>

 

也就说,当形参:(*args,**kwargs)形式的时候,当传递参数不固定的字符串、列表、字典等,则赋值给形参args并形成一个元组。而传递实参是key=value形式的时候,则赋值给:kwargs 形成一个字典。

我们称这种形参方式叫做万能参数(自己称呼)。

 

1 def mn(*args,**kwargs):
2     print(args)
3     print(kwargs)
4 
5 res=mn(1,2,3,a=2,c=3,)
6 
7 (1, 2, 3)
8 {'c': 3, 'a': 2}

 

也就是说:

按上图的所示进行实参的赋值。

3)format()函数字--符串的初始化:

2种形式:

1、

 1 name='evil'
 2 age='22'
 3 id=1318
 4 pre='''
 5 This is %s information:
 6 NAME:%s
 7 AGE:%s
 8 ID:%s
 9 '''%(name,name,age,id)
10 print(pre)
11 
12 this is evil information:
13 NAME:evil
14 AGE:22
15 ID:1318

 

2:用formate()函数进行初始化。如上的例子修改为:

 1 name='evil'
 2 age='22'
 3 id=1318
 4 pre='''
 5 This is {0} information:
 6 NAME:{1}
 7 AGE:{2}
 8 ID:{3}
 9 '''.format(name,name,age,id)
10 print(pre)
11 
12 This is evil information:
13 NAME:evil
14 AGE:22
15 ID:1318

 

其中有{num}比如上面的{0},{1}....是占位符。与后面的变量的依次对应。

需要注意的是其中0,1,2,3的数字对应后面的变量(name,name,age,id)所形成的元组的索引或者是字典的key值。不能随便修改成下面。会报错的或者显示的效果不是我们想要的。

 1 name='evil'
 2 age='22'
 3 id=1318
 4 pre='''
 5 This is {1} information:
 6 NAME:{2}
 7 AGE:{2}
 8 ID:{3}
 9 '''.format(name,name,age,id)
10 print(pre)
11 
12 This is evil information:
13 NAME:22
14 AGE:22
15 ID:1318

 

或者报错:

name='evil'
age='22'
id=1318
pre='''
This is {1} information:
NAME:{2}
AGE:{2}
ID:{4}
'''.format(name,name,age,id)
print(pre)

Traceback (most recent call last):
  File "C:/xx", line 9, in <module>
    '''.format(name,name,age,id)
IndexError: tuple index out of range

 

 

format()函数结构:

 所以根据可以传递列表、key=value形式:

1 info=['evil',22]
2 print('my name is {0} and age is {1}'.format(*info))
3 
4 my name is evil and age is 22

 

 用*info形式的进行传入实参。列表info会转换成('evil',22)的元组。然后进行索引的对应。

1 info={'name':'evil','age':22}
2 print('my name is {name} and age is {age}'.format(**info))
3 
4 my name is evil and age is 22

 

注意这种形式实参传入,其中的占位符是字典的key值,而不是索引!!! 传入的是字典不是元组了。也就是用format()函数的**kwargs参数。

4)关于函数的返回值。

一个函数的返回值是任意的可以是一个列表、一个字典、一个布尔值、数字、或者没有返回值。没有返回值的情况,缺省值是None。

返回值布尔值:如下简单登陆验证

 1 dic_a={
 2     'name':'evil',
 3     'password':'22',
 4 }
 5 def login(username,password):
 6     if username==dic_a['name'] and password==dic_a['password']:
 7         return True
 8     else:
 9         return False
10 if __name__=='__main__':
11     user=input('Entre your username:')
12     paswd=input('password:')
13     res=login(user,paswd)
14     if res:
15         print('Welcome to python')
16     else:
17         print('sorry login fail bye!')
18 
19 
20 Entre your username:evil
21 password:22
22 Welcome to python

 

返回值列表:

 1 def chek():
 2     user=input('entre your username:')
 3     age=input('entre your age:')
 4     addr=input('entre your adrr:')
 5     return [user,age,addr]
 6 if __name__=='__main__':
 7     res=chek()
 8     print('name:{0} age:{1},addr:{2}'.format(*res))
 9 
10 entre your username:tom
11 entre your age:22
12 entre your adrr:LianoNing
13 name:tom age:22,addr:LianoNing

 

返回值字典:

 1 def chek():
 2     user=input('entre your username:')
 3     age=input('entre your age:')
 4     addr=input('entre your adrr:')
 5     return {
 6         'name':user,
 7         'age':age,
 8         'addr':addr
 9     }
10 if __name__=='__main__':
11     res=chek()
12     print('name:{name} age:{age},addr:{addr}'.format(**res))
13 
14 entre your username:evil
15 entre your age:22
16 entre your adrr:;LiaoNing
17 name:evil age:22,addr:;LiaoNing

 

没有返回值:

1 def mn(x,y):
2     a=x+y
3 
4 res=mn(1,2)
5 print(res)
6 None

 5)相同函数名字执行顺序:

1 def mn(x,y):
2     a=x+y
3     return a
4 def mn(x,y):
5     a=x*y
6     return a
7 res=mn(1,2)
8 print(res)
9 2

相同的名字的函数,执行 临近函数调用最近的函数定义,如上。

6)函数传入给给形参的引用,形参引用实参,而不是内存中重新开辟一个值,赋给形参。

1 def mn(x):
2     x.append(999)
3 list_1=[1,2,3,4]
4 mn(list_1)
5 print(list_1)
6 
7 [1, 2, 3, 4, 999]

当x进行操作的时候,添加元素999的时候,会更新list_1.

7)函数的变量:

全局变量:所有作用域都可读。

对全局变量进行重新赋值,需要global

全局变量要大写。比如:NAME .....

私有变量:在函数里的变量是私有的,作用域只在函数体内。

全局变量作用域全局,如上所示。

 私有变量:

 1 def sum(x,y):
 2     a=2
 3     b=a+x+y
 4     print(b)
 5     return  b
 6 def a(x,y):
 7     print(b)
 8 sum(1,2)
 9 a(1,2)
10 
11 NameError: global name 'b' is not defined
12 5

 

 如果私有变量超出函数体的时候,别的函数调用这个变量会出现错误。如上所示。

可以把私有变量变为全局变量,如下所示:

 1 def sum(x,y):
 2     a=2
 3     global b
 4     b=a+x+y
 5     print(b)
 6     return  b
 7 def a(x,y):
 8     print(b)
 9 sum(1,2)
10 a(1,2)
11 5
12 5

 

注意:global 变量名,变量名赋值。这种写法,不要:先变量名,然后global 变量。这样会抛出一个warning 异常。

 1 def sum(x,y):
 2     a=2
 3     b=a+x+y
 4     global b
 5     print(b)
 6     return  b
 7 def a(x,y):
 8     print(b)
 9 sum(1,2)
10 a(1,2)
11 
12 SyntaxWarning: name 'b' is assigned to before global declaration global b
13 5
14 5

 

 

 

8)函数的注释:

注释:包括函数的功能。参数的说明。以及返回值的说明。好的description帮助别人能快速了解你的代码。

 1 USER_INFO={
 2     'name':'evil',
 3     'age':'22',
 4 }
 5 def login(username,password):
 6     '''
 7     用户登录
 8     :param username:用户名字
 9     :param password:用户密码
10     :return:True表示登录成功,False表示登录失败。
11     '''
12     if username==USER_INFO['name'] and password==USER_INFO['age']:
13         return True
14     else:
15         return False
16 
17 if __name__=='__main__':
18     user=input('Entre your login:')
19     paswd=input('Entre your password:')
20     res=login(user,paswd)
21     if res:
22         print('Welcome to Python!!')
23     else:
24         print('sorry login fail!!')
25 Entre your login:evil
26 Entre your password:22
27 Welcome to Python!!

 

9)三元运算(是针对if else来说)

我们常用的:

1 if 1==1:
2     a=2
3     print(a)
4 else:
5     a=3
6     print(a)
7 2

 

用三元运算可以这么写:

1 a=2 if 1==1 else 3
2 print(a)
3 2

 

 

lamdba表达式:

1 sum=lambda x,y:x+y
2 print(sum(1,2))
3 3

 

 

之前的写法:

1 def sum(x,y):
2     return x+y
3 print(sum(1,2))
4 
5 3

 

lamdba 是适用于简单的运算和判断,不适用于复杂的判断逻辑。

10)常用函数:

1:all()当所有元素为真才为真。

2:any()至少其中一个元素为真才为真。

1 m=all([1,2,3,4,])
2 print(m)
3 n=any([None,False])
4 print(n)
5 
6 True
7 False

 

1 m=all([1,2,3,0,])
2 print(m)
3 n=any([None,True])
4 print(n)
5 False
6 True

 

 3:abs() 求绝对值:

1 print(abs(-1))
2 1

 

3:bool() 求布尔值。

1 print(bool(1))
2 True

 

4:bytes()字符串转换字节。需要指定转换编码比如:utf-8 ,gbk.

1 a='evil'
2 print(bytes(a,encoding='utf-8'))
3 b='汉武帝'
4 print(bytes(b,encoding='utf-8'))
5 b'evil'
6 b'\xe6\xb1\x89\xe6\xad\xa6\xe5\xb8\x9d'

 

那字节怎么转换成字符串呢?同样用str()函数。但是必须指定相应的编码才可以哦。不正确的编码会报错哦。

1 print(str(b'\xe6\xb1\x89\xe6\xad\xa6\xe5\xb8\x9d',encoding='utf8'))
2 
3 汉武帝

 

11)文件操作:

 操作文件时候需要2个步骤:1)打开文件。2)操作文件。
1:打开文件模式有:
1 f=open('haproxy','r',encoding='utf-8')##以只读模式,以utf-8编码打开文件
2 f1=open('haproxy','w',encoding='utf-8')##以写模式,以utf-8编码打开文件,如果文件存在则直接清空,如果没有则创建。
3 f2=open('haproxy','x',encoding='utf-8')##在python3中新加的,文件存在报错,不存在则创建并写入内容。
4 f3=open('haproxy','a',encoding='utf-8')###文件追加内容。

 

r+,w+,a+表示既可读也可以写。
'b'模式以二进制形式打开文件。rb,wb,ab.
如果平时open打开文件是乱码,一般是编码有问题。现在一般使用编码utf-8编码。
注意:在使用open()函数打开文件的时候,在文件操作完毕的时候需要把文件句柄关闭即:
1 f=open('xxx','mod',encoding='xx')
2 xxxxx
3 f.close()

 

 由于这么操作的时候容易忘记关闭文件句柄。用with   as  函数来管理上下文件。文件操作完毕自动关闭文件。
1 with open('haproxy.txt','r',encoding='utf-8') as file_obj:
2     pass

 

在python2.7以后with函数可以同时操作多个文件。最常用的操作就是:一个文件在读,一个文件在写。
1 with open(1.txt','r',encoding='utf-8') as file_obj,open('1.back','w',encoding='utf-8')as file_obj1:
2     for i in file_obj.readlines():
3         i.replace('evil','tom')
4         file_obj1.write(i)
2:操作文件:
文件在硬盘以2进制存储,默认情况当python在以(r+,w+,a+等模式)读的时候,在不指定编码的时候,以pytho解释器默认编码,编码成字符串,供程序员进行读写。
如果以rb,wb,ab方式是不用python默认编码,直接以字节方式进行访问,存储的方式2进制,所以要把字符串写入文件,需要把字符串转化成字节才能写入。
1)常用的操作文件的函数。
file.fulsh(),强制把内存的内容刷进硬盘。
实验:
用input()交互方式,在等待用输入的时候,看文件是否内容。
1 with open('test.txt','a') as f1:
2     f1.write('this is test!')
3     dengdai=input('entre your NUM:')
运行该程序,查看文件。文件缓存区的内容没有写入磁盘内,加上file.fulsh(),我们在看下。

1 with open('test.txt','a') as f1:
2     f1.write('this is test!')
3     f1.flush()
4     dengdai=input('entre your NUM:')

发现文件句柄没释放,已经把文件内容写入文件里。
2) file.read()在指定字节大小,可以读指定字节,在没指定,读取文件整个内容。
1 with open('test.txt','r') as f1:
2     for i in f1.read(5):
3         print(i)
4 
5 1
6 1
7 1
8 1
9 t

 

文件内容:
1111this is test!
3)file.readline()仅读取文件一个行。
1 with open('test.txt','r') as f1:
2     for i  in f1.readline():
3         print(i)

4)file.readlines()读取文件,一行为单位,并根据换行来保存值列表,这个函数很常用。
1 with open('test.txt','r') as f1:
2     for i  in f1.readlines():
3         print(i)
4 
5 1111this is test!

 

5)file.seek()指定文件指定到指定位置(字节)。
1 with open('test.txt','r') as f1:
2     f1.seek(4)
3     for i  in f1.readlines():
4         print(i)
5 
6 this is test!
文件内容:1111this is test!
将文件指针移到第四个字节。然后操作读。

 

6)file.tell()获取文件当前指针。
1 with open('test.txt','r') as f1:
2     f1.seek(4)
3     for i  in f1.readlines():
4         print(i)
5     print(f1.tell())
6 
7 this is test!
8 17

 

因为文件读完,文件指针在文件的末尾。
7)file.truncate (),根据文件指针位置,在文件指针位置以后被清空。
1 with open('test.txt','r+') as f1:
2     f1.seek(4)
3     f1.truncate()
4 1111

 

上述文件内容,指定文件指针位置,文件指针位置以后都清除。
8)file.write()写数据,有b按字节写入,没指定按字符串写入。
1 with open('test.txt','r+') as f1:
2     f1.seek(4)
3     f1.write('goodbye!')
4 1111goodbye!

9)需要注意,在读文件的时候,最好用如下方式进行读,这种方式是生成迭代器,效率较高。相比read(),readline(),readlines()
1 with open('test.txt','r',encoding='utf-8') as f1:
2     for i in f1:
3         print(i)

 




























posted @ 2016-05-26 22:18  evil_liu  阅读(648)  评论(0编辑  收藏  举报