• 接口测试学习-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
  • 相关阅读:
    服务限流原理及算法
    Kafka 与 RabbitMQ 如何选择使用哪个?
    分布式事务之最终一致性实现方案
    如何在Ubuntu 14.04中使用systemctl?
    postgresql13 for window 安装及备份还原数据
    手把手教大家在mac上用VMWare虚拟机装Ubuntu
    在Mac平台上使用Multipass安装Ubuntu虚拟机
    如何在markdown中插入js和css
    HTML5标签
    linux
  • 原文地址:https://www.cnblogs.com/myyard777/p/8885090.html
Copyright © 2020-2023  润新知