python学习之函数

函数概述

从实现函数的角度来看,其至少需要想清楚以下 3 点:
• 函数需要几个关键的需要动态变化的数据,这些数据应该被定义成函数的参数。
• 函数需要传出几个重要的数据(就是调用该函数的人希望得到的数据),这些数据
应该被定义成返回值。
• 函数的内部实现过程。

十多年的沙市网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销的优势是能够根据用户设备显示端的尺寸不同,自动调整沙市建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“沙市网站设计”,“沙市网站推广”以来,每个客户项目都认真落实执行。

函数创建和调用

#1). 定义函数:
#def 函数名(参数1, 参数2........):
#函数执行的内容
#2). 定义函数时指定参数和返回值的类型
#def mymax(num1: int, num2: int) -> int:
#代表num1需要传入整形, num2需要传入整形, 返回值必须是整形。
#3). 函数的帮助文档: 三引号

def mymax(num1: int, num2: int) -> int:
    """
    求两数的最大值
    :param num1: 第一个数值
    :param num2: 第二个数值
    :return: 最大值
    """
    #if num1 > num2:
    #return  num1
    #else:
    #return  num2
    return num1 if num1 > num2 else num2

#调用函数
max_num = mymax(2, 1)
print(max_num)

#print(help(mymax))

定义空函数

#定义函数的时候, 函数内部代码不会执行。 只有在调用函数的时候, 才会执行代码的内容.

def login(username: str, passwd: str) -> bool:
    """
    实现用户登录
    :param username: 用户名
    :param passwd: 密码
    :return: 是否登录成功
    """
    pass

login('root', 'westos')

返回值理解:
#定义函数的时候, 函数内部代码不会执行。 只有在调用函数的时候, 才会执行代码的内容.

def login(username: str, passwd: str) -> bool:
    """
    实现用户登录
    :param username: 用户名
    :param passwd: 密码
    :return: 是否登录成功
    """
    if username == 'root' and passwd == 'westos':
        print('login ok')
        return  True
    else:
        print('login fail')
        return False

#没有返回值,默认返回None

result = login('root', 'westos')
print(result)

函数里面可以调用其他函数:

def printOneLine():
    """打印一行提示"""
    print('*'*30)

def printNumLine(num: int):  # num=3
    """打印多行提示"""
    for count in range(num):
        printOneLine()
printNumLine(3)

局部变量:

• 局部变量,就是在函数内部定义的变量
• 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
• 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
#局部变量,就是在函数内部定义的变量, 只在函数内部生效
def save_money(money):
"""存钱"""
#函数内部定义的变量
#如何将局部变量声明为全局变量? global 变量名, 这样操作, 外部就可以访问到该局部变量.
global allMoney
allMoney = 100
print(id(allMoney))
print("存钱前: ", allMoney)
allMoney += money
print("存钱后: ", allMoney)

def view_money():

函数内部定义的变量

allMoney = 500
print(id(allMoney))
print(allMoney)

if name== 'main':
save_money(150)
print(allMoney)

全局变量

#没有在函数内部定义的函数, 我们就称为全局变量。
如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量。
• 在函数外边定义的变量叫做全局变量
• 全局变量能够在所有的函数中进行访问
• 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
• 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的
allMoney = 100

#局部变量,就是在函数内部定义的变量, 只在函数内部生效
def save_money(money):
"""存钱"""
#函数内部定义的变量
#如何将局部变量声明为全局变量? global 变量名, 这样操作, 外部就可以访问到该局部变量.

    global  allMoney
    allMoney = 200
    print("存钱前: ", allMoney)
    allMoney += money
    print("存钱后: ", allMoney)

if __name__ == '__main__':
    save_money(100)
不使用global声明全局变量时不能修改全局变量?
global的本质是声明可以修改全局变量的指向, 即变量可以指向新的数据。

1). 不可变类型的全局变量: 指向的数据不能修改, 不使用global时无法修改全局变量。
2). 可变类型的全局变量: 指向的数据可以修改, 不使用global时可以修改全局变量。

可变数据类型与不可变数据类型在全局变量修改的不同

import  pprint

#定义了两个全局变量
allMoney = 100
operator = []

def save_money(money):
    testCount = 1000
    global  allMoney
    print("存钱之前: ", allMoney, operator)
    allMoney += money
    operator.append("存钱%s元" %(money))
    print("存钱之后: ", allMoney, operator)
    #locals(): 当前局部范围内所有变量组成的“变量字典”。
    print(locals())

if __name__ == '__main__':
    save_money(10)
    #save_money(20)
    #save_money(30)
    ##globals():全局范围内所有变量组成的“变量字典”。
    #pprint.pprint(globals().keys())

默认参数

#def mypow(x, y=2, z=None):
#"""求次方, 默认求2次方"""
#return  x**y

#if __name__ == '__main__':
#print(mypow(2))         # 4  x=2, y=2,z=None
#print(mypow(2, 3))      # 8  x=2, y=3,z=None

#默认参数可以降低调用函数的难度。
def connect_MySQL(user, passwd, host='localhost', port=3306, charset='utf8'):
    print('connect mysql......', user, passwd, host, port, charset)

if __name__ == '__main__':
    connect_mysql(user='root', passwd='redhat')
    connect_mysql(user='root', passwd='redhat', host='172.25.254.197')

可变参数

#形参(必选参数, 默认参数, 可变参数/位置参数,)
#args是形参, 可以任意修改名称.
#
args是可变参数,可以传入1个、2个、3个......个参数。将所有的参数封装成元组, 赋值给变量args.

def square_sum(*args):  # args=(1, 2, 3, 4)
    """
    求多个数值的平方和
    args = (1, 2, 3, 4)
    count   arg   result
    1       1       1
    2       2       1+4=5
    3       3       5+9=14
    4       4       14+16=30
    :return:
    """
    result = 0
    for arg in args:
        result = result + arg ** 2
    return  result

#1). 调用函数
#square_sum(1)
#square_sum(1, 2)
print(square_sum(1, 2, 3))
print(square_sum(1, 2, 3, 4))

关键字参数

import random
print()

#关键字参数允许传入 0 个或任意个含参数名的参数;
#kwargs是形参, 可以任意修改名称, 一般是kwargs
#kwargs是以字典的数据类型存储用户传入的信息
def record_student_info(name, age, **info):
print(name, age, info)

#1). 调用参数
record_student_info('root', 10)
record_student_info('root', 10, hobby='python program', city='西安', english_level='CET-6')

#2). 解包
info = dict(hobby='python program', city='西安', english_level='CET-6')
record_student_info('westos', 10, **info)

匿名函数

匿名函数指一类无须定义标识符的函数或子程序。Python用lambda语法定义匿名函数,
只需用表达式而无需申明。(省略了用def声明函数的标准步骤)
lambda函数的语法只包含一个语句,如下:

mymax = lambda num1, num2 : num1 if num1 > num2 else num2
print(mymax(1, 2))

mypow = lambda x, y=2 :  x**y
print(mypow(2))
print(mypow(2, 3))

lambda函数能接收任何数量的参数但只能返回一个表达式的值
匿名函数当作参数传入:
#应用场合1: 函数作为参数传递

def fun(num1, num2, operator_fun=pow):
    return  operator_fun(num1, num2)

print(fun(2, 3))
print(fun(2, 3, lambda  x, y: x+y))

匿名函数作为参数传递:

from prettytable import  PrettyTable
def show(goods):
    """友好的以表格的方式打印商品信息"""
    table = PrettyTable(field_names=['Name', 'Count', 'Price'])
    for good in goods:
        table.add_row(good)
    print(table)

goods = [
    ("Python核心编程", 200, 378.9),
    ("Java核心编程", 300, 278.9),
    ("Php核心编程", 100, 78.9),
    ("Ruby核心编程", 260, 178.9),
]

print("按照数量进行排序".center(30, '*'))
goods.sort(key=lambda x:x[1])
show(goods)

print("按照价格进行排序".center(30, '*'))
goods.sort(key=lambda x:x[2])
show(goods)

(2018-携程-春招题)
给定一个整形数组, 将数组中所有的0移动到末尾, 非0项保持不变;
在原始数组上进行移动操作, 勿创建新的数组;
• 输入: 数组的记录;0 7 0 2
• 输出: 调整后数组的内容; 7 2 0 0

li = [0, 7, 0, 2]
"""
0   7   0   2
\   \   \   \
1   0   1   0

由小到大:
0   0   1   1
\   \   \   \
7   2   0   0
"""
li.sort(key=lamb
```da  x: 1 if x == 0 else 0)
print(li)
# 递归函数
一个函数在内部调用自己本身,这个函数就是递归函数
需求:
计算阶乘 factorial: n! = 1 * 2 * 3 * ... * n
def factorial(num):
    """通过递归的方式求num的阶乘"""
    #递归退出的条件: num <= 1
    #阶乘循环的内容: num! = num * (num-1)!

    if num > 1:
        result = num * factorial(num-1)
    else:
        result = 1
    return  result

if __name__ == '__main__':
    print("2的阶乘: ", factorial(2))
    print("3的阶乘: ", factorial(3))
    print("4的阶乘: ", factorial(4))

递归实现Fib

from functools import lru_cache@lru_cache(maxsize=1000)
br/>@lru_cache(maxsize=1000)
#1. 递归退出的条件: num=1 or num=2 直接退出递归. F(1)=1,F(2)=1
#2. 递归的规则:F(n)=F(n-1)+F(n-2)
if num == 1 or num == 2:
return 1
else:
return fib(num - 1) + fib(num - 2)

if name== 'main':
print("第5个Fib数列:", fib(5)) # 5
print("第8个Fib数列:", fib(8)) # 21
print("第100个Fib数列:", fib(100))

递归实现汉诺塔:
movecount = 0
def hanoi(n=3, start='A', cache='B', target='C'):
    """

    :param n: 盘子个数
    :param start: 初始塔
    :param cache: 缓冲塔
    :param target: 目标塔
    :return: None
    """
    #递归函数规则:
    #1). 什么情况下退出递归? 当盘子格式n=1是退出递归;
    #2). 递归的规则:
    #- hanoi(n-1, start, target ,cache)
    #- hanoi(1, start,   cache ,target)
    #- hanoi(n-1, cache,  start,target)
    if n == 1:
        print("盘子从%s移动到%s" %(start, target))
        global  movecount
        movecount += 1
    else:
        hanoi(n - 1, start, target, cache)
        hanoi(1, start, cache, target)
        hanoi(n - 1, cache, start, target)
hanoi(4)
print(movecount)

这周作业

判断闰年:

num=int(input("输入:"))
def nian(year):
    return (year %4 ==0 and year % 100 !=0) or (year %400 ==0)
print(nian(num))

99乘法表:

def printLine(row):
    for col in range(1,row+1):
        print("{}*{}={}\t".format(col,row,col*row),end=" ")
    print("")
for row in range(1,10):
printLine(row)

求素数:
素数的特征是除了1和其本身能被整除,其它数都不能被整除的数'

def num(a,b):
    for i in range(a,b):
        f = 0
        for j in range(2,i -1):
            if i % j ==0:
                f = 1
                break
        if f  == 0:
            print(i)
num(100,200)


# 编写“学生管理系统”,要求如下:
# • 必须使用自定义函数,完成对程序的模块化
# • 学生信息至少包含:姓名、年龄、学号,除此以外可以适当添加
# 
# • 必须完成的功能:添加、删除、修改、查询、退出

    import re  # 导入正则表达式模块
    import os  # 导入操作系统模块

    filename = "students.txt"  # 定义保存学生信息的文件名

    def menu():
        # 输出菜单
        print('''
                        学生信息管理系统
            =============== 功能菜单 ===============        
        │   1 录入学生信息                             │
        │   2 查找学生信息                             │
        │   3 删除学生信息                             │
        │   4 修改学生信息                             │
        │   5 排序                                    │
        │   6 统计学生总人数                            │
        │   7 显示所有学生信息                          │
        │   0 退出系统                                 
        ''')

    def main():
        ctrl = True  # 标记是否退出系统
        while (ctrl):
            menu()  # 显示菜单
            option = input("请选择:")  # 选择菜单项
            option_str = re.sub("\D", "", option)  # 提取数字
            if option_str in ['0', '1', '2', '3', '4', '5', '6', '7']:
                option_int = int(option_str)
                if option_int == 0:  # 退出系统
                    print('您已退出学生成绩管理系统!')
                    ctrl = False
                elif option_int == 1:  # 录入学生成绩信息
                    insert()
                elif option_int == 2:  # 查找学生成绩信息
                    search()
                elif option_int == 3:  # 删除学生成绩信息
                    delete()
                elif option_int == 4:  # 修改学生成绩信息
                    modify()
                elif option_int == 5:  # 排序
                    sort()
                elif option_int == 6:  # 统计学生总数
                    total()
                elif option_int == 7:  # 显示所有学生信息
                    show()

    '''1 录入学生信息'''
    def insert():
        stdentList = []        # 保存学生信息的列表
        mark = True  # 是否继续添加
        while mark:
            id = input("请输入ID(如 1001):")
            if not id:  # ID为空,跳出循环
                break
            name = input("请输入名字:")
            if not name:  # 名字为空,跳出循环
                break
            try:
                english = int(input("请输入英语成绩:"))
                python = int(input("请输入Python成绩:"))
                c = int(input("请输入C语言成绩:"))
            except:
                print("输入无效,不是整型数值....重新录入信息")
                continue
            stdent = {"id": id, "name": name, "english": english, "python": python, "c": c}  # 将输入的学生信息保存到字典
            stdentList.append(stdent)  # 将学生字典添加到列表中
            inputMark = input("是否继续添加?(y/n):")
            if inputMark == "y":  # 继续添加
                mark = True
            else:  # 不继续添加
                mark = False
        save(stdentList)  # 将学生信息保存到文件
        print("学生信息录入完毕!!!")

    # 将学生信息保存到文件
    def save(student):
        try:
            students_txt = open(filename, "a")  # 以追加模式打开
        except Exception as e:
            students_txt = open(filename, "w")  # 文件不存在,创建文件并打开
        for info in student:
            students_txt.write(str(info) + "\n")  # 按行存储,添加换行符
        students_txt.close()  # 关闭文件

    '''2 查找学生成绩信息'''
    def search():
        mark = True
        student_query = []  # 保存查询结果的学生列表
        while mark:
            id = ""
            name = ""
            if os.path.exists(filename):  # 判断文件是否存在
                mode = input("按ID查输入1;按姓名查输入2:")
                if mode == "1":
                    id = input("请输入学生ID:")
                elif mode == "2":
                    name = input("请输入学生姓名:")
                else:
                    print("您的输入有误,请重新输入!")
                    search()  # 重新查询
                with open(filename, 'r') as file:  # 打开文件
                    student = file.readlines()  # 读取全部内容
                    for list in student:
                        d = dict(eval(list))  # 字符串转字典
                        if id is not "":  # 判断是否按ID查
                            if d['id'] == id:
                                student_query.append(d)  # 将找到的学生信息保存到列表中
                        elif name is not "":  # 判断是否按姓名查
                            if d['name'] == name:
                                student_query.append(d)  # 将找到的学生信息保存到列表中
                    show_student(student_query)  # 显示查询结果
                    student_query.clear()  # 清空列表
                    inputMark = input("是否继续查询?(y/n):")
                    if inputMark == "y":
                        mark = True
                    else:
                        mark = False
            else:
                print("暂未保存数据信息...")
                return

    '''3 删除学生成绩信息'''

    def delete():
        mark = True  # 标记是否循环
        while mark:
            studentId = input("请输入要删除的学生ID:")
            if studentId is not "":  # 判断要删除的学生是否存在
                if os.path.exists(filename):  # 判断文件是否存在
                    with open(filename, 'r') as rfile:  # 打开文件
                        student_old = rfile.readlines()  # 读取全部内容
                else:
                    student_old = []
                ifdel = False  # 标记是否删除
                if student_old:  # 如果存在学生信息
                    with open(filename, 'w') as wfile:  # 以写方式打开文件
                        d = {}  # 定义空字典
                        for list in student_old:
                            d = dict(eval(list))  # 字符串转字典
                            if d['id'] != studentId:
                                wfile.write(str(d) + "\n")  # 将一条学生信息写入文件
                            else:
                                ifdel = True  # 标记已经删除
                        if ifdel:
                            print("ID为 %s 的学生信息已经被删除..." % studentId)
                        else:
                            print("没有找到ID为 %s 的学生信息..." % studentId)
                else:  # 不存在学生信息
                    print("无学生信息...")
                    break  # 退出循环
                show()  # 显示全部学生信息
                inputMark = input("是否继续删除?(y/n):")
                if inputMark == "y":
                    mark = True  # 继续删除
                else:
                    mark = False  # 退出删除学生信息功能

    '''4 修改学生成绩信息'''

    def modify():
        show()  # 显示全部学生信息
        if os.path.exists(filename):  # 判断文件是否存在
            with open(filename, 'r') as rfile:  # 打开文件
                student_old = rfile.readlines()  # 读取全部内容
        else:
            return
        studentid = input("请输入要修改的学生ID:")
        with open(filename, "w") as wfile:  # 以写模式打开文件
            for student in student_old:
                d = dict(eval(student))  # 字符串转字典
                if d["id"] == studentid:  # 是否为要修改的学生
                    print("找到了这名学生,可以修改他的信息!")
                    while True:  # 输入要修改的信息
                        try:
                            d["name"] = input("请输入姓名:")
                            d["english"] = int(input("请输入英语成绩:"))
                            d["python"] = int(input("请输入Python成绩:"))
                            d["c"] = int(input("请输入C语言成绩:"))
                        except:
                            print("您的输入有误,请重新输入。")
                        else:
                            break  # 跳出循环
                    student = str(d)  # 将字典转换为字符串
                    wfile.write(student + "\n")   # 将修改的信息写入到文件
                    print("修改成功!")
                else:
                    wfile.write(student)  # 将未修改的信息写入到文件
        mark = input("是否继续修改其他学生信息?(y/n):")
        if mark == "y":
            modify()  # 重新执行修改操作

    '''5 排序'''

    def sort():
        show()  # 显示全部学生信息
        if os.path.exists(filename):  # 判断文件是否存在
            with open(filename, 'r') as file:  # 打开文件
                student_old = file.readlines()  # 读取全部内容
                student_new = []
            for list in student_old:
                d = dict(eval(list))  # 字符串转字典
                student_new.append(d)  # 将转换后的字典添加到列表中
        else:
            return
        ascORdesc = input("请选择(0升序;1降序):")
        if ascORdesc == "0":  # 按升序排序
            ascORdescBool = False           # 标记变量,为False表示升序排序
        elif ascORdesc == "1":  # 按降序排序
            ascORdescBool = True          # 标记变量,为True表示降序排序
        else:
            print("您的输入有误,请重新输入!")
            sort()
        mode = input("请选择排序方式(1按英语成绩排序;2按Python成绩排序;3按C语言成绩排序;0按总成绩排序):")
        if mode == "1":  # 按英语成绩排序
            student_new.sort(key=lambda x: x["english"], reverse=ascORdescBool)
        elif mode == "2":  # 按Python成绩排序
            student_new.sort(key=lambda x: x["python"], reverse=ascORdescBool)
        elif mode == "3":  # 按C语言成绩排序
            student_new.sort(key=lambda x: x["c"], reverse=ascORdescBool)
        elif mode == "0":  # 按总成绩排序
            student_new.sort(key=lambda x: x["english"] + x["python"] + x["c"], reverse=ascORdescBool)
        else:
            print("您的输入有误,请重新输入!")
            sort()
        show_student(student_new)  # 显示排序结果

    ''' 6 统计学生总数'''

    def total():
        if os.path.exists(filename):  # 判断文件是否存在
            with open(filename, 'r') as rfile:  # 打开文件
                student_old = rfile.readlines()  # 读取全部内容
                if student_old:
                    print("一共有 %d 名学生!" % len(student_old))
                else:
                    print("还没有录入学生信息!")
        else:
            print("暂未保存数据信息...")

    ''' 7 显示所有学生信息 '''

    def show():
        student_new = []
        if os.path.exists(filename):  # 判断文件是否存在
            with open(filename, 'r') as rfile:  # 打开文件
                student_old = rfile.readlines()  # 读取全部内容
            for list in student_old:
                student_new.append(eval(list))  # 将找到的学生信息保存到列表中
            if student_new:
                show_student(student_new)
        else:
            print("暂未保存数据信息...")

    # 将保存在列表中的学生信息显示出来
    def show_student(studentList):
        from prettytable import PrettyTable
        if not studentList:
            print("(o@.@o) 无数据信息 (o@.@o) \n")
            return
        field_names = ("ID", "名字", "英语成绩", "Python成绩", "C语言成绩", "总成绩")
        table = PrettyTable(field_names=field_names)
        for info in studentList:
            sum_score = info.get('english', 0) + info.get('python', 0) + info.get('c', 0)
            row = list(info.values())
            row.append(sum_score)
            table.add_row(row)
        print(table)

    if __name__ == "__main__":
        main()

运行结果示例:

                        学生信息管理系统

            =============== 功能菜单 ===============        

        │   1 录入学生信息                             │
        │   2 查找学生信息                             │
        │   3 删除学生信息                             │
        │   4 修改学生信息                             │
        │   5 排序                                    │
        │   6 统计学生总人数                            │
        │   7 显示所有学生信息                          │
        │   0 退出系统                                 

    请选择:1
    请输入ID(如 1001):1109
    请输入名字:浅浅
    请输入英语成绩:98
    请输入Python成绩:99
    请输入C语言成绩:80
    是否继续添加?(y/n):n
    学生信息录入完毕!!!

当前标题:python学习之函数
当前URL:http://hbruida.cn/article/jpopii.html