之前我们写的代码,都一行一行写,执行的时候,会把文件中所有的代码都会执行。代码不能复用。使用函数可以将公共使用代码封装起来,使用的时候,通过调用函数来实现代码的复用,减轻我们的维护成本。

定义函数

基本语法

通过关键字 def 进行定义函数。 def 后跟函数名,函数名的命名有如下规范:

  1. 函数名中除了_ 不能有其他特殊字符。
  2. 函数名中可以有数字,但是数字不能放在首位。一般都是放在后面。
  3. 函数名可以使用英文,但是不建议使用中文。一般命名都会使用有意义的名字。
    1. # 定义最基本的函数
    2. def f1():
    3. pass
  • f1 为函数名
  • () 每个函数后面都需要有(), 固定的。
  • pass 表示函数的占位符,这个函数还没有实现逻辑,先占个位置。

在搭建框架的时候,可以先把主要函数定义出来,等后续实现,使用 pass 作为占位符。
下面来定义一个 写入文件的函数。

定义函数

  1. def write_file():
  2. with open('hello.txt',mode='w',encoding='utf8') as file:
  3. # 写入文件, whitelines 需要 列表类型的数据
  4. file.writelines(["hello","world"])

将执行的代码放在 函数内部。
函数定义好之后,只是定义好了而已,运行的时候不会执行。只用在调用的时候才能执行。

  1. def write_file():
  2. with open('hello.txt',mode='w',encoding='utf8') as file:
  3. # 写入文件, whitelines 需要 列表类型的数据
  4. file.writelines(["hello","world"])
  5. #调用函数
  6. write_file()

调用函数之后,运行代码就可以看到效果。
image.png

函数的参数

上面的函数定义的时候每次写入文件都是写入到 hello.txt 中,不够灵活,我们希望能够写入到不同的文件中。可以在定义函数的时候设置一个参数。
指定参数

  1. def write_file_name(name):
  2. """
  3. 函数注释: 写入文件的时候提供一个文件名,指定写入的文件
  4. :param name: 要写入的文件名
  5. :return:
  6. """
  7. with open(name,mode='w',encoding='utf8') as file:
  8. file.write("helloworld")
  9. # 调用函数的时候 需给函数传入一个具体值
  10. write_file_name('fanmao.txt')
  11. write_file_name('abc.txt')
  • write_file_name 函数名
  • (name) 函数的参数, name 表示传入的文件名, name 这里类似变量名,可以任意命名,比如也可以改为 filename 等, 需要注意,函数内部使用的时候,要跟(参数名) 要保持一致

image.png
调用函数,传入对应的参数值。运行,可以看到执行结果。
image.png
函数也可以设置多个参数。

  1. def write_file_filename_content(filename,filecontent):
  2. """
  3. 自定义内容写入指定文件
  4. :param filename: 文件名字
  5. :param filecontent: 文件中的内容
  6. :return:
  7. """
  8. with open(filename,mode='w',encoding='utf8') as file:
  9. file.write(filecontent)
  10. write_file_filename_content('china.txt','hahahahaha')

根据函数的功能,可以设置多个参数。

  • 函数的注释, 可以让别人快速的了解这个函数是做什么的。这个注释可以加,也可以不加,规范的做法需要添加注释。

image.png
添加注释的好处就是再调用函数的时候,可以快速知道这个函数的功能。
鼠标移动到函数上可以看到注释。image.png

函数参数的默认值

在定义函数的时候,可以为参数指定默认值。

  1. # 定义函数的时候 使用默认值
  2. def write_file_with_default_contet(filename,filecontent="helloworld"):
  3. """
  4. 定义函数 带有默认值参数
  5. :param filename: 文件名
  6. :param filecontent: 文件内容
  7. :return:
  8. """
  9. with open(filename,mode='w',encoding='utf8') as file:
  10. file.write(filecontent)
  11. # 函数定义的时候 有默认值, 调用的是不传参,运行的时候会自动使用默认值。
  12. write_file_with_default_contet('b.txt') # 使用默认值
  13. write_file_with_default_contet('c.txt',"hahaha") # 不使用默认值

调用的时候,如果有默认值的参数不传值,运行的时候会使用默认值。
传值就会覆盖默认值。

默认值的注意事项:

如果一个函数中有默认值,定义函数的时候,默认值的位置要放在后面,必填值的位置放在前面。上面定义的函数,定义的时候,参数的位置必须是这样 (filename,filecontent="helloworld")
不能将有默认值的参数放在前面 (filecontent="helloworld",filename) 这是错误的。

如果定义的函数 只有一个参数,参数也有默认值,直接定义即可。

  1. def f1(name="xiaoming"):
  2. print(f"hi,{name}")
  3. #调用函数
  4. f1() # 使用默认值
  5. f1("小王")

函数的返回值

在定义的函数中 可以通过return 关键字来设置函数的返回值。比如函数中没有return ,这个函数的值默认为 None
比如下面这个函数

  1. def f1():
  2. a = 1
  3. b = 2
  4. c = a+b
  5. print(f1())

f1() 函数没有返回值。所以打印的时候为 None。
image.png

return 返回值

在函数内部通过使用 return 来返回结果。函数就有值了。

  1. def f1():
  2. a = 1
  3. b = 2
  4. c = a+b
  5. return c
  6. print(f1())

这个函数有 return 关键字,将c的结果return出来, 当调用f1() 函数的时候,就会返回对应的值。 c结果就可以给到f1()。
所以执行结果为 3
image.png
在做一些项目的时候,项目文件中有很多函数,这些函数之间是可以相互来使用的。 举个例子,在做电商的接口测试过程中。可以将每个接口的操作定义为函数。

Python 函数 - 图8

  1. def login():
  2. """
  3. 登录成功之后会返回token值
  4. :return:
  5. """
  6. token = "xxxxxx"
  7. return token
  8. def add_cart():
  9. # 调用login() 函数
  10. t = login() # login() 有返回值,login() 等价于 "abcdedf"
  11. print(f'这里需要使用到login登录接口中的token值,{t}')
  12. add_cart()

执行代码,可以看到 在add_cart() 函数通过调用 login() 函数,就能获取到 login() 函数中的返回值。就可以使用了。
image.png

是否使用return返回值

我们一般在编码的过程中,如果其他函数中有可能用到这个函数的运算结果,那么在定义的时候必须添加返回值。在其他函数中通过调用 来获取函数的返回结果。

加强练习

  1. 定义一个函数,实现 从1—n 之和。(n的值大于等于1) ```python

    计算1—n 之和 (n>=1)

    def add_n(n): return sum(list(range(1,n+1)))

s1 = add_n(10) s2 = add_n(20) print(“计算1-10之和”,s1) print(‘计算1-20之和’,s2)

  1. 在编写程序的时候,也需要考虑异常场景。对上面的程序添加如下需求: 当传入参数值小于1的时候,返回None
  2. ```python
  3. # 计算1--n 之和 (n>=1) 如果传入值 n<1 打印 输入参数必须大于0 ,返回None
  4. def add_n(n):
  5. if n< 1:
  6. print('输入参数必须大于0')
  7. return None
  8. else:
  9. return sum(list(range(1,n+1)))
  10. s1 = add_n(10)
  11. s2 = add_n(20)
  12. print("计算1-10之和",s1)
  13. print('计算1-20之和',s2)
  14. s3 = add_n(-10) # 异常场景
  15. print(s3)
  1. 在做接口测试时候,用户注册接口,每次注册的时候都需要一个手机号码。这个手机号码不能重复的。为了做这个接口,我们可以通过定义一个函数生成一个随机的手机号,这样每次测试注册接口的时候,通过调用这个函数来生成随机手机号码进行注册。

image.png

# 导入python中的随机数生成模块
import random
def get_phone():
    """
    生成一个随机的11手机号码, 手机号码中 前2位 ['13','14','15','17','18']

    :return:
    """
    # 定义一个空的字符串 表示手机号
    phone=""
    # 定义手机号的支持的前两位
    pre_phone = ['13','14','15','17','18']
    # 随机从列表中选择一个 需要使用到随机函数
    p1 = random.choice(pre_phone) # 从列表中随机选择一个元素
    print(p1)
    # 将随机获取的前两位放到手机号中
    phone=phone+p1
    # 生成9位随机的数字 (0,9) 循环9次
    for i in range(9):
        # 生成1位随机数
        n = random.randint(0,9)
        print(n)
        # 将随机数字添加到手机号 n 位数字,数字不能直接跟字符串拼接 str(n) 将数字转换位字符串
        phone = phone+str(n)

    # 循环完成之后将电话号码返回
    return phone


p = get_phone()
print(f"生成随机电话 {p}")
  1. 将下面的代码使用 函数的方式进行封装。

对应的data.csv文件如下
data.csv

# 导入csv  进行 读取数据
import csv
# 打开csv 文件
with open('data.csv',mode='r',encoding='utf8') as f:
    # 使用csv模块提供的方法创建一个对象
    lines = csv.reader(f)
    # 定义一个计数的变量
    count=0
    for line in lines:
        # 打印出文件中的每一行内容
        print(line)
        #循环一次 count值增加1
        count=count+1
        # 前50行数据
        if count<=50:
            # 将内容写入到 txt 文件中
            with open('a.txt',mode='a',encoding='utf8') as fa:
                # whitelines 写入行内容,传入的数据需要列表类型
                fa.writelines(line)
                # 默认没有换行 换行
                fa.write('\n')

        else:
            #后50行内容
            with open('b.txt',mode='a',encoding='utf8') as fa:
                fa.writelines(line)
                # 换行
                fa.write('\n')

分析上面的代码
写入文件有共同的部分,需要进行函数封装。
读取csv文件也可以进行封装, 现在暂时先定义两个函数。

import csv

# 文件写入, 需要提供写入的文件名,以及对应的文件内容。
def write_txt(filename,filecontent):
    """
    写入文件

    :param filename: 文件名
    :param filecontent: 文件的内容
    :return:
    """
    with open(filename,mode='a',encoding='utf8') as f:
        f.writelines(filecontent)
        f.write('\n')




# 读取文件进行封装
def read_csv_file(csvfile):
    # 定义空的列表,主要存放csv文件中的数据
    csv_data = []
    with open(csvfile,mode='r',encoding='utf8') as file:
        lines = csv.reader(file)
        # 使用csv 创建reader对象
        for line in lines:
            # 将每一次读取到的数据存放到 csv_data
            csv_data.append(line)

    #等文件中所有内容都读完,csv_data会保存所有的数据内容,将所有的数据返回
    return csv_data

data = read_csv_file('data.csv')
print("csv文件中的所有的数据",data)

下面演示一下如何使用这些定义好的函数。

import csv

# 文件写入, 需要提供写入的文件名,以及对应的文件内容。
def write_txt(filename,filecontent):
    """
    写入文件

    :param filename: 文件名
    :param filecontent: 文件的内容
    :return:
    """
    with open(filename,mode='a',encoding='utf8') as f:
        f.writelines(filecontent)
        f.write('\n')

# 读取文件进行封装
def read_csv_file(csvfile):
    """
    读取csv文件的内容

    :param csvfile: csv文件的路径
    :return:
    """
    # 定义空的列表,主要存放csv文件中的数据
    csv_data = []
    with open(csvfile,mode='r',encoding='utf8') as file:
        lines = csv.reader(file)
        # 使用csv 创建reader对象
        for line in lines:
            # 将每一次读取到的数据存放到 csv_data
            csv_data.append(line)

    #等文件中所有内容都读完,csv_data会保存所有的数据内容,将所有的数据返回
    return csv_data


def run():
    # 1. 先读取文件内容  data.csv 文件中的内容
    # read_csv_file(r'C:\Users\zengy\PycharmProjects\pythonProject8\data.csv')
    data = read_csv_file('data.csv')
    # print(data)
    # 2. 前50行数据写入到 a.txt 文件中
    for i in range(50):
        print(f'现在写入数据:{data[i]}')
        write_txt('a.txt',data[i])
    # 传入51-100内容到 b文件
    for i in range(50,100):
        write_txt('b.txt',data[i])

run()

作业

  1. 使用python生成随机身份证号(1960-2022出生)。

生成身份证号:
前6位 ** 地区
中间8位 yyyymmdd 年月日
最后4位 随机3位+随机1-9或者X


根据上面的分析
前6位 定义一个函数, 返回随机的地区
中间8位 定义函数, 返回 年月日
最后4位 定义函数


将上面3个函数返回结果拼接在一起,形成一个身份证号
使用到csv文件
gb2260.csv 存放所有的地区码

import csv
import random

def get_area():
    """
    生成随机的6位地区信息
    :return: 6个数字字符串
    """
    # 从csv文件中读取所有的地区码,随机选择一个
    # 定义空的list 用来存放地区码
    area_code=[]
    with open('gb2260.csv',mode='r',encoding='utf8') as file:
        lines = csv.reader(file)
        for line in lines:
            # 每个地区码 都放在list 中
            area_code.append(line)

    # 随机从 所有地区码中选择一个
    code = random.choice(area_code)
    # code 值选择出来是 一个list 需要将list 转换位字符串
    code_str = ''.join(code)  # ''.join(code) 将list 转换位字符串
    # 将随机选择的code 返回
    return code_str


def get_birth():
    """
    生成随机的 出生年月日 1960-2022出生
    :return:
    """

def get_last():
    """
    最后4位

    :return:
    """



code = get_area()
print(f'code值 {code}')

主要点:

  1. 列表转换为字符串
    names = ['helloworld']
    # 转为字符串
    n_str = "".join(names)
    print(n_str,type(n_str))
    

参考答案

import csv
import random

def get_area():
    """
    生成随机的6位地区信息
    :return: 6个数字字符串
    """
    # 从csv文件中读取所有的地区码,随机选择一个
    # 定义空的list 用来存放地区码
    area_code=[]
    with open('gb2260.csv',mode='r',encoding='utf8') as file:
        lines = csv.reader(file)
        for line in lines:
            # 每个地区码 都放在list 中
            area_code.append(line)

    # 随机从 所有地区码中选择一个
    code = random.choice(area_code)
    # code 值选择出来是 一个list 需要将list 转换位字符串
    code_str = ''.join(code)  # ''.join(code) 将list 转换位字符串
    # 将随机选择的code 返回
    return code_str


def get_birth():
    """
    生成随机的 出生年月日 1960-2022出生
    :return:
    """
    # 年份
    year = random.randint(1960,2022)
    # 月份
    month = random.randint(1,12)

    # 日
    # 考虑闰年,月份
    # 如果年份是闰年,并且月份2月, 有29天
    if year%4 == 0 and month == 2:
        day = random.randint(1,29)
    # 在 1,3,5,7,8,10,12 月中 有31天
    elif month in [1,3,5,7,8,10,12]:
        day = random.randint(1,31)
    elif month in [4,6,9,11]:
        day = random.randint(1,30)
    # 如果以上都不是 就是 平年的2月份
    else:
        day = random.randint(1,28)

    # 如果天为个位数 前面添加0
    if day<10:
        day = "0"+str(day)
    # 月份前 01, 02
    if month < 10:
        month = "0" + str(month)

    # 返回年月日
    return f'{year}{month}{day}'


def get_last():
    """
    最后4位

    :return:
    """
    pre_3=""
    for i in range(3):
        n = random.randint(0,9)
        pre_3 = pre_3+str(n)
    last = random.choice(['0','1','2','3','4','5','6','7','8','9','X'])
    # 返回
    return f'{pre_3}{last}'

code = get_area()
dt = get_birth()
lt = get_last()

id = code+dt+lt
print('生成对应的身份证号',id)

视频

python-函数.mp4 (268.73MB)python 函数.mp4 (1.83GB)