python基础知识6——函数

python中函数的定义和使用。

1、函数的分类

python的函数大致可以分三类:内建函数、三方函数、自定义函数。

2、函数的基本使用

  • 2.1、函数的定义
    语法:
    def func():
    	函数体
    
  • 2.2、函数的调用
    func()
    

3、函数的参数

  • 3.1、单个参数

    def test(num):
    	print(num ** 2)
    
    test(3)
    
  • 3.2、多个参数
    语法:

    def func(参数1, 参数2, 参数3, ...):
    	函数体
    

    示例:

    # 两个参数
    def my_sum(a, b):
        print(a + b)
    
    my_sum(2, 3)
    # 关键字传参
    my_sum(b=1, a=5)
    
  • 3.3、不定长参数

    • 3.3.1、通过参数前加*指明传递的参数在函数体中以元组的方式使用
      语法:
    def 函数名(*args):
    	函数体以元组方式使用args
    

    示例:

    def my_sum(*args):
        sum = 0
        for v in args:
            sum += v
        print(sum)
    
    my_sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    
    • 3.3.2、通过参数前加**指明传递的参数在函数体中以字典的方式使用
      语法:
    def 函数名(**args):
    	函数体以字典方式使用args
    
    # 使用
    函数名(名称1=1, 名称2=2, ...)
    

    示例:

    def my_sum(**args):
    	print(args)
    
    my_sum(name="sz", age=12)
    
    • 3.3.3、参数拆包

    元组方式:

    def test(*args):
        # 装包
        print(args)
        # 拆包
        print(*args)
    test(1, 2, 3, 4)
    

    字典方式:

    def my_sum(a, b):
    	print(a, b)
    
    def test(**args):
    	# 装包
    	print(args)
    	# 拆包
    	my_sum(**args)
    test(a=1, b=2)
    
  • 3.4、缺省参数
    语法:

    def 函数名(形参1=默认值1, 形参2=默认值2, ...):
    	函数体中,即使没有传递参数,也会使用默认值正常运行
    

    示例:

    def my_sum(a=1, b=2):
    	print(a + b)
    my_sum()
    
  • 3.5、注意
    1、在python中参数的传递只有引用传递,没有值传递。
    2、如果参数值的数据类型是可变类型,则在函数体中可以改变原件;如果数据类型是不可变类型,在函数体中不会改变原件,如果执行改变操作,则会重新分配空间,原值不会发生任何变化。

4、函数的返回值

  • 语法:
    def 函数():
    	函数体
    	return 返回值
    
  • 示例:
    # 返回一个值
    def my_sum(a, b):
     	return (a + b)
    print(my_sum(1, 3))
    print(my_sum("abc", "def"))
    
    # 返回多个值
    def calculate(a, b):
    	sum = a + b
    	diff = a -b
    	return (sum, diff)
    print(calculate(1, 3))
    

5、偏函数

  • 5.1、概念
    新建一个函数,将部分参数设为默认值来调用旧函数,用于简化函数调用。

  • 5.2、创建方法

    • 1、手动创建
    def test(a, b, c, d=1):
    	print(a + b + c + d)
    
    # 手动创建test的偏函数test2
    def test2(a, b, c=1, d=2):
        test(a, b, c, d)
    test2(1, 2)
    
    • 2、使用内置模块创建偏函数
    def test(a, b, c, d=1):
    	print(a + b + c + d)
    
    import functools
    new_func = functools.partial(test, c=1, d=2)
    new_func(1, 2)
    

6、高阶函数

  • 6.1、概念
    当一个函数A的参数,接收的又是另一个函数时,则把这个函数A称为是高阶函数。
  • 6.2、示例
    • 示例1
    def getkey(x):
    	return x["age"]
    
    l = [{"name":"as", "age": 15}, {"name":"sd", "age": 16}, {"name":"df", "age": 19}]
    result = sorted(l, key=getkey)
    print(result)
    
    • 示例2
    def calculate(a, b, func):
    	print(func(a, b))
    def sum(a, b):
        return a + b
    def diff(a, b):
        return a - b
    
    calculate(6, 3, sum)
    calculate(6, 3, diff)
    

7、返回函数

  • 7.1、概念
    一个函数内部返回的数据是另外一个函数,把这样的操作称为返回函数。
  • 7.2、示例
    def get_func(f):
        def sum(a, b, c):
            return a + b + c
        def diff(a, b, c):
            return a - b - c
    
        if(f == "+"):
            return sum
        elif(f == "-"):
            return diff
    
    r = get_func("+")(1, 2, 3)
    print(r)
    r = get_func("-")(1, 2, 3)
    print(r)
    

8、匿名函数

  • 8.1、概念
    匿名函数也称为"lambda函数",就是指没有名字的函数。
  • 8.1、语法
    lambda 参数1,参数2... : 表达式
    
    说明:
    • 只能写一个表达式, 不能return;
    • 表达式的结果就是返回值;
    • 适用于一些简单的操作处理;
  • 8.3、示例
    示例1:
    r = (lambda a, b : a + b)(3, 2)
    print(r)
    
    func = lambda a, b : a + b
    print(func(4, 3))
    
    示例2:
    l = [{"name":"as", "age": 15}, {"name":"sd", "age": 16}, {"name":"df", "age": 19}]
    result = sorted(l, key=lambda x : x["age"])
    print(result)
    

9、闭包

  • 9.1、概念
    在函数嵌套的前提下,内层函数引用了外层函数的变量,外层函数又把内层函数当作返回值进行返回。这个内层函数和所引用的外层变量,称为闭包。

  • 9.2、语法

    def test():
    	a = 10
    	def test2():
        	print(a)
    	return test2
    
    func = test()
    func()
    
  • 9.3、示例

    def line_config(content, length):
        def draw_line():
            print("-" * (length // 2) + content + "-" * (length // 2))
        return draw_line
    
    line_config("闭包", 20)()
    line_config("test", 20)()
    
  • 9.4、注意事项
    1、闭包中,如果要修改引用的外层变量,需要使用nonlocal变量声明,否则当作是闭包内新定义的变量
    2、当闭包内,引用了一个后期会发生变化的变量时,一定要注意值的变化

10、装饰器

  • 10.1、作用
    在函数名及函数体不改变的前提下,给函数附加一些额外的代码。

  • 10.2、语法

    def prepare(func):
        def pre():
            print("prepare")
            func()
            print("done")
        return pre
    
    @prepare
    def do_something():
        print("doing")
    
    do_something()
    

    上述代码等同于下面的闭包实现:

    def prepare(func):
        def pre():
            print("prepare")
            func()
            print("done")
        return pre
    
    def do_something():
        print("doing")
    
    do_something = prepare(do_something)
    do_something()
    
  • 10.3、注意事项
    装饰器函数的执行时间是立即执行,也就是在@语句时,已经执行了。

  • 10.4、装饰器的叠加
    叠加规则: 从上到下装饰,从下到上执行

    def prepare(func):
        def pre():
            print("prepare")
            func()
        return pre
    
    def prepare1(func):
        def pre():
            print("prepare 1")
            func()
        return pre
    
    def finish(func):
        def pre():
            func()
            print("done")
        return pre
    
    @prepare
    @prepare1
    @finish
    def do_something():
        print("doing")
    
    do_something()	
    
  • 10.5、对有参函数进行装饰

    def prepare(func):
        def pre(*args, **kargs):
            print("prepare")
            # print(args, kargs)
            func(*args, **kargs)
        return pre
    
    @prepare
    def pnum(a):
        print(a)
    
    @prepare
    def pnum2(a, b):
        print(a, b)
    
    pnum(10)
    pnum2(10, 11)
    
  • 10.6、对有返回值函数进行装饰

    def prepare(func):
        def pre(*args, **kargs):
            print("prepare")
            # print(args, kargs)
            return func(*args, **kargs)
        return pre
    
    @prepare
    def pnum(a):
        return a
    
    @prepare
    def pnum2(a, b):
        return a, b
    
    print(pnum(10))
    print(pnum2(10, 11))
    
  • 10.7、带有参数的装饰器

    • 实现方法:
      1、通过@装饰器(参数)的方式,调用这个函数,并传递参数;并把返回值再次当作装饰器使用。
      2、先计算@后面的内容,把这个内容当做是装饰器。
    • 示例:
    def get_prepare(num):
        def prepare(func):
            def pre(*args, **kargs):
                print("prepare", num)
                return func(*args, **kargs)
            return pre
        return prepare
    
    @get_prepare(100)
    def pnum(a):
    	return a
    
    print(pnum(10))
    

11、生成器

  • 11.1、概念
    生成器是一个特殊的迭代器(迭代器的抽象层级更高)。
  • 11.2、创建方式
    • (1)、生成器表达式:
      把列表推导式的[]修改为():
    l = (i for i in range(1, 100) if i % 2 == 0)
    print(l)
    print(next(l))
    print(l.__next__())
    
    • (2)、生成器函数
      • 函数中包含yield语句,这个函数的执行结果就是生成器。
      • yield可以去阻断当前的函数执行,当执行next()函数时会让函数继续执行,当执行下一个yield语句的时候又会被暂停。
    def test():
        print("start")
    
        yield 1
        print("a")
    
        yield 2
        print("b")
    
        yield 2
        print("c")
    
    g = test()
    print(g)
    print(next(g))
    
  • 11.3、send()函数
    send()方法有一个参数,指定的是上一次被挂起的yield语句的返回值。相比于.next(),可以额外的给yield语句传值。第一次调用时,需使用g.send(None)。
    def test():
        print("start")
        for i in range(1, 10):
            ret = yield i
            print(i, ret)
    
    g = test()
    g.send(None)
    g.send("a")
    g.send("b")
    g.send("c")
    
  • 11.4、close()函数
    后续如果继续调用,会抛出StopIteration异常
    def test():
        yield 1
        print("a")
    
        yield 2
        print("b")
    
        yield 3
        print("c")
    
    g = test()
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    g.close()
    

12、作用域

  • 12.1、变量作用域
    变量作用域指的是变量的作用范围,可操作范围。
    python是静态作用域,也就是在python中,变量的作用域源于它在代码中的位置。在不同的位置,可能有不同的命名空间。

  • 12.2、命名空间
    命名空间是作用域的体现形式,不同的具体的操作范围。

  • 12.3、python-LEGB
    L-Local: 函数内的命名空间就。作用范围:当前整个函数体范围;
    E-Enclosing function locals: 外部嵌套函数命名空间。作用范围:闭包函数;
    G-Global: 全局命名空间。作用范围:当前模块(文件);
    B-Builtin: 内建模块命名空间。作用范围:所有模块(文件);

    LEGB规则: 按照 L -> E -> G -> B 的顺序进行查找。

  • 12.4、局部区域修改全局变量
    需要在局部区域中,将全局变量前加global

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值