• python 函数(一)


    函数初识/名称空间/作用域/高阶函数/globals()local()/关键字global/nonlocal

    函数初识

    1、函数基本组成

    写一个函数

    def my_len(s):
        count = 0
        for i in s:
            count += 1
        return count
    
    s1 = "aldjfalkdjfd"
    s1_len = my_len(s1)
    print(s1_len)
    
    

    # def : 关键字

    # my_len : 函数名

    # s : 形参

    # return : 返回 return 可以返回一个或多个值,返回一个值的时候,值是什么类型的数据,返回就是什么类型的数据,值是多个的时候,返回一个元祖

    # 函数如果没有return的话返回None

    # 函数的作用:减少重复的代码,提高代码的复用性,是代码更加简洁,可读性强

    # 函数的执行:函数名()

    2、函数传参

    # 函数的传参:让函数封装的这个功能,盘活

    # 实参,形参

    def my_len(s):
        count = 0
        for i in s:
            count += 1
        return count
    
    s1 = "aldjfalkdjfd"
    s1_len = my_len(s1)
    print(s1_len)
    

    # s就是形参

    # s1就是实参

    3、实参角度分类

    1、位置参数:

    从左至右,一一对应

    # 练习题

    # 写一个函数,只接收两个int的参数,函数的功能是将较大的数返回
    def big_num(a, b):
        if type(a) is int and type(b) is int:
            if a > b:
                return a
            else:
                return b
    ret = big_num(23, '4')
    print(ret)

    # 三元运算符

    就是简单的  if  else

    a = 10
    b = 20
    c = a if a>b else b     # a > b的话,c = a,否则 c = b
    print(c)

    答案:20


    上面的也可以写成这样

    def complit(a,b):
        return a if a>b else b
    a = 10
    b = 20
    print(complit(a,b))

    答案:20


    #  2、关键字参数

    def userinfo(name,age,area,telnum):
        print("姓名:%s age:%s area:%s telnum:%s" %(name,age,area,telnum))
    
    userinfo(name="bob",age=18,area="henan",telnum=1234324354)
    userinfo(age=23,area='hanguo',name='simida',telnum=2343244)

    显示结果:

    姓名:bob age:18 area:henan telnum:1234324354
    姓名:simida age:23 area:hanguo telnum:2343244


    # 练习题
    # 函数:传入两个字符串参数,将两个参数拼接完成后形成的结果返回。
    def join_str(a,b):    
        return a + b
    
    a = "bob"
    b = 'sb'
    ret = join_str(a=a,b=b)
    print(ret)

    显示结果: bobsb


    # 3、混合参数
    # 1、位置参数一定要在关键字参数的前面
    # 2、不可以重复传参:重复传参也就是位置参数传入了一次,然后关键字参数又去传一次

    def userinfo(name,age,area,telnum):
        print("姓名:%s age:%s area:%s telnum:%s" %(name,age,area,telnum))
    
    userinfo("juice",18,telnum=23425454,area="diqiu")

    显示结果:

    姓名:juice age:18 area:diqiu telnum:23425454

    4、形参角度分类

    # 1、位置参数    :同实参的位置参数,都是从左到右,一一对应

    # 2、默认参数    :在进行函数调用的时候,可以传值也可以不传值,传值的话就用传入的值,没有传的话就用默认的值

    def userinfo(name,age,sex='男'):
        print('姓名:%s  age:%s  性别:%s'%(name,age,sex))
    
    userinfo("alex",18,sex='女')
    userinfo('bob',20)

    答案:

    姓名:alex  age:18  性别:女
    姓名:bob  age:20  性别:男


    # 3、万能参数

    # 定义一个函数:注意开放封闭原则
    def eat(a,b,c,d):
        print('请你吃:%s %s %s %s'%(a,b,c,d))
    eat('鸡','鸭','鱼','肉')
    # 上面的eat的参数就写死了,如果需要扩展更多的食物就的修改函数里面的源代码,这就违反了开放封闭原则
    # *
    def eat(*args):
        food = '请你吃:'
        for i in range(len(args)):
            food += args[i]
        return food
    print(eat('鸡','鸭','鱼','肉','羊','牛肉'))

    # *args可以接收任意的位置参数,你在扩展的时候就不用动源代码,只需要在调用的时候传入参数即可


    练习题

    # 写一个函数,计算传入函数的所有的数字的和
    def sum_func(*args):
        sum = 0
        for i in args:
            if type(i) is int:
                sum += i
        return sum
    ret = sum_func(2,3,7,8,3,7,30,"alex")
    print(ret)

    答案:60

    # *args是接收所有的位置参数,哪来接收所有的关键字参数呢?    **kwargs

    def fun(**kwargs):
        print(kwargs)
    fun(name='bob',age=50)   # 打印:{'name': 'bob', 'age': 50}
    # ** 会把所有的关键字参数转换成字典赋值给kwargs

    # 4、仅限关键字参数

    # 形参里面的仅限关键字参数,比如下面的函数
    def func(*args,c,**kwargs):         # c就是仅限关键字参数
        print(args)
        print(c)
        print(kwargs)
    func(1,3,name='alex',c=5,age=18)       # 调用的时候必须以关键字参数调用,也就是说必须写成 c=多少,调用的时候仅限关键字参数的位置要放在位置参数的后面
    # 答案:
    (1, 3)
    5
    {'name': 'alex', 'age': 18}


    5、参数的传入顺序

    # 位置参数,*args, 仅限关键字参数,位置参数,**kwargs      # 其中仅限关键字参数和位置参数可以调换位置

    6、实参中的*,*的魔性用法

    #  *  **在函数调用时,* 代表打散
    def func(*args,**kwargs):
        print(args)
        print(kwargs)
    # func([1,2],[3,4])
    # 答案
    '''
    ([1, 2], [3, 4])
    {}
    '''
    
    # func(*[1,2],*[3,4])            # 相当于:  func(1,2,3,4)
    # 结果:
    '''
    (1, 2, 3, 4)
    {}
    '''
    
    func(**{"a":"alex"},**{'b':'dt'})    # 相当于: func(a='alex',b='dt')
    # 结果:
    '''
    ()
    {'a': 'alex', 'b': 'dt'}
    '''
    
    func(*[1,3],*[5,9],**{'name':'bob','age':18})
    # 结果:
    '''
    (1, 3, 5, 9)
    {'name': 'bob', 'age': 18}
    '''
    
    func(2,4,*[1,3],*[5,9],**{'name':'bob','age':18})
    # 结果:
    '''
    (2, 4, 1, 3, 5, 9)
    {'name': 'bob', 'age': 18}
    '''


    python的名称空间

    # 名称空间分类

    1、内置名称空间(builtins.py)

    2、全局名称空间(当前py文件)

    3、局部名称空间(函数,函数执行时才开辟)


    # 加载顺序

    内置名称空间  -----  全局名称空间 ------  局部名称空间(函数执行时)

    image

    作用域

    分类:

    1、全局作业域   (包括内置名称空间、全局名称空间)

    2、局部作业域     (局部名称空间)

    a = "bob"
    def func():
        b = "jim"
        print(b)
        print(a)
    func()
    
    

    # 显示结果:"jim"   "bob"

    在这里:   a就在全局作业域里面,b在局部作用域里面,局部作用域可以引用全局作用域的变量,但是不可以修改全局作用域的变量,全局作用域不可以使用局部作用域的变量

    比如下面的代码:

    a = "bob"
    def func():
        b = "jim"
        print(b)
        print(a)
        a += "sb"
    func()

    ***这就会报错:UnboundLocalError: local variable 'a' referenced before assignment


    为什么局部作用域不可以修改全局作用域的变量?

    # 是因为局部作用域修改全局作用域的变量时,解释器就会认为在局部作用域里面已经

    定义了该变量,所以就报错。


    取值顺序

    遵循的原则:就近原则,LEGB原则,如下图

    image

    函数的嵌套(高阶函数)

    想要明白函数的嵌套,关键点:只要遇见了函数名+()就是函数的调用,如果没有就不是函数的调用:举例:

    例1:

    def func1():
        print('in func1')
        print(3)
    def func2():
        print('in func2')
        print(4)
    func1()
    print(1)
    func2()
    print(2)
    
    #  显示结果:   'in func1'  3   1  'in func2'  4   2

    image

    例2:


    def func1():
        print('in func1')
        print(3)
    def func2():
        print('in func2')
        func1()
        print(4)
    print(1)
    func2()
    print(2)
    # 显示结果:1   'in func2'  'in func1'  3   4  2

    image

    例3


    def func2():
        print(2)
        def func3():
            print(6)
        print(4)
        func3()
        print(8)
    print(3)
    func2()
    print(5)
    # 显示结果:3   2   4   6   8   5

    image

    globals()   local()

    # globals()  local()都是字典 

    globals(): 以字典的形式返回全局作用域所有的变量对应关系

    local():以字典的形式返回当前作用域的变量的对应关系

    def func1():
    age = 35
    print(locals())
    print(globals())
    func1()

    显示结果:

    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000024DF527F588>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'F:/python_project/python_22/day10/s2 global local.py', '__cached__': None, 'name': 'alex', 'func1': <function func1 at 0x0000024DF53373A8>}


    {'age': 35}

    函数补充

    当默认参数是个可变参数时,调用的时候不传值的话,他们共用的是默认参数开辟的内存所在的内存地址

    补充1:

    def func1(a,b=[]):
        b.append(a)
        return b
    ret1 = func1(20)
    print(ret1)
    ret2 = func1(10)
    print(ret2)
    # 显示结果:[20,]    [20,10]

    11

    补充2:

    def func1(a,b=[]):
        b.append(a)
        return b
    ret1 = func1(20)
    ret2 = func1(10)
    print(ret1)
    print(ret2)
    #  显示结果:   [20,10]      [20,10]

    补充3:

    def func1(a,list=[]):
        list.append(a)
        return list
    ret1 = func1(20)
    print(ret1)
    ret2 = func1(10,[])
    print(ret2)
    # 显示结果:  [20,]    [10,]

    补充4:

    def func1(a,list = []):
        list.append(a)
        return list
    ret1 = func1(20)
    ret2 = func1(10,[])
    ret3 = func1(100)
    print(ret1)
    print(ret2)
    print(ret3)
    # 显示结果: [20,100]    [10,]  [20,100]

    总结:通过几个补充的例子,知道了默认值是可变数据类型时,要特别注意

    补充5

    count = 1
    def func():
        count += 1                # 局部作用域只能引用全局作用域的变量,而不能修改
        print(count)
    func()
    

    # 显示结果:会报错

    UnboundLocalError: local variable 'count' referenced before assignment


    补充6:在函数中,如果你定义了一个变量,但是在定义这个变量之前对其引用了,那么解释器认为:语法问题。应该是在使用前先定义。

    count = 1
    def func():
        print(count)              # 解释器会以为你是先引用后定义
        count = 2
    func()

    # 显示结果:

    UnboundLocalError: local variable 'count' referenced before assignment

    关键字global   nonlocal

    global:

    # 有些时候就想在局部作用域里面改全局作用域里面的变量怎么办呢?

    name = 'alex'
    def func():
        name = 'bob'
        print(name)
    func()
    print(name)
    # 显示结果:  bob   alex

    name = 'alex'
    def func():
        global name
        name = 'bob'
        print(name)
    func()
    print(name)
    #   显示结果: 'bob'   'bob'

    # global里面定义的变量,如果函数没有执行的话,全局是没有这个变量的,会报错
    def func():
        global name
        name = 'alex'
        print(name)
    print(name)
    func()
    # 显示结果:NameError: name 'name' is not defined

    小结:global可以对全局变量进行引用和修改

    nonlocal:

    # nonlocal局部作用域对父级作用域的变量进行引用和修改

    def func():
        name = 'alex'
        def inner():
            nonlocal name
            name = 'bob'
        inner()
        print(name)
    func()        # 显示结果:  'bob'
     # 显示结果:  'bob'

    image

    # 小结:

    1、nonlocal不能更改全局变量

    2、局部作用域对父级作用域的变量进行引用和修改



    ----------------------- end -------------------------

    对于一个有思想的人来说,没有地方是荒凉而遥远的
  • 相关阅读:
    Redis 安全
    基于Twemproxy的Redis集群方案(转载)
    Mongodb数据模型
    关于LRU算法(转载)
    基于Redis实现分布式锁(转载)
    Redis持久化(转载)
    redis 内存管理与数据淘汰机制(转载)
    redis事务(转载)
    redis发布与订阅
    redis的数据类型和基本操作
  • 原文地址:https://www.cnblogs.com/quanag/p/12667506.html
Copyright © 2020-2023  润新知