zoukankan      html  css  js  c++  java
  • Python_函数

    函数

    函数的定义:函数是指将一组语句的集合通过一个名字(函数名)封装起来,想要执行这个函数,只需调用其函数名即可。

    函数的特性:

    • 减少重复代码;
    • 方便修改,更易扩展;
    • 保持代码的一致性。

    函数名命名规则:

    • 函数名必以下划线或者字母开头,可以包含任意字母、数字或下划线的组合,不能使用任何标点符号;
    • 函数名是区分大小写的;
    • 函数名字不能是保留字。

    语法定义:

    def add(a, b):                                        # 函数名
        print(a + b)
    add(3,7)                                              # 调用函数
                        

    一、函数的参数

    形参与实参:

     形参:形参变量只有在被调用时才分配内存单元,在调用结束时,即可释放所分配的内存单元。因此,形参只有在内部有效。函数的调用结果返回主调用函数后则不能再使用此形参变量。

     实参:实参可以使常量、变量、表达式、函数等,无论实参是任何类型的量,在进行函数调用时,他们都必须有确定的值,以便把这些值传送给形参,因此预先用赋值、输入等办法使参数获得确定值。

    def add(a, b):                                              # a, b 为形参数
        res = a + b
        return res
    c = add(3, 4)                                               # 3, 4 为实参
    print(c)

    函数参数:

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

    必须参数:必须参数必须以正确的顺序传入参数,调用时的数据必须和声明时的一样。

    def mu_info(name, age):
        print('Name:%s 
    Age:%d' % (name, age))
    
    mu_info('wj', 24)

    关键字参数:传入参数的时候带上关键字,即使顺序不对,依然可以辨识。

    def mu_info(name, age):
        print('Name:%s 
    Age: %d' % (name, age))
    
    mu_info(age=24, name='wj')

    默认参数:形参定义时就确定好的值调用参数的时候可以省略。

    必选参数在前,默认参数在后,否则Python解释器会报错,

    当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面,变化小的参数可以作为默认参数。

    def mu_info(name, age, sex='male'):
        print('Name:%s 
    Age: %d 
    sex:%s
    ' % (name, age, sex))
    mu_info('wj', 24)
    mu_info('zl', 24)
    mu_info('cf', 25, 'female')

    不定长参数:不定常参数可以处理比当初声明时更多的参数。不定长参数和其他三种参数不同,声明时不会命名。

    *args指的是接受所有无命名参数

    def add(*args):
        sum = 0
        for i in args:
            sum = sum + i
        print(sum)
    
    add(1, 2, 3, 4)

     **kwargs指的是接受键值对的参数保存方式为字典,进行函数内部运算。

    def print_info(**kwargs):
        for i in kwargs:
            print('%s:%s' % (i, kwargs[i]))
    
    print_info(name='mu', age='18', sex='male', job='Linux', height=180)

    不定长参数的位置:*args只能放左边。**kwargs只能放右边不能改变,实参也要按照这个位置顺序来,不然无法保存。

    def print_info(*args, **kwargs):
    # def print_info(**kwargs,*args):                                                       # 错误示范
        for i in args:
            print(i)
        for o in kwargs:
            print('%s:%s' % (o, kwargs[o]))
    
    print_info('mu', 24, sex='male', job='Linux', height=180)
    # print_info(sex='male', 'mu, 24, job='Linux', height=180)                              # 错误示范
    # print_info(sex='male', job='Linux', height=180, 'mu', 24)                             # 错误示范

    不定长参数+默认参数

      如果有默认参数,放左边。

    def print_info(sex='male', *args, **kwargs):
        print(sex)
        print(args)
        print(kwargs)
    
    # print_info()
    print_info('mu', 1, 2, 3, job='Linux')                  # sex 没有打印,因为传入的参数‘mu’占用了sex的位置,所以单独打印了‘mu’,如不是把它打印在元组中

      标准顺序

    def func(name, age=22, *arge, **kwargs)

    二、函数的作用域

    python中的作用域分4种情况
      L: local,局部作用域,即函数中定义的变量;
      E: enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
      G: globa,全局变量就是模块级别的定义的变量;
      B: built-in,系统固定模块里的变量,比如:int,byrearray等。
    搜索变量的优先级顺序依次是:局部作用域 > 外层作用域 > 当前模块中的全局 > python内置作用域, 也就是LEGB。

    局部作用域不能修改全局作用域的变量,如果想要修改,需要用global声明。

    name = "全局作用域"
    def change_name(name):
        print("打印的是那个?:", name)
        name = "局部作用域"
        print("重新赋值后打印的是那个?:" , name)
    
    change_name(name)
    print("全局作用域是否发生改变?:", name)
    name
    = "全局作用域" def change_name(): global name print("打印的是那个?:", name) name = "局部作用域" print("重新赋值后打印的是那个?:" , name) change_name() print("全局作用域是否发生改变?:", name)

    内层局部作用域不能修改外层作用域的变量,如果想要修改,需要用nonlocal声明。

    def change_one():
        name = "外层作用域"
        print(name)
        def change_two():
            name = "局部作用域"
            print(name)
        change_two()
        print(name)
    change_one()
    
    def change_one():
        name = "外层作用域"
        print(name)
        def change_two():
            nonlocal name
            name = "局部作用域"
            print(name)
        change_two()
        print(name)
    change_one()

    小结:

    1. 变量查找顺序: LEGB,局部作用域 > 外层作用域 > 当前模块中的全局 > python内置作用域
    2. 只有模块、类、及函数才能引入新作用域
    3. 对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量
    4. 内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个关键字,就讷讷个完美的实现闭包了。

    三、函数返回值

    想要获取函数的执行结果,可以用return语句将结果返回。

    注意:

      函数里如果没有return,结束时默认会返回一个None;

      return后可以返回多个对象,如果是多个对象,python会帮我们把多个对象封装为一个元组,元组中的元组就是各个对象;

      函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束。

    def f():
        print('ok')
        return
        # return None                                         # 如果不写,python,默认追加这个
    print(f())

     四、高阶函数

    定义:变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

    高阶函数特点:

    •  函数名可以进行赋值;
    • 函数名可以作为函数参数名还可以作为函数的返回值。

    作为函数名:

    def f(n):
        return n * n
    
    def test(a, b, func):
        res = func(a) + func(b)
        return res
    
    print(test(3, 2, f))

    作为函数的返回值:

    def foo():
        def test():
            return 8
        return test                                                     # 其实此时foo() = test
    
    ret = foo()
    print(ret)                                                          # 打印的就是还没有调用的test,也就是test的内存地址,想要调用,再在后边加()就行,打印出来的就是test的值
    print(ret())
    print(foo())
    print(foo()())

     五、递归函数

    递归的特性:

    • 调用自身的函数;
    • 需要有一个明确的结束条件;
    • 每次进入更深一层递归时,问题规模相比上次递归都应有所减少;
    • 递归能处理的,循环都能处理;
    • 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出) 

     递归算阶乘:

    # 正常算阶乘
    def f(n):
        num = 1
        for i in range(n):
            num = (i + 1) * num
        return num
    print(f(5))
    
    
    # 递归引用自己
    def fact(n):
        if n == 1:
            return 1
        return n * fact(n - 1)
    print(fact(5))

     斐波那契数列:

    # 正常算法
    def f(x):
        a, b = 0, 1
        n = 0
        while n <= x:
            # print(b)
            a, b = b, a + b
            n = n + 1
        return b
    print(f(7))
    
    
    # 引用自己
    def fibo(n):
        if n <= 1:
            return n
        return  fibo(n - 1) + fibo(n -2)
    print(fibo(5))

     六、内置函数

    filter:过滤器,需要两个参数。第一个参数是函数,第二个参数是一个序列,只过滤,不修改。

    str = ['a', 'b', 'c', 'd']
    def fun(n):
        if n != 'a':
            return n
    ret = filter(fun, str)                                        # ret是一个迭代器对象
    print(list(ret))

    map:可对列表进行修改

    str = ['a', 'b', 'c', 'd']
    def fun(n):
        return n + 'mu'
    
    ret = map(fun, str)                                           # ret是一个迭代器对象
    print(list(ret))

    reduce:接收参数时,一个函数f,一个列表,传入reduce的函数必须有两个参数,reduce对list中的每次参数反复调用函数f,并返回最终结果

    from functools import reduce
    def f(x, y):
        return x + y
    print(reduce(f, range(1,10)))

    lambda算法:lambda a, b : a + b

    用内置函数算阶乘

    from functools import reduce
    print(reduce(lambda x, y : x * y, range(1,6)))
  • 相关阅读:
    A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
    Fliptile 开关问题 poj 3279
    Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276
    Aggressive cows 二分不仅仅是查找
    Cable master(二分题 注意精度)
    B. Pasha and String
    Intervals poj 1201 差分约束系统
    UITextField的快速基本使用代码块
    将UIImage转换成圆形图片image
    color转成image对象
  • 原文地址:https://www.cnblogs.com/dmjx/p/7903432.html
Copyright © 2011-2022 走看看