接口测试学习-Python第四课(文件操作及函数定义)

一、关于文件一些常用的方法

1、闪存

如果对文件进行写入操作后,文件内容没有更新,可能是因为读取写入都需要经过缓冲区,导致无法立即成功。此时可以用flush()方法,强制写入。

1 with open('ss','w',encoding='utf-8') as f:
2     f.write('string')
3     f.flush()    

2、修改文件内容

修改文件内容有两种方法。

第一种方法是先读出原文件数据,进行修改后,清空原文件数据,再将修改后的内容写入原文件中。

1 f = open('zhanghao','a+',encoding='utf-8')
2 f.seek(0)
3 all_str = f.read()#先获取到原来文件的所有内容
4 new_str = all_str.replace('123456','17171717')#修改获取到的数据数据 5 f.seek(0)#调整指针位置 6 f.truncate()#清空原文件的所有内容 7 f.write(new_str)#将修改后的数据写入文件 8 f.close()

这样操作的缺点是,当原文件内容较大时,这样读出数据会影响运行速度甚至导致内存溢出。

第二种方法是读取原文件的每一行数据并进行修改,然后依次存入新文件中,再将原文件删除,最后修改新文件名称为原文件名称。这样就完成了“修改”文件内容。

1 import os#需要使用os模块
2 # 先将原文件的每一行修改并存入新文件,一行一行处理
3 with open('words',encoding='utf-8') as fr,open('.words.bak','w',encoding='utf-8') as fw:
4     for line in fr:
5         new_line = line.replace('','flower')
6         fw.write(new_line)
7 # 先删除原文件,再将新文件名称修改来和原文件一致
8 os.remove('words')
9 os.rename('.words.bak','words')

另关于写入一般使用f.write()写入数据,数据应该是字符串模式,但是利用f.writelines()可以直接写入list,该方法在内部完成了对list的循环。

3、函数

在python中,有很多的内置函数,比如abs()就是取绝对值的函数。这类函数是因为已经提前定义过了,所以可以直接调用。

1 >>>abs(-100)
2 100

如果我们在程序中会重复使用一段代码,就可以将这段代码定义为函数,每次使用时直接调用即可。函数的定义需要使用def语句。

1 def say(name):
2     print('hello,%s'%name)

函数定义整体还包括函数名、括号、括号中的参数、冒号、缩进体中的函数体。函数体主要定义函数的作用,函数体中一般用return返回结果。说到函数的参数,就必须提到形参和实参,直接以下例解释。

1 def calc(a,b):#a,b是形参,在函数中的这两个参数也叫位置参数,为必填参数
2     res = a*b
3     print('%s*%s=%s'%(a,b,res))
4 calc(7,8)#调用函数并传入参数,7和8就是实参

定义函数calc时,a和b就是代表函数calc中需要两个参数,这个就是形参;而后调用calc(7,8),传入的7和8就是实际参数,按照输入位置7默认传给a,8默认传给b。

calc中的函数,直接用print输出了函数计算结果。但是如果我们需要得到a*b的值进行下一步计算呢。这种时候,需要用return返回。在定义calc函数的函数体末尾,直接写入“return res”即可。这样调用函数后可以用一个变量来接收return的值。

return除了返回值外,还可以结束函数。

1 def lainxi():
2     for i in range(5):
3         print(i)
4         if i == 3:
5             return#遇到return,函数结束
6 lainxi()

如上面的函数,在调用时,只会刷出0,1,2,3这四个数,因为当i == 3时,会自动结束函数,不会继续循环了。当函数体中没有return时,会默认返回None,比如下面的判断密码格式的函数。

1 import string
2 def check(pwd):
3     if len(pwd)>5 and len(pwd)<12:
4         if set(pwd)&set(string.ascii_letters) and  set(pwd)&set(string.digits):
5             print('密码合法')
6     else:
7         print('密码不合法')
8 res = check('asd1234')
9 print(res)#函数体中没有return时,默认返回None

最后利用print输入res的值就是None。

4、常量和全局变量

常量就是一个默认不变的值,在python中一般用大写字母定义常量。如:

1 FILENAME = ‘test.txt’

变量是有使用范围的,如在函数体中定义的变量,就只能在函数体中使用,函数体外是不可调用的。而全局变量就是在整个文件中都能被使用的值。比如在下面的代码中:

1 name = '谢红'
2 def sayName():
5     print('name1',name)
6 sayName()
7 print('name2',name)

一开始定义了name = '谢红',那么在函数体中会直接输出时会直接输出已定义的数据,所以上面的代码运行后结果为:

1 name1 谢红
2 name2 谢红

而如果在函数体中对name变量进行了新的赋值。

1 name = '谢红'
2 def sayName():
3     name = '刘伟'
4     print('name1',name)
5 sayName()
6 print('name2',name)

那么函数体中的name变量就是“刘伟”了,但是函数体外的name变量则是“谢红”,所以上面的代码输出结果为:

1 name1 刘伟
2 name2 谢红

如果想要在函数内部修改name变量并影响整个文件,需要先定义name函数为global。

1 name = '谢红'
2 def sayName():
3     global name#如果想在函数内部修改全局变量,就需要先声明一下name是全局变量
4     name = '刘伟'
5     print('name1',name)
6 sayName()
7 print('name2',name)

这样修改后,name就已经被定义为“刘伟”了,函数体外也同样被修改,所以上面代码的输出结果为:

1 name1 刘伟
2 name2 刘伟

全局变量最好不要轻易使用,缺点1是不安全,所有人都可以修改这个数据;缺点2是全局变量会一直占用内存。

5、json串文件和字典的相互转换

在 操作文件的过程中,有时文件内容可能是json串格式的,此时要如何处理呢?在python中有将json串格式文件转化为字典的方法,只需要导入json模块就可以应用了。首先是将json串文件转化为字典。转化方法也有两种,一种是json.loads(),一种是json.load()前者和后者的区别在于,前者必须先将文件内容读出来,然后对文件内容进行操作,后者可以直接对文件进行操作,内部自动完成读出操作。

1 import json
2 f = open('product.json',encoding='utf-8')
3 res = f.read()
4 product_dic = json.loads(res)#json.loads就是将json串变成python的数据类型字典,操作对象为字符串,需要先将文件中的内容读出来
1 import json
2 f = open('product.json',encoding='utf-8')
3 product_dic1 = json.load(f)#用json.load可以不用先将文件中的数据读出,直接对文件进行操作

以上两种方法得到的结果其实是一样的,根据实际情况选择方法使用即可。

可以将json格式的文件转换为字典格式,自然也能反过来转换。同样,将字典格式的文件转化为json串格式也有两种方法,分别是json.dumps()和json.dump()。前后两者的区别是第一种方法只用于转换字典格式的文件为json串格式,必须参数只有字典;而第二种方法必须参数除了字典格式的数据,还包括即将写入json串的文件,可以做到转换写入一步到位。

 1 import json
 2 f = open('product.json',encoding='utf-8')
 3 d = {
 4     'zll':{
 5         'addr':'北京',
 6         'age':28
 7     },
 8     'ljj':{
 9         'addr':'北京',
10         'age':21
11     }
12 }
13 fw = open('user_info.json','w',encoding='utf-8')
14 dic_json = json.dumps(d,ensure_ascii=False,indent=4)#json.dumps方法将字典转化为json串#就这么直接转换的话,格式不好看,需要处理一下
15 fw.write(dic_json)#用json.dumps()方法需要再使用write()方法写入数据
16 dic_json1 = json.dump(d,fw,ensure_ascii=False,indent=10)#用json.dump,入参中包括fw,这样将字典转换后会自动写入文件中,不需要再fw.write()

在代码中ensure_ascii = False和indent = 4或者indent = 10都是优化格式的,可以直接带上。

6、函数不固定参数

在讲定义函数的时候提到了形参和实参,其中calc()函数中的a,b两个参数都是固定参数,也就是必须传入两个参数,不论是不传、少传或者多传都会报错,因为定义时就写明了calc()只有两个固定参数。有时候的确需要传入不确定个数的参数,此时就要用到不固定参数。

1 def syz(*args):#*args表示参数组,将所有参数放进一个元祖中
2     print(args)
3 syz('niuhanyang','233','122',111)

在定义函数syz()时,参数前面加入了一个'*'号,这样的参数可以接受多个传入参数,并将所有传入的参数放入一个tuple中。

1 def sys2(**kwargs):#**kwargs是关键字参数,将传入的参数放入字典中
2     print(kwargs)
3 sys2(name = 'nhy',age = 38)
4 sys2(name = 'nhy',age = 38,addr = '回龙观')
5 sys2(name = 'nhy',age = 38,addr = '回龙观',home = '河南')

而定义函数sys()时,参数前面加了两个‘*’号,这样的参数也可以接受多个传入参数,并将传入的参数放入一个字典中,所以传入的参数必须是key和value对应的数据。

除了这两种不固定参数外,还有默认参数,即不传入数据则为默认值,传入数据则使用传入的值。在函数中,参数的排序也是很重要的。必须以固定参数、默认参数、不固定参数的顺序排序,定义和传入时都要这样,否则函数不知道究竟传入的参数是赋给哪一个形参的,会报错。

7、递归

递归其实就是在函数内部调用函数本身。具体见代码。

def test1():
    num = int(input('number:'))
    if num%2 == 0:#判断输入的数字是否为偶数
        return True#如果为偶数程序退出,返回TRUE
    print('非偶数重新输入')
    return test1()#不是偶数的话调用函数本身重新输入

在函数test1()的函数体中,调用了test1()函数本身,这就是递归函数。其实递归函数也是在循环,而且递归最多999次,否则会溢出,所以并不是一个非常值得使用的方法。

8、模块

在平常的代码编写中,需要用到各种已封装好的方法,有时候这些方法并不是python的内置函数,需要导入模块才能使用。模块其实也是一个python文件,有的模块可以直接调用,有的模块需要先下载安装才能导入使用。模块分为三个部分。

(1)、标准模块、标准包

python自带的这些模块,就是标准模块,直接import就可以使用,比如random、string、datetime等。

(2)第三方模块,别人写好的,需要安装才能使用

安装方法有:①PIP install mokuaiming;②手动安装,首先进入https://pypi.python.org/pypi/redis#downloads下载安装包,如果安装包以.whl结尾,cmd命令首先进入文件存储目录,再运行pip install redis-2.10.6-py2.py3-none-any.whl;如果安装包是tar.gz的安装包,先解压,进入解压出来的文件,在当前窗口运行cmd,再运行命令python setup.py install。

(3)自己写的python文件

9、内置函数
python自带的一些函数,可以直接拿过来用

 1 print(all([1,2,3,4]))#判断可迭代的对象里面的值是否都为真
 2 print(any([0,1,2,3,4]))#判断可迭代的对象里面的值是否有一个为真
 3 print(bin(10))#十进制转二进制
 4 print(bool('s'))#把一个对象转换成布尔类型
 5 print(chr(10))#打印数字对应的ascii
 6 print(ord('b'))#打印字符串对应的ascii码
 7 print(dir(1))#打印传入对象的可调用方法
 8 print(exec('def a():pass'))#执行python代码
 9 print(filter(lambda x:x>5,[12,3,12,2,1,2,35]))#把后面的迭代对象根据前面的方法筛选
10 print(map(lambda x:x>5,[1,2,3,4,5,6]))
11 print(max(111,12))#取最大值
12 print(round(11.11,2))#取几位小数
13 print(sorted([2,31,34,6,1,23,4]))#排序
1 # zip函数
2 l1 = ['a', 'b', 'c']
3 l2 = [1, 2, 3]
4 l3 = ['x', 'y', 'z']
5 # for a, b in l1, l2:
6 #     print(a, b)  # 直接这样遍历是执行不了的
7 for a, b, c in zip(l1, l2, l3):  # zip可以将这几个list合并到一起,变成多维数组
8     print(a, b, c)
9 # 如果l1,l2,l3的长度不一样的话,会以长度最短的那个为标准
 1 # map 用于循环调用函数
 2 def my(num):
 3     return str(num)
 4 lis = [1, 2, 3, 4, 5, 6, 7, 8, 9]
 5 # new_lis = []
 6 # for i in lis:
 7 #     new_lis.append(my(i))
 8 # print(new_lis)
 9 res = list(map(my, lis))  # 结果必须强制转换为list才好print
10 print(res)
 1 # filter 也是用于循环调用函数
 2 def even(num):
 3     if num % 2 == 0:
 4         return True
 5     else:
 6         return False
 7 lis = [1, 2, 3, 4, 5, 6, 7, 8, 9]
 8 res = list(filter(even, lis))   # filter是过滤器,只保留返回为真的数据
 9 res1 = list(map(even, lis))  # map就循环函数,函数返回什么就保存什么
10 print('filter的结果:', res)
11 print('map的结果:', res1)
1 filter的结果: [2, 4, 6, 8]
2 map的结果: [False, True, False, True, False, True, False, True, False]

10、返回多个值的函数

函数是多种多样的,很多时候并不是只有一个返回值,那么当函数的返回值是多个时如何处理呢。比如下面的函数,返回值有三个,分别是num1,num2,num3。

1 def some():
2     num1 = 10
3     num2 = 20
4     num3 = 30
5     return num1,num2,num3

像这样的函数,如果用一个数据去接收返回值,比如res = some(),那么会将返回值储存在元祖中返回,所以res现在接收的是一个元祖,其中包含num1-3三个数据。如果想要分开接收三个数据。则使用res1,res2,res3 = some()即可。此时res1接收的就是return后的第一个返回值也就是num1,依次推类res2 = num2,res3 = num3。

11、匿名函数

这个不是特别了解,函数结构如下:

1 res = lambda x:x*x  lambda函数中,冒号后面的是返回值
2 print(res(2))

x就是函数参数,而冒号后面的为计算公式也是返回的值。这个函数有时候会用于为字典排序。下面这段函数就是根据字典的value进行升序排序,当然res所接受的返回结果并不是一个字典了。其实所谓的排序也不是针对字典而是针对d.items(),所以字典是无序的这个准则并没有被推翻。

1 d = {'a': 8, 'b': 5, 'c': 3}
2 res = sorted(d.items(), key=lambda x: x[1])

12、三元运算符

三元运算符其实就是简洁版的if else判断。也是会用到if else命令。

1 a = 4
2 b = 5
3 c = a if a>b else b#利用三元运算符判断a,b大小并选择某个变量赋值给c
4 if a>b:#利用if else进行判断,和三元运算符判断结果一致
5     c = a
6 else:
7     c = b

 

posted on 2018-04-20 17:18  四方城郭  阅读(312)  评论(0编辑  收藏  举报