zoukankan      html  css  js  c++  java
  • python函数详解

    函数

      如果在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数。

      函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
    函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

    定义函数

    可以定义一个由自己想要功能的函数,以下是简单的规则:

    • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
    • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
    • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    • 函数内容以冒号起始,并且缩进。
    • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
    def functionname( parameters ):
       "函数_文档字符串"
       function_suite
       return [expression]
    

    默认情况下,参数值和参数名称是按函数声明中定义的的顺序匹配起来的。

    函数的文档说明

    >>> def test(a,b):
    ...     "用来完成对2个数求和"
    ...     print("%d"%(a+b))
    ... 
    >>> 
    >>> test(11,22)
    33
    

    如果执行,以下代码

    >>> help(test)
    能够看到test函数的相关说明
    
    Help on function test in module __main__:
    
    test(a, b)
        用来完成对2个数求和
    (END)
    

    调用函数

      定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。

      这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。

      调用函数很简单的,通过 函数名() 即可完成调用

    参数传递

     在 python 中,类型属于对象,变量是没有类型的:

    a=[1,2,3]
    
    a="Runoob"
    

      以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是 List 类型对象,也可以指向 String 类型对象。

    可更改(mutable)与不可更改(immutable)对象

      可更改(mutable)与不可更改(immutable)对象在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象

    • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
    • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

    python 函数的参数传递:

    • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
    • 可变类型:类似 c++ 的引用传递,如** 列表,字典**。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

      python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象

    python 传不可变对象实例

    def ChangeInt( a ):
        a = 10
    
    b = 2
    ChangeInt(b)
    print(b) # 结果是 2
    

      实例中有 int 对象 2,指向它的变量是 b,在传递给 ChangeInt 函数时,按传值的方式复制了变量 b,a 和 b 都指向了同一个 Int 对象,在 a=10 时,则新生成一个 int 值对象 10,并让 a 指向它。

    传可变对象实例

    # 可写函数说明
    def changeme( mylist ):
       "修改传入的列表"
       mylist.append([1,2,3,4]);
       print("函数内取值: ", mylist)
       return
     
    # 调用changeme函数
    mylist = [10,20,30];
    changeme( mylist );
    print ("函数外取值: ", mylist)
    

    实例中传入函数的和在末尾添加新内容的对象用的是同一个引用,故输出结果如下:

    函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
    函数外取值:  [10, 20, 30, [1, 2, 3, 4]]
    

    参数

    以下是调用函数时可使用的正式参数类型:

    • 必备参数
        必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
    • 关键字参数
        关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
        使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
    • 默认参数
        调用函数时,如果没有传递参数,则会使用默认参数。
    • 不定长参数
        你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。

    下面用几个例子来解释,前三个比较简单,主要是不定长参数。

    #必备参数,调用时必须传入一个字符串
    def printme( str ):
       "打印任何传入的字符串"
       print (str)
       return
    
    #关键字参数,及在调用方法时,直接写“变量=值”
    def printinfo( name, age ):
       "打印任何传入的字符串"
       print ("名字: ", name);
       print ("年龄: ", age);
       return;
     
    #调用printinfo函数
    printinfo( age=50, name="runoob" );
    
    #默认参数,直接在定义函数时传入值
    def printinfo( name, age = 35 ):
       "打印任何传入的字符串"
       print ("名字: ", name);
       print ("年龄: ", age);
       return;
     
    #调用printinfo函数
    printinfo( age=50, name="runoob" );#名字:  runoob  年龄:  50
    print ("------------------------")
    printinfo( name="runoob" );#名字:  runoob  年龄:  35
    
    
    

    不定长参数比较复杂单独讲

    格式为 

    def functionname([formal_args,] *args,**kwargs ):
       "函数_文档字符串"
       function_suite
       return [expression]
    

      加了星号(*)的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数,它就是一个空元组。
      加了两个星号(**)的来把多个关键字参数转化为字典,可以对元祖/字典进行拆包。
      

      注:“args”参数表示未知的位置参数序列长度,而“**kwargs”代表包含关键字和值映射关系的字典,它可以包含任意数量的关键字和值映射,并且在函数定义中“args”必须位于“**kwargs”前面。

    def test(a, b, c=33, *args, **kwargs):  # 在定义的时候 *,**用来表示后面的变量有特殊功能
        print(a)
        print(b)
        print(c)
        print(args)
        print(kwargs)
    
    
    # test(11,22,33,44,55,66,77,task=99,done=89)
    """
    11
    22
    33
    (44, 55, 66, 77)
    {'task': 99, 'done': 89}
    """
    
    A = (44, 55, 66)
    B = ({"name": "wang", "age": 18})
    
    test(11, 22, 33, *A, **B)  # 在实参中*,**表示对元祖/字典进行拆包
    """
    11
    22
    33
    (44, 55, 66)
    {'name': 'wang', 'age': 18}
    """
    

    return语句(函数返回)

      return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。

    函数可以返回一个值也可以返回多个值
    例子

    def test():
        a = 11
        b = 22
        c = 33
    
        # 第1种,用一个列表来封装3个变量的值
        #d = [a,b,c]
        # return d
    
        # 第2种
        # return [a, b, c]
    
        # 第3中
        # return (a,b,c)
    
        return a,b,c # 本质封装为元组
    
    num = test()
    print(num)
    

    由此函数可分为4种

    • 无参数,无返回值
    • 无参数,有反回值
    • 有参数,无返回值
    • 有参数,有返回值
  • 相关阅读:
    LeetCode 515. 在每个树行中找最大值(Find Largest Value in Each Tree Row)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 1022. 从根到叶的二进制数之和(Sum of Root To Leaf Binary Numbers)
    LeetCode 897. 递增顺序查找树(Increasing Order Search Tree)
    LeetCode 617. 合并二叉树(Merge Two Binary Trees)
    LeetCode 206. 反转链表(Reverse Linked List) 16
    LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)
    LeetCode 110. 平衡二叉树(Balanced Binary Tree) 15
    LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14
  • 原文地址:https://www.cnblogs.com/yangliguo/p/7921402.html
Copyright © 2011-2022 走看看