• python基础教程总结5——函数


    1.函数创建

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

    def functionname( parameters ):
       "函数_文档字符串"
       function_suite
       return [expression]
    

    2.函数参数

      形参:写在def语句中函数名后面的变量通常叫做函数的形式参数,

      实参:而调用函数的时候提供的值是实际参数,或者称为参数;      参数存储在局部作用域(local scope)内。


    2.1 参数的改变:在函数内为参数赋予新值不会改变外部任何变量的值。

    1. def try_to_change(n):
          n = 'Mr. Gumby'
      name = 'Mrs Entity'
      try_to_change(name)
      print name

      运行结果打印"Mrs Entity“。在try_to_change内,参数n获得了新值,但是它没有影响到name变量。n实际上是个完全不同的变量。


    2.2关键字参数:通常我们所使用的参数都叫做位置参数,因为它们的位置很重要——事实上比它们的名字更重要。因此python引入了使用参数名来提供参数,这类使用参数名提供参数就叫做关键字参数。

    def hello_1(greeting,name):
        print '%s, %s!' %(greeting,name)
        
    def hello_2(name,greeting):
        print '%s, %s!' %(name,greeting)
        
    print hello_1('hello','world')
    print hello_2('hello','world')

    #运行结果:
    1. hello, world
    2. None
    3. hello, world
    4. None
    1. def hello_1(greeting,name):
          print '%s, %s!' %(greeting,name)
          
      def hello_2(name,greeting):
          print '%s, %s!' %(name,greeting)
          
      hello_1(greeting='hello',name='world')
      hello_1(name='world',greeting='hello')

      #结果:
      1. hello, world
      2. hello, world

    2.3 参数的默认值:前面提到了关键字参数的一些作用,但关键字参数最厉害的地方在于可以在函数中给参数提供默认值:
    def hello_3(greeting='Hello',name='world'):
        print '%s, %s!' %(greeting,name)
        
    hello_3()
    hello_3('greeting')
    hello_3('greeting','universe')
    #结果:
    1. Hello, world!
    2. greeting, world!
    3. greeting, universe!


     
    2.4 并非真正函数的函数:数学意义上的函数,总在计算其参数后返回点什么。python的有些函数却并不返回任何东西。

    def test():
        print 'This is printed'
        return
        print 'This is not'
    x = test()
    print x
    #运行结果:
    This is printed
    None
     
      这里的return语句只起到结束函数的作用,第二个print语句被跳过了。return语句不返回任何值,那么x又引用什么呢?对,就是第二行的None。所以,所有的函数其实都返回了东西:当不需要它们返回值的时候,它们就返回None。

     
    2.5 可变长度参数
    1 #coding:utf-8       #设置python文件的编码为utf-8,这样就可以写入中文注释
    2 def foo(arg1,*tupleArg,**dictArg):
    3     print "arg1=",arg1  #formal_args
    4     print "tupleArg=",tupleArg  #()
    5     print "dictArg=",dictArg    #[]
    6 foo("formal_args")

      tupleArg前面“*”表示这个参数是一个元组参数,从程序的输出可以看出,默认值为();

      dicrtArg前面有“**”表示这个字典参数(键值对参数)。

      可以把tupleArg、dictArg看成两个默认参数。多余的非关键字参数,函数调用时被放在元组参数tupleArg中;多余的关键字参数,函数调用时被放字典参数dictArg中。

     1 #coding:utf-8       #设置python文件的编码为utf-8,这样就可以写入中文注释
     2 def foo(arg1,arg2="OK",*tupleArg,**dictArg):
     3     print "arg1=",arg1
     4     print "arg2=",arg2
     5     for i,element in enumerate(tupleArg):
     6         print "tupleArg %d-->%s" % (i,str(element))
     7     for  key in dictArg:
     8         print "dictArg %s-->%s" %(key,dictArg[key])
     9 
    10 myList=["my1","my2"]
    11 myDict={"name":"Tom","age":22}
    12 foo("formal_args",arg2="argSecond",a=1)
    13 print "*"*40
    14 foo(123,myList,myDict)
    15 print "*"*40
    16 foo(123,rt=123,*myList,**myDict)
    复制代码

    输出为:

    从上面的程序可以看出:

    (1)如代码第16行。

       参数中如果使用“*”元组参数或者“**”字典参数,这两种参数应该放在参数列表最后。并且“*”元组参数位于“**”字典参数之前。

       关键字参数rt=123,因为函数foo(arg1,arg2="OK",*tupleArg,**dictArg)中没有rt参数,所以最后也归到字典参数中。

    (2)如代码第14行。

      元组对象前面如果不带“*”、字典对象如果前面不带“**”,则作为普通的对象传递参数。

      多余的普通参数,在foo(123,myList,myDict)中,123赋给参数arg1,myList赋给参数arg2,多余的参数myDict默认为元组赋给myList。

     
     
    2.6 参数顺序

      在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数,关键字参数

    def func(a, b, c=0, *args, **kw):
        print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw 

      在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去。

    >>> func(1, 2)
    a = 1 b = 2 c = 0 args = () kw = {}
    >>> func(1, 2, c=3)
    a = 1 b = 2 c = 3 args = () kw = {}
    >>> func(1, 2, 3, 'a', 'b')
    a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
    >>> func(1, 2, 3, 'a', 'b', x=99)
    a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}

      最神奇的是通过一个tuple和dict,你也可以调用该函数:

    >>> args = (1, 2, 3, 4)
    >>> kw = {'x': 99}
    >>> func(*args, **kw)
    a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}

      所以,对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。

          *args是可变参数,args接收的是一个tuple;

          **kw是关键字参数,kw接收的是一个dict。

      参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3))

      关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})

     

    3. 作用域

    3.1作用域分类

      python中的作用域分4种情况:搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。

        L:local,局部作用域,即函数中定义的变量;
        E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
        G:globa,全局变量,就是模块级别定义的变量;

        B:built-in,系统固定模块里面的变量,比如int, bytearray等。

    1 x = int(2.9)  # int built-in
    2  
    3 g_count = 0  # global
    4 def outer():
    5     o_count = 1  # enclosing
    6     def inner():
    7         i_count = 2  # local



    3.2 作用域的产生

      在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码:

    if True:
        x = 1;
    print(x)
    # 1
     

      这个是没有问题的,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用。

    def test():
        x2 = 2
    print(x2)
    # NameError: name 'x2' is not defined
    

    3.3 变量的修改 

      一个不在局部作用域里的变量默认是只读的,如果试图为其绑定一个新的值,python认为是在当前的局部作用域里创建一个新的变量,也就是说在当前局部作用域中,如果直接使用外部作用域的变量,那么这个变量是只读的,不能修改,如:

    1 count = 10
    2 def outer():
    3     print(count)  
    4     count = 100
    5     print(count)
    6 outer()
    7 #UnboundLocalError: local variable 'count' referenced before assignment

      这里第一个print中,使用到了外部作用域的count,这样后面count就指外部作用域中的count了,再修改就会报错。 如果没使用过这个变量,而直接赋值,会认为是新定义的变量,此时会覆盖外部作用域中变量,如:

    1 count = 10
    2 def outer():
    3     count = 100  
    4     print(count)
    5 outer()
    6 #100
     

    内部作用域中直接声明了count=100,后面使用count都是内部作用域的了。 

    3.4 global关键字
      当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:

    1 count = 10
    2 def outer():
    3     global count
    4     print(count)  
    5     count = 100
    6     print(count)
    7 outer()
    8 #10
    9 #100
    

     

    3.5 nonlocal关键字
      global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了

     1 def outer():
     2     count = 10
     3     def inner():
     4         nonlocal count
     5         count = 20
     6         print(count)
     7     inner()
     8     print(count)
     9 outer()
    10 #20
    11 #20
    

      

    3.6 小结:

    (1)变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;

    (2)只有模块、类、及函数才能引入新作用域;

    (3)对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;

    (4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个关键字,就能完美的实现闭包了。

  • 相关阅读:
    Jmeter学习笔记-初级
    python selenium利用 126.com id自动生成
    Python代码无法保存
    卸载python2.7出错
    python pip用法
    pycharm 连接数据库
    Python打包PyPI上传实践
    Python实现Api的Mock测试
    抓包工具使用
    Jenkins+Ant可持续集成Jmeter脚本
  • 原文地址:https://www.cnblogs.com/zxqstrong/p/4646499.html
Copyright © 2020-2023  润新知