6.1_8 Python3.x入门 P8 【函数】

相关链接



一、函数的定义与调用

1. def是英文define的缩写
2. 函数名称应该能够表达函数封装代码的功能,方便后续的调用
3. 函数调用必须在函数定义的下方(python属于解释型语言,逐行解析、逐行运行)
4. 函数名称的命名应该符合 标识符的命名规则
  a. 可以由字母下划线数字组成
  b. 不能以数字开头
  c. 不能与关键字重名

"""
 @author GroupiesM
 @date 2022/6/29 15:49
 @introduction
    函数:完成指定功能的一段代码
    优点:复用代码、隐藏实现逻辑、提高可维护性、提高可读性便于调试
    语法:
        def 函数名(变量1:类型1,变量2:类型2,...):
            函数体
            返回体 return xxx
    语法简写:
        def 函数名(变量1,变量2,...):
            函数体
            返回体 return xxx
    P.S:
        1.可以没有变量,根据实际业务场景决定
        2.可以没有返回体,根据实际业务场景决定
"""
# 1.定义函数(有返回值)
def sum(a, b):
    c = a * 2 + b
    return c
# 1.调用函数(有返回值)
print(sum(10, 20))  # 40

# 2.定义函数(无返回值)
def print_sum(a, b): print(a * 2 + b)
# 2.调用函数(无返回值)
print_sum(10, 20)  # 40

1.1 函数的注释

  根据PEP 8(Python官方代码风格文档)要求,函数上方、下方各保留2个空行,并且函数名下方使用三引号注释。

import random


def print_params(arg1: str, arg2: str):
    """文档注释:打印参数(函数上方、下方均要空两行,文档注释使用三引号)

    :param arg1: 第一个参数
    :param arg2: 第二个参数
    """
    print(arg1, arg2, sep='\n')


def r_int():
    """文档注释:随即获取1~100的正整数"""
    return random.randrange(1, 100, 1)


print_params(r_int(), r_int())

  可以通过点击代码,选择 View -> Quick Documentation (也可以点击快捷键,但我的MacPro M1没有f1键)快速查看函数的注释内容。

在这里插入图片描述

  显示效果如下:

在这里插入图片描述


二、函数的参数

2.1 参数传递

"""
 @author GroupiesM
 @date 2022/6/29 17:32
 @introduction
    形参:定义函数时,定义的参数变量
    实参:调用函数时,传递的参数
"""
'''定义函数
形参:a,b
'''
def sum(a, b):
    c = a * 2 + b
    return c

'''调用函数
实参:10,20
未指定形参,按函数形参顺序赋值
'''
result = sum(10, 20)
print(result)  # 40

'''
指定形参,按指定赋值
'''
result = sum(b=10, a=20)
print(result)  # 50

2.2 参数默认值

"""
 @author GroupiesM
 @date 2022/6/30 10:10
 @introduction
"""
# 形参b指定默认值为10
def func(a, b=10):
    print(a, b)

"""函数的调用
 形参有默认值的情况下(b=10),
    1.如果实参没有传递值,则使用默认值(b=10)
    2.如果实参指定了值(b=30),则使用指定值(30)
"""
func(100) # 100 10
func(20, 30) # 20 30
# func(a=20, 30) # 报错 - 如果指定参数,需要指定全部参数

2.3 可变参数

"""
 @author GroupiesM
 @date 2022/6/30 10:17
 @introduction
 规则:
    1.从*之后,调用函数时,只能采用关键字进行参数传递

 一、可变参数-位置参数(元组)
    1.定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
    2.使用*定义个数可变的位置形参
    3.结果为一个元组tuple(v1,v2,...)
    4.参考:解压元组
        tup = (4127, 4098, 8637678)
        print(14, 'Jack: {}; Sjoerd: {}; ''Dcab: {}'
              .format(*tup))  # Jack: 4127; Sjoerd: 4098; Dcab: 8637678

二、可变参数-关键字形参(字典)
    1.定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
    2.使用**定义个数可变的关键字形参
    3.结果为一个字典dict{k1:v1,...}
    4.参考:解压元组
        table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
        print(6, 'Jack: {Jack}; Sjoerd: {Sjoerd}; Dcab: {Dcab}'
              .format(**table))  # Jack: 4098; Sjoerd: 4127; Dcab: 8637678
"""
#  一、可变参数-位置参数(元组)
def function_tuple(*args):
    print(args)

function_tuple(10)  # (10,)
function_tuple(10, 20, 30)  # (10, 20, 30)

# 二、可变参数-关键字形参(字典)
def function_dict(**arg):
    print(arg)

function_dict(a=10)  # {'a': 10}
function_dict(a=10, b=20, c=30)  # {'a': 10, 'b': 20, 'c': 30}

def funciton_test(*arg1,**arg2):
    pass

# def funciton_test(*arg1,*arg2): # 两种可变参数,一个函数中只能分别出现1次

2.4 参数*

"""
 @author GroupiesM
 @date 2022/6/30 10:17
 @introduction
 规则:
    1.从*之后,调用函数时,只能采用关键字进行参数传递
"""
def function_star(a, b, *, c, d):
    print(f'{a=},{b=},{c=},{d=}')

function_star(10, 20, d=30, c=40)  # a=10,b=20,c=40,d=30

2.5 多种参数混合

"""
 @author GroupiesM
 @date 2022/6/30 11:29
 @introduction
 规则:
    1. * 和 *args 互斥,不能同时出现
        def func1(a, * , *args): pass # 报错
"""
def func1(a, b): pass

def func2(a, b=10): pass # 有默认值的函数
func2(10,20)

def func3(*args): pass # 可变参数-位置形参
func3(10)
func3(10,)
func3(10,20)

def func4(**args): pass # 可变参数-关键字形参
func4(x=10,y=20)

print('func5')
def func5(a, b, *, c, d, **args2): print(f"{a=},{b=},{c=},{d=},{args2=}") # 混合
func5(10,20,c=30,d=40,f=50) # a=10,b=20,c=30,d=40,args2={'f': 50}

def func6(*args1, **args2): pass # 混合
func6(10,c=50)

print('func7:')
def func7(a, b, *args1, **args2): print(f"{a=},{b=},{args1=},{args2=}")  # 混合
func7(10,20,30,d=40) # a=10,b=20,args1=(30,),args2={'d': 40}

print('func8:')
def func8(a, b=10, *args1, **args2): print(f'{a=},{b=},{args1=},{args2=}') # 混合
func8(10,20,30,d=40) # a=10,b=20,args1=(30,),args2={'d': 40}

三、函数返回值

"""
 @author GroupiesM
 @date 2022/6/29 17:44
 @introduction
    函数的返回值
        函数返回多个值时,结果为元组tuple(v1,v2,...)
"""
# 一、没有返回值
def funcOne():
    print("hello")
funcOne() # hello

# 二、返回一个值
def funcTwo():
   return 'hello'
print(funcTwo()) # hello

# 三、返回多个值
def funcThree():
    return 'hello','python'
print(funcThree()) # ('hello', 'python')

# 三、返回多个值(拆分基数和偶数)
def num_split(num: list):
    odd = []  # 存放奇数
    even = []  # 存放偶数
    obj = []  # 存放其他类型
    for i in num:
        if type(i) == int:
            if i % 2:
                odd.append(i)
            else:
                even.append(i)
        else:
            obj.append(i)
    return odd, even, obj

print(num_split([3, 4, 6, 12, 3.14, 'luna', True, {'doom': 18}]))
'''测试结果
([3], [4, 6, 12], [3.14, 'luna', True, {'doom': 18}])
'''

四、变量的作用域

"""
 @author GroupiesM
 @date 2022/6/30 11:44
 @introduction
 变量的作用域:
    1.程序代码能访问该变量的区域
    2.根据变量的有效范围可分为:全局变量、局部变量
        2.1 全局变量
            函数体外定义的变量,可做用于函数内外
        2.2 局部变量
            在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成为全局变量
"""
# 1.全局变量
name ='luna'
def fun2():
    age=16 # 2.局部变量
    global money # 1.全局变量
    money = 10000
    # 引用1.全局变量 + 2.局部变量
    print(name,age)
fun2()
'''测试结果
luna 16
'''

# 引用1.全局变量
print(name,money)
'''测试结果
luna 10000
'''

# 引用2.局部变量
# print(age) # 不能在函数体外引用局部变量

五、递归函数

嵌套调用函数:一个函数里面又调用了另一个函数。
递归函数:一个函数里面调用了函数自身。


5.1 阶乘

"""
 @author GroupiesM
 @date 2022/6/30 13:41
 @introduction
 递归函数:
    1.函数体内调用了函数本身,这个函数称为递归函数
    2.递归函数需要:递归调佣、递归终止条件
    3.每递归调用一次函数,都会在栈内分配一个栈帧
    4.每执行完一次函数,都会释放相应的空间
"""


# 案例:阶乘
def factorial(num:int):
    if num < 1 :
        print("参数错误,请输入大于1的数字")
        return None
    if num == 1:
        return 1
    else:
        result = num * factorial(num - 1)
        return result

print(factorial(5)) # 120

5.2 斐波那契函数

"""
@author GroupiesM
@date 2022/6/30 14:13
@introduction
斐波那契函数 : 从第三个数起,每个数是前两个数之和

数值      1   1   2  3   5   8   13   21 ...
递归次数   0   0  1   2   3   4   5    6
"""


def _trans_lst_to_dct(lst: list):
   """list格式斐波那契数列转dict格式输出

   :param lst:list形式斐波那契数列
   :return:
   """
   dct = {}
   for i in range(len(lst)):
       dct[f'第{i + 1}位'] = lst[i]
   return dct


def fibonacci(length: int, type: int = 0):
   """获取斐波那契数列

   :param length: 斐波那契数列长度
   :param type: 0=数组格式 1=字典格式
   :return:
   """
   if length < 1 or type not in [0, 1]:
       print('参数异常,请检查传参格式。 length>1,type(0=数组格式 1=字典格式)')
       return
   if type == 0:  # type==0 数组
       if length == 1:
           return [1]
       elif length == 2:
           return [1, 2]
       else:
           lst = _fibonacci_recursion(length - 1)
           return lst
   elif type == 1:  # type==1 字典
       if length == 1:
           return {'第1位': 1}
       elif length == 2:
           return {'第1位': 1, '第2位': 1}
       else:
           lst = _fibonacci_recursion(length - 1)
           return _trans_lst_to_dct(lst)


def _fibonacci_recursion(_recursion_times: int, _lst=None, _order_number=3):
   """斐波那契数列递归方法

   :param _recursion_times: 剩余递归次数
   :param _lst: 存放结果
   :param _order_number:已递归次数
   :return:
   """
   if _lst is None:
       _lst = [1, 1]  # 初始化数列,前两个值为1,1
   if _recursion_times == 1:
       return _lst
   else:
       _lst.append(_lst[len(_lst) - 2] + _lst[len(_lst) - 1])  # 存放当前递归结果:前两位之和
       result = _fibonacci_recursion(_recursion_times - 1, _lst, _order_number=_order_number + 1)  # 获取下一个数字
   return result


print(fibonacci(3))  # [1, 1, 2]
print(fibonacci(5, 0))  # [1, 1, 2, 3, 5]
print(fibonacci(6, 1))  # {'第1位': 1, '第2位': 1, '第3位': 2, '第4位': 3, '第5位': 5, '第6位': 8}


22/06/30

M

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值