zoukankan      html  css  js  c++  java
  • python 函数基础知识整理

    一、函数的定义:

    定义:def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。

       def 是固定的,不能变,必须是连续的def三个字母,不能分开。。。

       空格 为了将def关键字和函数名分开

       函数名:必须由字母下划线数字组成,不能是关键字,不能是数字开头,函数名还是要有一定的意义能够简单说明函数的功能

       括号:是必须加的

    注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。

    调用:就是 函数名() 要记得加上括号

    def 函数名(参数1,参数2,*args,默认参数,**kwargs):
            """注释:函数功能和参数说明"""
            函数体
            ……
            return 返回值

    二、函数的返回值

    
    
    1.return xxx  返回一个值(一个变量)
    2.return a,b 返回多个值(多个变量),多个值之间用逗号区分
    接收:可以用一个变量接收,以元组的形式返回
    也可以用多个变量接收,返回几个就用几个变量去接收
    3.返回值为None
    函数的返回值为None有三种情况
    a.不写返回值
    b.只写一个return
    c.return None (几乎不用)

    return的作用:结束一个函数的执行

    函数的返回值不为None,有返回值

    复制代码
    def func():
        a = 111
        b = [1,2,3]
        #首先 返回值可以是任意的数据类型
        return b
    
    #如果有返回值:必须要用变量接收才会有效果
    # ret = func()
    # print(ret)
    
    def func1():
        a = 111
        b = [1,2,3]
    # ret = func1()
    # print(ret)
    #函数可以没有返回值
    #当不写return的时候,一个函数默认的返回值是'None'
    
    def func2():
        a = 111
        b = [1,2,3]
        return
    # ret = func2()
    # print(ret)
    #当只写一个return的时候,函数的返回值为None
    
    def func3():
        a = 111
        b = [1,2,3]
        return None
    # ret = func3()
    # print(ret)
    #return None的时候函数的返回值也为None(几乎不用)
    
    def func4():
        print(1111)
        return
        print(2222)
    
    # func4()
    
    def func5():
        for i in range(20):
            if i == 5:
                return
            else:
                print(i)
    # func5()
    
    #函数要先定义 后 调用
    
    def func6():
        '''返回一个值'''
        #return 111
        #return 'abc'
        return ['abc',123]
    
    def func7():
        '''返回多个值'''
        a = 123
        b = 'abc'
        return a,b,[1,2,3]
    
    # ret = func7()
    # print(ret)
    # m,n,k = func7()
    # print(m)
    # print(n)
    # print(k)
    
    def func8():
        l = [1,2,3,4]
        return l[-1]
    
    # ret = func8()
    # print(ret)
    复制代码

    三、参数:

    1.实参:函数调用时我们传入的参数就叫做实参

    2.形参:函数定义时我们定义的参数就叫做形参

    站在实参的角度看:

    参数有位置参数和关键字参数

                                     注意:位置参数必须放在关键字参数前面

    复制代码
    #位置参数
    def fun(a,b):
        print('a',a,"b",b)
        if a>b:
            return a
        else:
            return b
    #位置参数
    l1=fun(10,20)
    #关键字参数
    l2=fun(a=20,b=10)
    print(l1)
    print(l2)
    复制代码
    复制代码
    __author__ = 'ctz'
    def fun(name,addr,sex="male"):
        return name,addr,sex
    a=fun("ctz","km")
    b=fun(name="cmq",addr="xw",sex="female")
    c=fun("sss",addr="bj")
    d=fun(addr="sss",name="ccc")
    print(a)
    print(b)
    print(c)
    print(d)
    复制代码
    复制代码
    __author__ = 'ctz'
    def fun(name,addr,sex="male"):
        return name,addr,sex
    #位置传参
    a=fun("ctz","km")
    #关键字传参
    b=fun(name="cmq",addr="xw",sex="female")
    #位置传参和关键字传参混用
    c=fun("sss",addr="bj")
    #关键字传参
    d=fun(addr="sss",name="ccc")
    print(a)
    print(b)
    print(c)
    print(d)
    复制代码

    动态传参

    复制代码
    def fun2(*args):#*args代表把散列的元素拼成元组
        print(args)
    t = (1,2,3,4)
    l = [1,2,3,4]
    # fun2(t[0],t[1],t[2],t[3])
    fun2(*t)  #*代表把一个元组、列表拆了
    fun2(*l)  #*代表把一个元组、列表拆了
    
    def fun3(**kwargs):#*args代表把按关键字传来的参数拼成字典
        print(kwargs)
    fun3(a = 10, b = 20)
    d = {'a': 10, 'b': 20}
    fun3(**d)  #*代表把一个字典拆了
    复制代码

    站在形参角度看

    可以传递0个或多个参数,
    传参顺序必须为:位置参数,*args,默认参数,**kwargs
    传参数的时候:必须先按照位置传参数,再按照关键字传参数
     

    1.位置参数必须传值,按顺序定义参数

    复制代码
    def mymax(x,y):
        #此时x = 10,y = 20
        print(x,y)
        the_max = x if x > y else y
        return the_max
    
    #调用mymax不传递参数
    ma = mymax()
    print(ma)
    
    #结果
    TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'
    复制代码
    2.默认参数
    首先,不要设置可变数据类型的默认参数 对于变化小的参数可以设置默认参数 默认参数可以不传,不传的时候用的就是默认值 如果传,会覆盖默认值 默认的值是在定义函数的时候就已经确定了的
    复制代码
    def stu_info(name,sex = "male"):
        """打印学生信息函数,由于班中大部分学生都是男生,
            所以设置默认参数sex的默认值为'male'
        """
        print(name,sex)
    
    
    stu_info('alex')
    stu_info('eva','female')
    复制代码

    3.动态参数:

     a.*args

    按位置传值多余的参数都由args统一接收,保存成一个元组的形式

    复制代码
    def func(a,b,*c):
        my_sum = a+b
        for i in c:
            my_sum += i
        return my_sum
    
    #按位置传参数
    # print(func(3,2))
    # print(func(1,2,5,6))
    复制代码

    b.**kwargs

    def fun(a,b,**kwargs):
        print(a,b,kwargs)
    
    # 按照关键字传参数
    #fun(a = 10,b = 20,cccc= 30,dddd = 50)

    四、函数的命名空间

    命名空间一共分为三种:

      全局命名空间

      局部命名空间

      内置命名空间

    *内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

    三种命名空间之间的加载与取值顺序:

    加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

    取值:

      在局部调用:局部命名空间->全局命名空间->内置命名空间

    x = 1
    def f(x):
        print(x)
    
    print(10)

    在全局调用:全局命名空间->内置命名空间

    复制代码
    def fun(a,b,c):
        return max(a,b,c)#用的是内置命名空间的max
    print(fun(1,2,3))
    
    
    def max(a,b):
        c=a  if a>b else b
        return c
    print(max(1,5))#用的1是自己定义的max 全局作用域里面的
    复制代码

    五、函数的作用域:

    作用域

    作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

    全局作用域:包含内置命名空间、全局命名空间,在整个文件的任意位置都能被引用、全局有效

    局部作用域:局部命名空间,只能在局部范围生效

    小范围的可以用大范围的,但是大范围的不能用小范围的

    范围从大到小在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。如果都没有,报错

    globals和locals方法

    复制代码
    a = 20
    b = 50
    def haha():
    x = 1
    y = 2
    print(globals()) #全局作用域中的名字
    print(locals()) #局部作用域中的名字
    
    # haha()
    # print(globals()) #全局作用域中的名字
    # print(locals()) #全局的局部还是全局
    复制代码

    global关键字

    复制代码
    a = 10
    def func():
        global a
        a = 20
    
    print(a)
    func()
    print(a)
    复制代码

    六、函数的嵌套和作用域链

    函数嵌套

    复制代码
    def f1():
        def f2():
            def f3():
                print("in f3")
            print("in f2")
            f3()
        print("in f1")
        f2()
        
    f1()
    复制代码

    函数作用域链

    复制代码
    def f1():
        a = 1
        def f2():
            def f3():
                print(a)
            f3()
        f2()
    
    f1()
    复制代码
    复制代码
    def f1():
        a = 1
        def f2():
            a = 2
        f2()
        print('a in f1 : ',a)
    
    f1()
    复制代码

    nonlocal关键字

    复制代码
    def f():
        a = 3
        def f1():
            a = 1
            def f2():
                nonlocal a
                # 1.外部必须有这个变量
                # 2.在内部函数声明nonlocal变量之前不能再出现同名变量
                # 3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效
    
                a = 2
            f2()
            print('a in f1 : ', a)
        f1()
        print('a in f : ',a)
    
    f()
    复制代码

    七、函数名的本质

    函数名本质上就是函数的内存地址

    1.可以被引用

    def func():
        print('in func')
    
    f = func
    print(f)

    2.可以被当作容器类型的元素

    复制代码
    def f1():
        print('f1')
    
    
    def f2():
        print('f2')
    
    
    def f3():
        print('f3')
    
    l = [f1,f2,f3]
    d = {'f1':f1,'f2':f2,'f3':f3}
    #调用
    l[0]()
    d['f2']()
    复制代码

    3.可以当作函数的参数和返回值

    复制代码
    __author__ = 'Administrator'
    def f():
        print("so good")
        return 1+2
    l=f#函数名实际上就是普通的变量名
    #print(l())
    
    def g(f):#函数名可以做参数
        print(f)#结果是函数名所指向的那块内存地址
        print("so good g")
        return 2+5
    print(g(f))
    
    
    
    def l():
        return f#函数名可用作返回值
    
    ll=l()
    print(ll())
    复制代码

    八.闭包

    闭包
    1.闭 内部的函数
    2.包 包含了对外部函数作用域中变量的引用

    闭包的作用:

    就是能够引用外部函数的变量,并且可以保证外部函数的变量控制在一个局部作用域中

    复制代码
    #闭包的常用形式
    def hei():
        x = 20
        def inner():
            print(x)  #局部的
        return inner
    
    # i = hei()
    # i()  #全局
    复制代码
    复制代码
    __author__ = 'Administrator'
    # from urllib.request import urlopen
    # def fun():
    #     url="http://www.sina.com.cn/"
    #     def op():
    #         return urlopen(url).read()
    #     return op
    # l=fun()
    # print(l())
    from urllib.request import urlopen
    def fun(url):
        def op():
            return urlopen(url).read()
        return op
    url="http://www.sina.com.cn/"
    l=fun(url)
    print(l())
    复制代码

    判断闭包函数的方法__closure__

    复制代码
    #输出的__closure__有cell元素 :是闭包函数
    def func():
        name = 'eva'
        def inner():
            print(name)
        print(inner.__closure__)
        return inner
    
    f = func()
    f()
    
    #输出的__closure__为None :不是闭包函数
    name = 'egon'
    def func2():
        def inner():
            print(name)
        print(inner.__closure__)
        return inner
    
    f2 = func2()
    f2()
    复制代码
    复制代码
    #闭包嵌套
    def wrapper():
        money = 1000
        def func():
            name = 'eva'
            def inner():
                print(name,money)
            return inner
        return func
     
    f = wrapper()
    i = f()
    i()
    复制代码

    九、装饰器

    装饰器的本质 :闭包函数
    功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能

    实际上是一种设计模式,开放封闭原则,对扩展是开放的,对修改是封闭的

    通用版本
    复制代码
    def timmer(func):
        def inner(*args,**kwargs):
            '''添加函数调用之前的扩展代码'''
            ret = func(*args,**kwargs)
            '''添加函数调用之后的扩展代码'''
            return ret
        return inner
    复制代码
    复制代码
    __author__ = 'Administrator'
    def sw(fun):
        def inner(*args,**kwargs):
            ret=fun(*args,**kwargs)
            print(ret)
            return ret
        return inner
    @sw#语法糖------>a=sw(a)
    def a(m):
        return m
    @sw
    def b(m,n,**kwargs):
        return m,n,kwargs
    a(1)
    b(2,3,name="ctz",paw="ahgfggf")
    复制代码

    被装饰函数没参数

    复制代码
    def zsq(fun):
        def inner():
            fun()
        return  inner
    
    def a():
        print("aaaaaa")
    
    a=zsq(a)
    a()
    复制代码

    被装饰函数有一个参数

    复制代码
    __author__ = 'Administrator'
    import  time
    def f(fun):
        def inner(x):
            fun(x)
        return  inner
    
    def b(a):
        print(a)
    
    b=f(b)
    b(4)
    复制代码

    被装饰参数有两个参数

    复制代码
    __author__ = 'Administrator'
    def fun(f):
        def inner(x,y):
            f(x,y)
        return  inner
    
    @fun
    def c(a,b):
        print(a,b)
    c(5,6)
    复制代码

    带参数的装饰器(开关)

    复制代码
    __author__ = 'Administrator'
    F=True
    def outer(F):
        def wap(fun):
            def inner(*args,**kwargs):
                if F:
                    print("inner   before")
                    ret=fun(*args,**kwargs)
                    print("inner   after")
                else:
                    ret=fun(*args,**kwargs)
                return  ret
            return inner
        return wap
    
    @outer(F)
    def gg():
        print("gg............")
    gg()
    复制代码
    多个装饰器装饰一个函数
    复制代码
    __author__ = 'Administrator'
    def yn(fun):#fun=sc_inner
        def yn_inner(*args,**kwargs):
            print("yun..........before")
            ret=fun(*args,**kwargs)#sc_inner()
            print("yn...........after")
            return ret
        return yn_inner
    
    def sx(fun):#fun=china
        def sx_inner(*args,**kwargs):
            print("sx..........before")
            ret=fun(*args,**kwargs)#china()
            print("sx...........after")
            return ret
        return sx_inner
    
    @yn #china=yn(china)-----china=yn(sx(china))----china=yn(sx_inner)---->china=yn_ineer
    @sx  #china=sx(china)----china=
    def china():
        print("china is good ")
    
    china()#yn_inner()
  • 相关阅读:
    WebSVN 2.3.3
    webSVN客户端(转) initOS的日志 网易博客
    分享:httping 2.0 发布,测试 HTTP 连接的工具
    ThriftUsageC++ Thrift Wiki
    硬盘接口:SCSI、IDE与SATA的区别
    把event sql导入数据库难点
    cpu插槽 LGA 1155
    Processing简介
    技嘉主板GAB75MD3V产品规格
    pci Express
  • 原文地址:https://www.cnblogs.com/Xanderzyl/p/10495017.html
Copyright © 2011-2022 走看看