函数基础知识点总结大全

文章目录

  • 函数上
    • 1. 函数简介
    • 2. 函数的参数
      • 2.1 形参和实参
      • 2.2 函数的传递方式
      • 3可变参数
      • 位置参数、默认参数、可变参数的混合使用
  • 函数中
    • 1. 函数的返回值
    • 2. 文档字符串
    • 3. 函数的作用域
      • 全局作用域
      • 函数作用域
        • global用法
    • 4. 命名空间
    • 5. 递归函数
  • 函数下
    • 高阶函数
    • 匿名函数
    • 嵌套函数
    • 闭包
    • 装饰器的引入
    • 装饰器的使用
    • 命名空间

函数上

1. 函数简介

  • 函数也是一个对象
  • 函数用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次调用
    语法
def 函数名([形参1,形参2,形参3....]):
    代码块

注意:
函数名必须符合标识符的规范(可以包含字母、数字、下划线但是不能以数字开头)
print是函数对象 print()是调用函数

2. 函数的参数

2.1 形参和实参

  • 形参(形式参数) 定义形参就相当于在函数内部声明了变量,但是并不是赋值

  • 实参(实际参数)指定了形参,那么在调用函数时必须传递实参,实参将会赋值给对应的形参,简单来说有几个形参就要有几个实参

2.2 函数的传递方式

  • 定义形参时,可以为形参指定默认值。指定了默认值以后,如果用户传递了参数则默认值不会生效。如果用户没有传递,则默认值就会生效
def fn(name,age=18):
    print(f"my name is {name},今年{age}岁了".format(name,age))

fn("小明",20)
def fn(name,age=18):
    print(f"my name is {name},今年{age}岁了".format(name,age))

fn("小明")
# my name is 小明,今年18岁了
  • 位置参数:位置参数就是将对应位置的实参赋值给对应位置的形参

  • 关键字参数 : 关键字参数可以不按照形参定义的顺序去传递,而根据参数名进行传递

def fn(name,age=18):
    print(f"my name is {name},今年{age}岁了".format(name,age))

fn(age=20,name="小花")
# my name is 小花,今年20岁了

注意:所有位置参数必须出现在默认参数前,包括函数定义和调用
函数基础知识点总结大全_第1张图片

def fn(name,love="花",age=18):
    print(f"my name is {name},今年{age}岁了,喜欢{love}".format(name,age))

fn("小花","帅锅",age=20)
#my name is 小花,今年20岁了,喜欢帅锅

3可变参数

在定义函数的时候,可以在形参的前面加上一个*。这样这个形参就可以获取到所有的实参
它将获取到的实参放到一个元组当中*a 会接受所有位置实参,并且会统一保存到一个元组当中

def s(*args):
    # 定义一个变量,保存结果
    r = 0
    # 遍历元祖,将元组中的数进行相加
    for n in args:
        r += n 
    print(r)
s(1,2,6,9)
  • 带星号的形参只能有一个
    def fn2(a,*b,*c):
                 ^
SyntaxError: invalid syntax
def fn2(a,b,*c):
    print('a =',a)
    print('b =',b)
    print('c =',c)

fn2(1,2,3,4,5)
# a = 1
# b = 2
# c = (3, 4, 5)
  • 不定长参数不一定非要写在后面,但是要注意,带*号后面的参数,都必须以关键字参数的形式来进行传递
def fn2(a,*b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)

fn2(1,2,3,4,c = 5)
# a = 1
# b = (2, 3, 4)
# c = 5
def fn2(*,a,b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)

fn2(a = 3,b = 4,c = 5)
a = 3
# b = 4
# c = 5

**形参可以接收其他关键字参数,它会将这些参数统一保存到一个字典当中。
key就是参数的名字,字典的value就是参数的值
**形参只能有一个,并且只能写在所有参数的后面

def fn4(b,c,**a):
    print('a =',a)
    print('b =',b)
    print('c =',c)

fn4(1,2,d=4,e=5)
a = {'d': 4, 'e': 5}
# b = 1
# c = 2

位置参数、默认参数、可变参数的混合使用

基本原则是:先位置参数,默认参数,包裹位置,包裹关键字(定义和调用都应遵循)

def func(name, age, sex=1, *args, **kargs):
    print( name, age, sex, args, kargs)

函数中

1. 函数的返回值

  • 返回值就是函数执行以后返回的结果
  • 通过return来指定函数的返回值
  • return后面可以跟任意对象,返回值甚至可以是一个函数
def s(*args):

    # 定义一个变量,保存结果
    r = 0
    # 遍历元祖,将元组中的数进行相加
    for n in args:
        r += n # r = r + n
    # print(r)
    return r
r = s(1,2,6,9)
print(r - 10)

2. 文档字符串

  • help()是Python中内置函数,通过help()函数可以查询Python中函数的用法
  • 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是对函数的说明

3. 函数的作用域

  • 作用域(scope)
  • 作用域指的是变量生效的区域
  • 在Python中一共有两种作用域

全局作用域

全局作用域在程序执行时创建,在程序执行结束时销毁

  • 所有函数以外的区域都是全局作用域
  • 在全局作用域中定义的变量,都是全局变量,全局变量可以在程序的任意位置进行访问

函数作用域

函数作用域在函数调用时创建,在调用结束时销毁

  • 函数每调用一次就会产生一个新的函数作用域
  • 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问

global用法

  • 使用 global ,可以让 方法内的 局部变量 全局可用,并且在别的文件里也可以引用到
def fun():
   global c
   c =0

fun()
print(c)
  • 在局部函数对全局变量重新赋值
a = 0
b = 0
def fun():
   global a       # 在a  之前添加 global
   a = 2
   b = 2

fun()
print(a)
print(b)

4. 命名空间

  • 命名空间实际上就是一个字典,是一个专门用来存储变量的字典
  • locals()用来获取当前作用域的命名空间
  • 如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间
  • 返回值是一个字典

5. 递归函数

  • 递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题
    递归式函数有2个条件
  • 1.基线条件
    问题可以被分解为最小问题,当满足基线条件时,递归就不执行了
  • 2.递归条件
    可以将问题继续分解的条件
    练习1:
    创建一个函数用递归的方式来解决 求任意数的阶乘
    先分析:
# 10! = 10 * 9!
# 9!= 9 * 8!
# 8! = 8 * 7!
# ....
# 1! = 1

代码

创建一个函数用递归的方式来解决 求任意数的阶乘
def fn1(n):
    # 参数n 要求阶乘的数字

    # 1 基线条件
    # 判断如果n为1的时候,就是它本身就不需要递归了
    if n == 1:
        return 1

    # 2 递归条件8 * 7!
    return n * fn1(n-1)

print(fn1(10))

问题2:定义一个函数 来为任意数字做任意幂运算
分析:

# 10 ** 5 = 10 * 10 ** 4
#  10 ** 4 = 10 * 10 ** 3
# .....
# 10 ** 1 = 10

代码

def fn2(n,i):
    # 参数n 要做幂运算的数字
    # 参数i 要做幂运算的次数

    # 1 基线条件
    if i == 1:
        return n
    #  2 递归条件 10 ** 5 = 10 * 10 ** 4
    return n * fn2(n,i-1)

print(fn2(5,6))
print(5 ** 6)

函数下

高阶函数

  • 接收函数作为参数,或者将函数作为返回值返回的函数就是高阶函数
lst = [1,2,3,4,5,6,7,8,9,10]
# 定义一个函数 实现偶数
def fn2(i):
    if i % 2 == 0:
        return True
# 定义一个函数,将指定列表中的所有的偶数,保存到一个新的列表
def fn(func,l):
    # 参数func:需要传递一个函数对象,其实这个函数对象就是我们想要的一个规则
    # 参数l:要进行筛选的列表

    # 创建一个新的列表
    new_lst = []

    # 对列表进行遍历在筛选
    for n in l:
        # 判断n的奇偶
        if func(n):
            new_lst.append(n)
    # 返回新的列表
    return new_lst

print(fn(fn2,lst))               

匿名函数

匿名函数 lambda表达式
lambda函数表达式可以用来创建一些简单的函数,它是函数的另一种创建方式
语法 lambda 参数列表 : 返回值

定义一个函数 实现2个数的和

def fn(a,b):
    return a + b

print(fn(1,2))

print(lambda a,b : a + b)

嵌套函数

  • 在一个函数里面嵌套一个函数
def waihanshu():
    def neihanshu():
        print('内函数调用了')
    neihanshu() #内部函数需要在调用,要不只调用外部函数的功能
    print('我是外函数')
waihanshu()
# 内函数调用了
# 我是外函数

注意:不能在 外面单独的调用其内嵌函数

闭包

  • 定义:闭包是一个可以由另一个函数动态生成的函数,并且可以改变和存储函数外创建的变量的值
  • 将函数作为返回值也是高阶函数我们也称为闭包

闭包的好处

  • 通过闭包可以创建一些只有当前函数能访问的变量

  • 可以将一些私有数据藏到闭包中

  • 行成闭包的条件:

  • 函数嵌套

  • 将内部函数作为返回值返回

  • 内部函数必须要使用到外部函数的变量

>>> def fun():
...  a = 1
...  def fun1():
...      return a
...  return fun1
...
>>> f = fun()
>>> print(f())
1

在函数 fun() 里面,有 a = 1 和 函数 fun1() ,它们两个都在函数 fun() 的环境里面,但是它们两个是互不干扰的,所以 a 相对于 fun1() 来说是自由变量,并且在函数 fun1() 中应用了这个自由变量 – 这个fun1() 就是我们所定义的闭包。闭包实际上就是一个函数,但是这个函数要具有 1.定义在另外一个函数里面(嵌套函数);2.引用其所在环境的自由变量。上述例子通过闭包在 fun() 执行完毕时,a = 1依然可以在 f() 中,即 fun1() 函数中存在,并没有被收回,所以 print(f()) 才得到了结果

>>> def fun(a,b,c):
...  def para(x):
...      return a*x**2 + b*x + c
...  return para
...
>>> f = fun(1,2,3)
>>> print(f(2))
11

上面的函数中,f = fun(1,2,3) 定义了一个一元二次函数的函数对象,x^2 + 2x + 3,如果要计算 x = 2 ,
该一元二次函数的值,只需要计算 f(2) 即可

装饰器的引入

  • 我们可以直接通过修改函数中的代码来完成需求,但是会产生以下一些问题
  • 如果修改的函数多,修改起来会比较麻烦
  • 不方便后期的维护
  • 这样做会违反开闭原则(ocp)
  • 程序的设计,要求开发对程序的扩展,要关闭对程序的修改

装饰器的使用

  • 通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展
  • 在开发中,我们都是通过装饰器来扩展函数的功能的
  • 写一个计算加法代码,并装饰计算时间的功能
import time
def count_time(f):
#f指的是要装饰的函数,
    def call_fun(*args,**kwargs):
#因为不确定要输入什么类型的参数,所以用*args,**kwargs表示形参
        print("开始计算")
        t1 = time.time()
        time.sleep(2)
        f(*args,**kwargs)
        t2 = time.time()
        t = t2-t1
        print("一共用时{0}".format(t))
        print("结束计算")
#最后返回函数,实现闭包功能,即可以在函数外部,调用内部函数
    return call_fun
@count_time#装修函数,此行代码等同于yunsuan =count_time(yunsuan),可看代码3分析
def yunsuan(a,b):
    s=a+b
    # print(s)
    return s

s = yunsuan(8,5)

print(s)

开始计算
一共用时2.0007264614105225
结束计算
None

结果发现返回值为None,原因是在装修器内没有返回值,可定义一个参数结束函数返回值,并return一下
代码改后如下:

import time
def get_time(f):
#f指的是要装饰的函数,
    def call_fun(*args,**kwargs):
#因为不确定要输入什么类型的参数,所以用*args,**kwargs表示形参
        print("开始计算")
        t1 = time.time()
        time.sleep(2)
        
        r=f(*args,**kwargs)#调用要修饰的函数,并接受返回值
    
        t2 = time.time()
        t = t2-t1
        print("一共用时{0}".format(t))
        print("结束计算")
        return r#不要忘了返回
    return call_fun#最后返回函数,实现闭包功能,即可以在函数外部,调用内部函数

@get_time#装修函数,此行代码等同于yunsuan =count_time(yunsuan),可看代码3分析
def yunsuan(a,b):
    s=a+b
    # print(s)
    return s

s = yunsuan(8,5)

print(s)

代码3:不使用装饰器

import time
def count_time(f):
    def call_fun(*args,**kwargs):

        print("开始计算")
        t1 = time.time()
        time.sleep(2)
        r = f(*args,**kwargs)
        t2 = time.time()
        t = t2-t1
        print("一共用时{0}".format(t))
        print("结束计算")
        return r

    return call_fun

def yunsuan(a,b):
    s=a+b
    # print(s)
    return s
#***********************************************************
yunsuan =count_time(yunsuan)
s = yunsuan(8,5)

print(s)

总结步骤:

  • 给fn2函数扩展功能fn1
#第一步
def fn1(f):
#f指的是要装饰的函数,
    def call_fun(*args,**kwargs):
#因为不确定要输入什么类型的参数,所以用*args,**kwargs表示形参
       #此处可以添加需要扩展功能代码,,,,,,,,,    
         
        r=f(*args,**kwargs)#调用要修饰的函数,并接受返回值
    
        #此处可以添加需要扩展功能代码,,,,,,,,,
        
        return r#不要忘了返回
    return call_fun#最后返回函数,实现闭包功能,及可以在函数外部,调用内部函数
#第二步
@fn1#装修函数
def fn2(*args,**kwargs):
    #代码功能
    return “需要返回的数据”

#第三步
#调用函数


参考代码

参考代码2

推荐b站视频讲解

命名空间

实际上没有太大价值

# locals()来获取当前作用域的命名空间 返回的是一个字典
a = 10

def fn():
    print('我是函数fn....')

scope = locals()
print(scope)

你可能感兴趣的:(python)