zoukankan      html  css  js  c++  java
  • 接口测试学习-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
  • 相关阅读:
    EntityFramework优缺点
    领导者与管理者的区别
    七个对我最好的职业建议(精简版)
    The best career advice I’ve received
    Difference between Stored Procedure and Function in SQL Server
    2015年上半年一次通过 信息系统项目管理师
    Difference between WCF and Web API and WCF REST and Web Service
    What’s the difference between data mining and data warehousing?
    What is the difference between a Clustered and Non Clustered Index?
    用new创建函数的过程发生了什么
  • 原文地址:https://www.cnblogs.com/myyard777/p/8885090.html
Copyright © 2011-2022 走看看