Python 函数,函数参数,变量作用域 (LEGB),递归

函数

简介

函数是一个程序语言的基本功能,函数主要用来封装一个代码块,从而对部分的代码进行封装。

定义函数

定义一个函数需要使用def关键字,依次写出函数名、参数列表、函数体、return返回语句

def 函数名(参数列表):
    函数体

定义一个函数:

def func_abs(x):
    if x >= 0:
        return x
    else:
        return -x
调用函数
f = func_abs(-10)
print(f)  # 10

函数的参数

  • 必备参数
  • 关键字参数
  • 默认参数
  • 不定长参数
必备参数

必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样

def print_info(info):
    print(info)

print_info('输出信息')
关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

def print_info(info1, info2):
    print(info1, info2)

print_info(info2='信息二', info1='信息一')
默认参数

用函数时,如果没有传递参数,则会使用默认参数。

def print_info(name, age=20):
    print(name, age)

print_info('Tom', 10)
print_info('Jake')
不定长参数

加了星号”“的变量args会存放所有未命名的变量参数,args为元组 ;而加”*“的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典。

def print_info(name, *args, **kwargs):
    print(name, args, kwargs)

print_info('Tom', '篮球', '足球', '乒乓球', age=20, height=170, address='beijing')

装包与拆包

  • args和kwargs:*args和 **kwargs是在python的代码中经常用到的两个参数,初学者对这两个参数的理解可能仅仅限于*args是用于接收多余的未命名参数,**kwargs用于接收形参中的命名参数,其中args是一个元组类型,而kwargs是一个字典类型的数据 。
  • 装包:装包的意义就是把未命名的参数和命名的参数放在元组字典中。
  • 拆包:
    1. 解包的意义就是将传递给函数的一个列表、元组、字典拆分成独立的多个元素然后赋值给函数中的参变量。
    2. 解压字典有两种解发,一种用*解的只有key,一种用**解的有key,value。但是这个方法**只能在函数定义中使用。
def func1(*args):
    print(type(args))  # <class 'tuple'>
    print(args)  # 未拆包:(1, 2, 3, 4)
    print(*args)  # 拆包:1 2 3 4

func1(1, 2, 3, 4)  # 装包
def func2(**kwargs):
    print(type(kwargs))  # <class 'dict'>
    print(kwargs)  # 未拆包:{'name': '小明', 'age': 20, 'height': 170, 'address': 'beijing'}
    print(*kwargs)  # 拆包,只输出key:name age height address
    for k, v in kwargs.items():
        print(k, v)

func2(name='小明', age=20, height=170, address='beijing')  # 装包

变量作用域 (LEGB)

变量作用域
  • L (Local) 局部作用域
  • E (Enclosing) 函数范围作用域(闭包函数外的函数中)
  • G (Global) 全局作用域
  • B (Built-in) 内建作用域

在python中,每个变量都会有其生存的作用域,一般的查找变量的时候以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找,如果再没有,那么就会出现报错异常。

b = int(2.9)  # 内建作用域(内置方法属性)

g = 0  # 全局作用域
def outer():
    e = 1  # 闭包函数外的函数中
    def inner():
        l = 2  # 局部作用域
total = 0

def sum(arg1, arg2):
    total = arg1 + arg2
    print('局部变量:%d' % total) # 局部变量:30

sum(10, 20)
print('全局变量:%d' % total) #全局变量:0

当内部作用域想修改外部作用域的变量时,就要用到==global==和==nonlocal==关键字了

total = 0

def sum(arg1, arg2):
    global total
    total = arg1 + arg2
    print('total:%d' % total)  # total:30

sum(10, 20)
print('total:%d' % total)  # total:30
def outer():
    num = 10
    def inner():
        nonlocal num
        num = 100
        print(num)  # 100
    inner()
    print(num)  # 100

outer()

lambda 函数

  • lambda函数是一个匿名函数,使用lambda关键字,函数体比 def 简单很多。

  • lambda函数是匿名的:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数没有名字。

    扫描二维码关注公众号,回复: 2248856 查看本文章
  • lambda函数有输入和输出:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值。

  • lambda函数一般功能简单:单行expression决定了lambda函数不可能完成复杂的逻辑,只能完成非常简单的功能。由于其实现的功能一目了然,甚至不需要专门的名字来说明。

  • 语法: lambda 函数的语法:

    lambda [arg1 [,arg2,.....argn]]:expression
案例
#  函数传递
def func(a, b, opt):
    print('result=%d' % opt(a, b))

func(11, 22, lambda x, y: x + y)
# 排序
sample_list = [{'name': 'Tom'},
               {'name': 'Jake'},
               {'name': '小明'}]
sample_list.sort(key=lambda x: x['name'])
print(sample_list)  # [{'name': 'Jake'}, {'name': 'Tom'}, {'name': '小明'}]

递归函数

一个函数在内部调用自身本身,这个函数就是递归函数

不使用用递归

# 1*2*3*4*5
def calculate_num(num):
    result = 1
    for i in range(1, num + 1):
        result *= i
    return result

result = calculate_num(5)
print(result)  # 120

使用递归相乘

# 1*2*3*4*5
def calculate_num(num):
    if num > 1:
        return num * calculate_num(num - 1)
    else:
        return 1

result = calculate_num(5)
print(result)  # 120

打印1~100

def print_num(start, end):
    if start <= end:
        print(start)
        print_num(start + 1, end)

print_num(1, 100)

猜你喜欢

转载自blog.csdn.net/qq_14876133/article/details/81032512