函数基础篇——Python基础篇之函数

1.函数的理解

提升代码的复用,减少代码的重复编写

2.函数的定义与调用

#函数的定义
def 函数名(形参)
    函数体



#接下来我们定义一个判断质数的函数来深入了解 函数构造

def is_prime(num):
    for i in range(2,num):
        if num % i == 0
            return False  #如果被整除了 则证明不是质数  返回False
    else:
        return True  #如果不能被整除 则返回 True

#函数已经定义好了,如何调用呢?

#通过定义的函数名称来调用函数

num = int(input())  #接受用户输入的数字

result = is_prime(num)  #给函数传入实参,使用return接收返回值

print(result)

3.函数的形参与实参

上面案例中提到了函数的形参与实参,接下来我们深入了解一下

  • 形参:形式参数,声明函数 用一个变量名代表这里需要传入一个真实值
  •     :param num :形式参数num 没有具体值
  • 函数声明时,出现在小括号中,多个形参使用逗号分隔开
  • 形参没有具体值,需要接受实参

  • 实参:实际参数,调用函数时,使用的真实值
  • 函数调用时,出现在小括号中,多个实参使用逗号分隔开
  • 实参有具体值,传递给形参

4.函数的返回值

根据上面案例我们可以得知:

返回值就是函数的输入,经过函数内部的计算,将计算结果返回,函数执行结束

注意事项

  •     如果没有写return
  •         返回None
  •     函数运行到return
  •         后续代码不再继续执行
  •     return后面可以跟多个值
  •         返回一个元组

5.函数参数类型

1)位置参数

        按照顺序依次赋值

def my_fun(num1,num2,num3):  #这里的形参没有具体值
    print(num1,num2,num3)

#调用我们定义的函数

my_fun(a,b,c)  #这里我们三个实参会按照顺序依次照应num1,num2,num3
#输出  a,b,c

2)默认参数

        拥有默认值,如果赋予新值,则使用新值,否则使用默认值

def my_log(string, m=1, n=2):
    print('打印{}'.format(string), m, n)

my_log('213')  #给string传入'213'则会打印出'213',m和n没有传入参数,则输出默认值,1和2
#输出  '213',1,2


def my_log(string, m=1, n=2):
    print('打印{}'.format(string), m, n)

my_log('213',2,3)  #当我们给默认参数赋值时,则会打印出我们传入的值
#输出'213',2,3

3)关键字参数

        通过形参名给形参赋值

def my_log(string, m=1, n=2):
    print('打印{}'.format(string), m, n)

my_log('213',n=3)  #由于参数会按照顺序依次传入,我们不给m赋值,想直接给n赋值是办不到的,此时
                    #使用关键字传参就可以跳过m,直接给n赋值。
#输出'213',1,3

4)可变参数:               

  • 可变元组参数
    def my_fun(m, *args):  #*args 可以接手多个参数并转换为元组
        print(m, *args,type(m),type(args))  
    my_fun(1,2,3,1,2)  #调用函数,输出1 2 3 1 2 <class 'int'> <class 'tuple'>

  • 可变字典参数 

def my_fun(**kwargs):
    total = []
    for key, item in kwargs.items():
        total += item
    return total


dict_test = {'1': 'a', '2': 'b', '3': 'c', '4': '5'}
print(my_fun(name='1'))
print(my_fun(name='1', **dict_test))  #要传入字典需要  **进行系列解包操作

# 输出 
# ['1']
# ['1', 'a', 'b', 'c', '5']

6.函数变量的作用域

 在声明以后的代码区域才可以使用

循环外部不要使用循环内部定义的局部变量
    非强制

循环内部定义的局部变量 作用域是函数内部
    函数外部不能使用

函数内部可以直接获取函数外部定义的变量
    函数内部修改全局变量用global
    函数内部修改外部函数的局部变量用nonlocal

7.递归函数

        什么是递归函数?

                1、如果通过一个对象自身的结构来描述或部分描述该对象,就称为递归。

                2、递归函数即自调用函数,在函数内部直接或间接地自己调用自己,即函数的嵌套调用是函数本身

         递归函数的原理

                1、递归函数之所以能够实现,关键是系统使用堆栈来保存函数调用中的传值参数、局部变量和函数调用后的返回地址。函数自身调用进行堆栈:系统把有关参数和地址压入堆栈,一直递推到满足终止条件,找到问题的最基本模式为止。然后进行回归:系统从堆栈中逐层弹出有关参数和地址,执行地址所指向的代码,一直到栈为空为止,问题得到解决。

        递归函数的优缺点

                随着递归深度的增加,需要维护很大的函数调用栈,开销太大
                效率较低,尽量不要用

                优点:

                 1、递归使代码看起来更加整洁、优雅;

                 2、可以用递归将复杂任务分解成更简单的子问题;

                 3、使用递归比使用一些嵌套迭代更容易。

                缺点:

                  1、递归的逻辑很难调试、跟进;

                  2、递归调用的代价高昂(效率低),因为占用大量的内存和时间

下面根据一个实例来详细讲解递归数列

使用递归数列来实现获取第n个斐波那契数字:
1 1 2 3 5 8 13 21 ……
我们先观察数列的规律
不难发现 第n个数是前两个数字之和


def hinami(n):
    if n ==1 or n == 2:
        return 1
    else:
        return hinami(n-2) + hinami(n-1)
print(hinami(5)) #结果为5
当n=5时,为了更直观的感受,我们来罗列一下数列

5 = hinami(4) + hinami(3)
    hinami(3) + hinami(2) + hinami(2) + hinami(1)
    hinami(2) + hinami(1) + hinami(2) + hinami(2) + hinami(1)
    1 + 1 + 1 + 1 + 1 = 5

上面提到  随着递归深度的增加,需要维护很大的函数调用栈,开销太大 所以不建议使用

这里举个例子来具体演示一下

在Python中 默认递归深度为999,当超过这个深度时系统就会报错


如果我们一定要使用递归数列,那么如何解决这个深度限制呢?


这里我们插入sys
import sys
sys.getrecursionlimit(),'默认最大递归深度'
sys.getrecursionlimit(),'设置最大递归深度'


使用以上方法就可以解决最大递归深度问题啦

8.匿名函数

        匿名函数基础

                首先我们了解匿名函数的格式

lambda argument1,argument2,argument3 : epression  #前面是形参接受我们传入的实参,
                                                  #冒号后面是函数体

 

squre = lambda x : x**2
squre(3) #输出9

上面的函数其实就相当于
def squre(x):
    s = x ** 2
    return s


lambda是一个表达式,并不是一个语句
通常我们用匿名函数的目的就是以下几点:
    一、减少代码的重复性,
    二、模块化代码。


一个函数,但它非常简短,只需要一行就能完成,
同时它在程序中只被调用一次。那么这种情况,
就可以是匿名的,只需要在适当的地方定义并使用,
从而发挥匿名函数的作用。

9.装饰器

目的
    不改变函数原有实现,给函数添加新功能

本质
    闭包
        1.外部函数嵌套内部函数
        2.外部函数把内部函数返回
        3.内部函数获取外部函数局部变量
    @语法糖

#定义一个装饰器

def login_check(f):              #2外部函数返回 内部函数check(返回的是个函数,但是没有调用)
    def check():
        user = input("输入用户名")
        psd = input('请输入密码')
        if user == 'a' and psd == '123'
            f()
        else:
            print('输入错误')
    return check  #注意这里返回不要加()  加括号之后函数就被调用了

method1 = login_check(sys_shop)  #1调用验证方法,传入实参  #3把check赋值给method1
method1()                        #4 method1()  加小括号调用check方法,此时check中的f是我们
                                 #传入的实参sys_shop
def sys_shop():
    print('欢迎进入购物系统')



上面就是一个简易的装饰器,我们调用装饰器时每次都要输入
method1 = login_check(sys_shop)
method1() 
可以使用下面这个方法来代替上面两行
@login_check   #这就相当于上面的这两行代码
def sys_shop()
print('欢迎进入购物系统')  #当系统读取到@时会自动认为下面是被包装的函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值