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

    定义:

    函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

    目的:

    函数能提高应用的模块性,和代码的重复利用率。

    分类:

    内建函数、自定义函数。

    你已经知道Python提供了许多内建函数,比如print()。

    但你也可以自己创建函数,这被叫做用户自定义函数。

    举例:

    #!/usr/bin/python3
    
    # 计算面积函数(自定义)
    def area(width, height):
        return width * height
    # 打印问候(自定义) def print_welcome(name): print("Welcome", name)
    print_welcome(
    "Runoob") w = 4 h = 5 # 打印(内建函数) print("width =", w, " height =", h, " area =", area(w, h))

    参数传递

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

    #!/usr/bin/python3
     
    #可写函数说明
    def printinfo( name, age ):
       "打印任何传入的字符串"
       print ("名字: ", name);
       print ("年龄: ", age);
       return;
     
    #调用printinfo函数
    printinfo( age=50, name="runoob" );

    以上实例输出结果:

    名字:  runoob
    年龄:  50

    默认参数

    调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:

    #!/usr/bin/python3
     
    #可写函数说明
    def printinfo( name, age = 35 ):
       "打印任何传入的字符串"
       print ("名字: ", name);
       print ("年龄: ", age);
       return;
     
    #调用printinfo函数
    printinfo( age=50, name="runoob" );
    print ("------------------------")
    printinfo( name="runoob" );

    输出结果:

    名字:  runoob
    年龄:  50
    ------------------------
    名字:  runoob
    年龄:  35

    不定长参数

    你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下

    加了星号(*)的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例:

    #!/usr/bin/python3
     
    # 可写函数说明
    def printinfo( arg1, *vartuple ):
       "打印任何传入的参数"
       print ("输出: ")
       print (arg1)
       for var in vartuple:
          print (var)
       return;
     
    # 调用printinfo 函数
    printinfo( 10 );
    printinfo( 70, 60, 50 );
    以上实例输出结果:

    输出:
    10
    输出:
    70
    60
    50

    变量作用域

    Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。

    变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:

    • L (Local) 局部作用域
    • E (Enclosing) 闭包函数外的函数中
    • G (Global) 全局作用域
    • B (Built-in) 内建作用域

    以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。

    x = int(2.9)  # 内建作用域 B
     
    g_count = 0  # 全局作用域 G
    def outer():
        o_count = 1  # 闭包函数外的函数中 E
        def inner():
            i_count = 2  # 局部作用域 L

    Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:

    >>> if True:
    ...  msg = 'I am from Runoob'
    ... 
    >>> msg
    'I am from Runoob'
    >>> 

    实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的。

    如果将 msg 定义在函数中,则它就是局部变量,外部不能访问:

    >>> def test():
    ...     msg_inner = 'I am from Runoob'
    ... 
    >>> msg_inner
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'msg_inner' is not defined
    >>> 

    从报错的信息上看,说明了 msg_inner 未定义,无法使用,因为它是局部变量,只有在函数内可以使用。 

    全局变量和局部变量

    定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

    局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

    #!/usr/bin/python3
    
    total = 0; # 这是一个全局变量
    total2 = 0; # 这是一个全局变量
    # 可写函数说明
    def sum( arg1, arg2 ):
        #返回2个参数的和."
        total = arg1 + arg2; # total在这里是局部变量.
        print ("函数内是局部变量 : ", total)
        global total2 
        total2 = arg1 + arg2; # total在这里是全局变量.
    return total; 
    
    #调用sum函数 
    sum( 10, 20 );
    
    print ("函数外是全局变量 : ", total)
    print ("函数外是全局变量2 : ", total2)

    以上实例输出结果:

    函数内是局部变量 :  30
    函数外是全局变量 :  0
    函数外是全局变量2 :  30
     

    如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:

    #!/usr/bin/python3
     
    def outer():
        num = 10
        def inner():
            nonlocal num   # nonlocal关键字声明
            num = 100
            print(num)
        inner()
        print(num)
    outer()

    以上实例输出结果:

    100
    100

    另外有一种特殊情况,假设下面这段代码被运行:

    #!/usr/bin/python3
     
    a = 10
    def test():
        a = a + 1
        print(a)
    test()

    以上程序执行,报错信息如下:

    Traceback (most recent call last):
      File "test.py", line 7, in <module>
        test()
      File "test.py", line 5, in test
        a = a + 1
    UnboundLocalError: local variable 'a' referenced before assignment

    错误信息为局部作用域引用错误,因为 test 函数中的 a 使用的是局部,未定义,无法修改。

    其他实际问题:

    1、默认参数必须放在最后面,否则会报:

    SyntaxError: non-default argument follows default argument
    # 可写函数说明
    def printinfo( age=35,name):   # 默认参数不在最后,会报错
        "打印任何传入的字符串"
        print("名字: ", name);
        print("年龄: ", age);
        return;

    2、把N个关键字参数转化为字典:

    >>> def func(country,province,**kwargs):
    ...     print(country,province,kwargs)
    ... 
    >>> func("China","Sichuan",city = "Chengdu", section = "JingJiang")
    China Sichuan {'city': 'Chengdu', 'section': 'JingJiang'}
    >>> 

    3、匿名函数也是可以使用"关键字参数"进行参数传递:

    >>> g= lambda x,y : x**2+y**2
    >>> g(2,3)
    13
    >>> g(y=3,x=2)
    13

    lambda 匿名函数也可以设定默认值

    >>> g= lambda x=0,y=0 : x**2+y**2
    >>> g(2,3)
    13
    >>> g(2)
    4
    >>> g(y=3)
    9

    4、对于变量作用域,变量的访问以 L(Local) –> E(Enclosing) –> G(Global) –>B(Built-in) 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。

    观察以下几个例子,均从内部函数输出变量 x:

    1. 局部作用域

    x = int(3.3)
    
    x = 0
    def outer():
        x = 1
        def inner():
            x = 2
            print(x)
        inner()
    
    outer()

    执行结果为 2,因为此时直接在函数 inner 内部找到了变量 x。

    2.闭包函数外的函数中

    x = int(3.3)
    
    x = 0
    def outer():
        x = 1
        def inner():
            i = 2
            print(x)
        inner()
    
    outer()

    执行结果为 1,因为在内部函数 inner 中找不到变量 x,继续去局部外的局部——函数 outer 中找,这时找到了,输出 1。

    3.全局作用域

    x = int(3.3)
    x = 0
    def outer():
        o = 1
        def inner():
            i = 2
            print(x)
        inner()
    
    outer()

    执行结果为 0,在局部(inner函数)、局部的局部(outer函数)都没找到变量 x,于是访问全局变量,此时找到了并输出。

    4. 内建作用域

    x = int(3.3)
    g = 0
    def outer():
        o = 1
        def inner():
            i = 2
            print(x)
        inner()
    
    outer()

    5、函数也可以以一个函数为其参数:

    def hello () :
      print ("Hello, world!")
    
    def execute(f):
      "执行一个没有参数的函数"
      f()
    
    execute(hello)
    输出:
    Hello, world!

    结束!

  • 相关阅读:
    IDEA热部署插件Jrebel
    Navicat Premium15安装及破解教程
    IDEA中查看类的关系图
    PV、UV、IP名词解释
    Promise由浅入深
    URLSearchParams
    二进制流学习-Blob、ArrayBuffer、File、FileReader和FormData的区别
    前端vue以数据流方式导出word----借助 jquery
    js中 == 、=== 和 Object.is() 的区别
    后端传的是二进制流,前端应该如何通过blob处理二进制文件流格式流,并实现前端下载文件流格式
  • 原文地址:https://www.cnblogs.com/huangsxj/p/8632558.html
Copyright © 2011-2022 走看看