zoukankan      html  css  js  c++  java
  • Python——函数

    1. 函数   

    (1)特点

      可读性强、复用性强

    (2)定义

      def funcname():  

        funcbody  

        return  

    (3)调用

      funcname()

    (4)注释

    def func():
        '''
        这个函数实现了什么功能
        参数1:解释
        参数2:解释
        ...
        :return: 返回值类型
        '''
        #funcbody函数体

    (5)注意事项

      只定义不调用就一定不执行

      先定义后调用

    2. 返回值

      返回的重要性---不能使用函数调用结束的结果进行其他操作

      函数名()——不接收返回值

      返回值 = 函数名()——接收返回值

    (1)没有返回值:

      默认返回None

      <1>不写return:函数内的代码执行完毕,自动结束

    def func():
        l = ['xc','gx']
        for i in l:
            print(i)    #xc     gx
            if i=='gx':
                pass
        print('lalala')    #lalala
    rt = func()
    print(rt)   #None

      <2>只写return:结束一个函数

    def func():
        l = ['xc','gx']
        for i in l:
            print(i)        #xc     gx
            if i=='gx':
                return
        print('lalala')  #return之后函数结束,不再继续执行这句话
    rt = func() print(rt) #None

      <3>return None——不常用

    def func():
        l = ['xc','gx']
        for i in l:
            print(i)       #xc     gx
            if i=='gx':
                return None
        print('lalala') #return之后函数结束,不再继续执行这句话
    rt = func()
    print(rt)   #None

    (2)返回一个值

      结束了函数且返回一个值,可以是任意的值

        <1>可以返回任何数据类型

        <2>只要返回就可以接收到

        <3>如果在一个程序中有多个return,只执行第一个

    def func():
        return
    print(func())   #None
    
    def func1():
        return [1,2,3,4]
    print(func1())  #[1, 2, 3, 4]
    
    def func2():
        return {'k','v'}
        return 1    #在前一个return已经结束函数了,此条语句不执行
    print(func2())  #{'v', 'k'}

    (3)返回多个值

      多个值之间用逗号隔开,可以用一个(返回元祖)或者等量的多个变量接收

    def func():
        return 1,2
    rt1,rt2 = func()
    print(rt1,rt2)  #1 2
    r = func()
    print(r)    #(1, 2)

    3. 参数

      没有参数——定义和调用函数的时候,括号里不写内容
      有一个参数——传什么就是什么
      有多个参数——位置参数

    (1)形参和实参

    def my_len(s):   #接收参数——形式参数,形参
        i = 0
        for k in s:
            i += 1
        return i
    s = '金老板小护士'
    rt = my_len(s)  #传递参数(传参)——实际参数,实参
    rt1 = my_len('班主任星儿最好看')
    print(rt)   #6
    print(rt1)  #8

    (2)形参——定义函数的时候

      <1>位置参数:必须传,且有几个参数传几个值

      <2>默认参数:可以不传,不传就使用默认的,传什么用什么

        默认参数的陷阱:

          默认参数的值是可变数据类型,那么每一次调用函数的时候,如果不传值就公用这个数据类型的资源

    #(1)
    def qqxing(l = []):     
        l.append(1)
        print(l)
    qqxing()    #[1]
    qqxing([])  #[1]
    qqxing()    #[1, 1]
    qqxing()    #[1, 1, 1]
    qqxing([])  #[1]
    #(2)
    def qqxing(l = {}):
        l['k'] = 'v'
        print(l)
    qqxing()    #{'k': 'v'}
    qqxing({})  #{'k': 'v'}
    qqxing()    #{'k': 'v'}
    qqxing({})  #{'k': 'v'}
    
    #(3)
    def qqxing(k,l = {}):
        l[k] = 'v'
        print(l)
    qqxing(1)    #{1: 'v'}
    qqxing(5,l = {'k3':'v3'})   #{'k3': 'v3', 5: 'v'}
    qqxing(2)     #{1: 'v', 2: 'v'}
    qqxing(22)    #{1: 'v', 2: 'v', 22: 'v'}
    qqxing(6,l = {'k3':'v3'})   #{'k3': 'v3', 6: 'v'}
    qqxing(3)    #{1: 'v', 2: 'v', 3: 'v'}
    qqxing(33)   #{1: 'v', 2: 'v', 22: 'v', 3: 'v', 33: 'v'}
    qqxing(333)  #{1: 'v', 2: 'v', 22: 'v', 3: 'v', 33: 'v', 333: 'v'}
    qqxing(7,l = {'k3':'v3'})   #{'k3': 'v3', 7: 'v'}
    qqxing(3,l = {'k3':'v3'})   #{'k3': 'v3', 3: 'v'}
    qqxing(8,l = {'k3':'v3'})   #{'k3': 'v3', 8: 'v'}

      <3>动态参数:可以接收任意个参数

              *args:接收的是按照位置传参的值,组织成一个元祖

               **kwargs:接收的是按照关键字传参的值,组织成一个字典

               args必须在kwargs之前

    # 动态传参(*args)
    def func00(*args):    #站在形参的角度,给变量加上*,就是组合所有的值
        print(args)
    func00(1,2,3,4,5) #(1, 2, 3, 4, 5)
    l = [1,2,3,4,5]
    func00(*l)    #(1, 2, 3, 4, 5) 站在实参的角度,给一个序列加上*,就是将这个序列按照顺序打散
    
    def func1(**kwargs):    #可以接收任意多个按关键字传的参数
        print(kwargs)
    func1(a=1,b=2,c=3)  #{'a': 1, 'b': 2, 'c': 3}
    func1(a=1,b=2)      #{'a': 1, 'b': 2}
    func1(a=1)          #{'a': 1}
    
    def func11(**kwargs):
        print(kwargs)
    func11(a=1,b=2) #{'a': 1, 'b': 2}
    d = {'a':1,'b':2}
    func11(**d)     #{'a': 1, 'b': 2}
    
    def func2(*args,**kwargs):
        print(args,kwargs)
    func2(1,2,3,a = 'addc', b = 'csdsv')    #(1, 2, 3) {'a': 'addc', 'b': 'csdsv'}

      <4>混合使用

    # 位置参数+默认参数
    def classmate(name,sex=''):
        print('%s:%s'%(name,sex))
    classmate('二哥')     #二哥:男——位置参数+默认参数(未传值)
    classmate('小梦','')     #小梦:女——位置参数+默认参数(传值)
    classmate('大猛')     #大猛:男——位置参数+默认参数(未传值)
    
    # 动态参数(*args)+关键字参数
    def func0(*args,l=[]):
        print(args,l)
    func0()  #() []
    func0(1,2,'str',['lst',1])   #(1, 2, 'str', ['lst', 1]) []
    func0(1,2,'str',l = ['lst',1])   #(1, 2, 'str') ['lst', 1]

     特点: 

      <1>位置参数:必须传

      <2>*args:动态参数,可以接收任意多个按位置传的参数

      <3>默认参数:可以不传——陷阱

      <4>**kwargs:动态参数,可以接收任意多个按关键字传的参数

      定义函数的时候

        位置参数:直接定义参数

        默认参数:关键字参数,参数名 = ‘默认的值’

        动态参数:可以接收任意多个参数

          定义方式:*变量名(习惯用*args)

                 **变量名(习惯用**kwargs)

        顺序:位置参数,*args,默认参数,**kwargs

    (3)实参——调用函数的时候

      <1>按照位置传参数

      <2>按照关键字传参数     

    def my_sum(a,b):
        print(a,b)  #1  2
        res = a+b
        return res
    rt = my_sum(1,2)    #按照位置传参
    rt1 = my_sum(b = 2,a = 1)   #按照关键字传参
    rt2 = my_sum(1,b = 2)   #混合使用(位置传参在前,关键字传参在后)
    print(rt)   #3
    print(rt1)   #3
    print(rt2)   #3

      特点:

        可以混用 位置必须在关键字之前
        不能对一个参数重复赋值

      调用函数的时候:

        按照位置传:直接写参数的值 

        按照关键字传:关键字 = 值

    4. 命名空间(3种)

    (1)内置命名空间——python解释器

       python解释器一启动就可以使用的名字

      内置的名字在启动解释器的时候被加载进内存中

    (2)全局命名空间——我们写的代码,但不是函数中的代码

      是在程序从上到下执行的过程中依次加载进来的

      放置了我们设置的所有变量名和函数名

    (3)局部命名空间——函数

      是函数内部定义的名字

      当调用函数的时候才会产生这个名字空间,随着函数的结束而消失

      多个函数应该拥有多个独立的名字空间,不互相共享

    (4)加载与取值的顺序

      加载顺序:内置命名空间    >    全  局  命  名  空  间  >     局  部  命  名  空  间

            程序运行前加载       程序运行中:从上到下     程序运行中:调用时才加载

    (5)名字空间的使用

      在内置:不能使用全局和局部的名字

      在全局:可以使用内置的名字,但不能使用局部的名字

      在局部:可以使用内置和全局的名字

      

      局部有就用局部的,局部没有就找全局的;

      全局有就用全局的,全局没有就找内置的;

      内置的有就用内置的,内置没有就报错

    def max():
        print('in max func')
    max()   #in max func
    
    def input():
        print('in input now')
    def func():
        input = 1
    print(input)    #<function input at 0x0000012CB1761D08>
    
    #func()  #func---->函数的内存地址
             #func()---->函数的调用
             #函数的内存地址()---->函数的调用

    5. 作用域(2种)

    (1)全局作用域

      作用在全局——包含内置和全局名字空间中的名字

    (2)局部作用域

      作用在局部——包含局部名字空间()函数中的名字

    对于不可变数据类型:在局部可以查看全局作用域中的名字

              不能直接修改

              想要修改,则需要在函数开始添加globle

    6. 关键字:global、local、nonlocal

    (1)global  

      如果在一个局部(函数)内声明了global变量,在局部的所有操作对这个变量有效

    a = 1
    def func():
        global a
        a += 1
    func()
    print(a)    #2

      尽量少使用global,涉及到安全问题——用传参替代

    a = 1
    def func(a):
        a += 1
        return a
    a = func(a)
    print(a)    #2

    (2) global和locals的区别

      查看局部作用域中的所有名字——globals()全局的——在局部和全局永远都打印全局的名字

      查看全局作用域中的所有名字——locals()本地的——在局部就打印局部的名字,在全局就打印全局的名字

    a = 1
    b = 2
    def func():
        x = 'aaa'
        y= 'bbb'
        print(locals()) #局部{'y': 'bbb', 'x': 'aaa'}
    func()
    print(locals())     #全局+内置(同下)
    print(globals())    #全局+内置
                        #{'__name__': '__main__', '__doc__': '
    a = 1
    def func():
        global a
        # a += 1
    
                        # a = 2
    func()
    print(a)
    ', '__package__': None,
                        #  '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002028799B518>,
                        # '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
                        # '__file__': 'E:/Python/day10/03 函数的命名空间.py', '__cached__': None, 'a': 1, 'b': 2,
                        #  'func': <function func at 0x0000020287A71D08>}

    (3)nonlocal

      只能用于局部变量,找最近的上一层的局部变量

      声明了nonlocal的内部函数的变量的修改,回影响到上一层局部变量的值

      对全局无效,对局部最近的一层有影响

    def outer():
        a = 1
        def inner():
            a = 2
            def inner2():
                nonlocal a
                print(a)
            inner2()
        inner()
    outer() #2

    7. 函数的嵌套

    (1)嵌套调用

    def max(a,b):
        return a if a>b else b
    print(max(5,2)) #5
    def the_max(x,y,z):
        c = max(x,y)
        return max(c,z)
    
    print(the_max(1,5,3))   #5

    (2)嵌套定义

    a = 1
    def outer():    #定义inner
        a = 1
        def inner():    #定义inner1
            b = 2
            print(a)    #1
            print('inner')  #inner
            def inner2():   #定义inner2
                # global a    #声明了一个全局变量a,只对函数外的全局变量有效
                nonlocal a  #声明了一个上层的局部变量a,只找上面第一层
                a += 1  #没有上面两句中任意一句,则报错:不可变数据类型的修改
                print(a,b)  #2  2
                print('inner2') #inner2
            inner2() #调用inner2
            print('###a###: ',a)    ####a###:  2
        inner() #调用inner1——若没有这句话来调用inner(),则运行不输出任何结果
        print('***a***: ',a)    #***a***:  2
    outer() #调用inner
    print(a)    #1

    8. 闭包

    (1)闭包定义

      嵌套函数,且内部函数要调用外部函数的变量

    def outer():
        a = 1
        def inner():
            print(a)
        inner()
    outer()

    (2)判断是否是闭包

    def outer():
        a = 1
        def inner():
            print(a)
        print(inner.__closure__)    #是闭包:(<cell at 0x0000017AAEAC6678: int object at 0x000000005F8E60E0>,)
    outer()
    print(outer.__closure__)    #不是闭包:None

    (3)使用闭包的好处

      在函数的外部使用内部函数

    def outer():
        a = 1
        def inner():
            print(a)
        return inner
    inn = outer()
    inn()   #1

    (4)闭包的应用

    import urllib   #模块
    from urllib.request import urlopen
    def get_url():
        url = 'http://www.baidu.com'
        def get():
            ret = urlopen(url).read()
            print(ret)
        return get
    get_func = get_url()
    get_func()
    长得丑就应该多读书。我爱学习,只爱学习,最爱学习!
  • 相关阅读:
    [nginx]简单内容管理系统的spring项目的nginx.conf配置文件的注释理解
    [日常填坑]部署使用Idea开发的spring框架的多模块项目到服务器
    [日常填坑]centos7.0+版本服务器安装jdk9或者jdk10
    [日常填坑]centos7.0+版本服务器安装mysql
    机器学习实战之kNN算法
    机器学习实战之机器学习主要任务
    模式字符串匹配问题(KMP算法)
    ubuntu 更新引导命令
    ubuntu 14.04 中找不到 libgtk-x11-2.0.so
    maven project 更新总是jre-1.5
  • 原文地址:https://www.cnblogs.com/xc-718/p/9655582.html
Copyright © 2011-2022 走看看