zoukankan      html  css  js  c++  java
  • python基础之函数参数、嵌套、返回值、对象、命名空间和作用域

    函数的使用原则

    函数的使用必须遵循:先定义后使用的原则

    函数的定义,与变量的定义是相似的,如果没有事先定义函数而直接引用就相当于在引用一个不存在变量名

    定义阶段:只检测语法,不执行代码,当出现语法错误会抛出错误

    def foo():
        print('from foo')
        bar()
    def bar():
        print('from bar')

    调用阶段:执行代码的过程中,会检查逻辑问题,当引用一个不存在的变量名会抛错

    foo()

    函数参数

    形参与实参

    形参指的是函数定义时候标记的变量名,实参表示函数调用时候传入的实际数据参数,即标量值,形参在定义后是不可变的,而实参是可以变的。

    def foo(x,y):    #x,y即形参
        print(x)
        print(y)
    foo(2,3)      #2,3即实参

    函数参数分类

    位置参数:包括位置形参和位置实参,按照从左到右的数序依次定义的参数,用逗号分隔。

    def foo(x,y):
        print(x)
        print(y)
    foo(2,3)

    按位置定义的形参:在函数调用的时候,必须要有实参传入,实参的数量必须和形参的数量相同,不能多也不能少。

    按位置定义的实参:要与与形参一一对应

    关键字参数:实参在定义时,按照key=value形式定义,key值必须存在在形参里

    def foo(x,y):
        print(x)
        print(y)
    foo(x=1,y=10)
    或
    foo(y=10,x=1)  #关键字参数可以不用像位置实参一样与形参一一对应,指名道姓地传值

    要注意的是,当位置实参和关键字实参同时传入的时候,位置实参必须在关键字实参之前

    实参既可以用位置实参又可以用关键字参数,但是一个形参只能接受一个实参传入,不能接收多个

    默认参数:在定义函数阶段,就已经为形参赋值,定义阶段有值,调用阶段可以不用传值

    def func(x,y=10):
        print(x)
        print(y)
    func(1,20)
    或 func(1)

    默认形参必须在位置形参之后

    函数调用时候,传入的实参可以不写默认形参的传入值,即只传入位置实参就可以了

    当形参在大多数情况下是不变的时候,就可以定义成默认参数,默认参数通常定义成不可变类型,在定义的时候默认形参就已经被赋值了一次

    可变长参数:可变长指的是实参的个数不固定

    处理按位置定义的可变长度的实参:*

    def func(x,y,*args): #x=1,y=2,args=(3,4,5,6)
        print(x,y)
        print(args)
    func(1,2,3,4,5,6)

    *是用元组的方式接收多余出来的位置参数

    调用函数时候使用func(1,2,*(3,4,5,6))也可传入参数,当遇到这种方式传入的时候,实际上和func(1,2,3,4,5,6)一毛一样,会自动拆分成位置参数。

    处理按关键字定义的可变长度的实参:**

    def func(x,y,**kwargs): #x=1,y=2,kwargs={'a':1,'b':3,'z':3}
        print(x,y)
        print(kwargs)
    func(1,y=2,z=3,a=1,b=3)

    **是用字典的方式接收多余出来的位置参数

    调用函数时候使用func(1,y=2,**{'a':1,'b':3,'z':3})传入参数时候,实际上和func(1,y=2,z=3,b=3,a=1)一毛一样,也会自动将字典拆分成关键字实参

    def wrapper(*args,**kwargs): #可以接受任意形式,任意长度的参数
        print(args)
        print(kwargs)
    wrapper(1,2,3,3,3,3,3,x=1,y=2,z=3)

    位置实参被*接收,关键字实参被**接收

    扩展:以下代码在后面装饰器能用到,wraper接收的传入参数会原封不动传给index

    def index(name,group):
        print(name)
        print(group)
    def wrapper(*args,**kwargs):
        print(args)
        print(kwargs)
        index(*args,**kwargs)
    wrapper(1,23,3,13,4,315,3,15,23,4,x=1,y=2,c=3)

    命名关键字参数:定义在*后的形参,必须得传入值,必须以关键字方式传入

    def register(*args,name='egon',age):
        print(args)
        print(name)
        print(age)
    register(name='egon',age=18)
    register(1,2,2,3,age=10)

    以上代码可以没有args,写成register(*,name='egon',age),将不能传入register(1,2,2,3,age=10)

    形参定义顺序:位置形参,默认参数,*args,命名关键字参数,**kwargs

    函数的返回值

    返回值,return,一般有参函数需要有返回值

    如果函数内没有return,那么会返回一个None

    返回一个值,什么值都能返回

    返回多个值需要用元组,不带括号也可以

    return只能返回一次值,执行完return那么函数执行结束

    def foo():
        return 1
        print('=====>')
        return 2
        return 3
        return 4
    
    print(foo())

    命名空间

    名称空间:存放变量名与值的绑定关系

    名称空间三种:

    内置名称空间

      python自带的名称,如print、len、max

      解释器启动就会生成这个空间,是第一个生成的名称空间

    全局名称空间

      文件级别定义的名字

      执行python文件的时候会生成,一般是顶头写的,流程控制语句内定义的变量名也放在全局名称空间

    x=1
    def func():
        pass
    class Foo:
        pass
    import os
    if 1 > 2 :
        y=3

    局部名称空间

      定义在函数内部的,如嵌套定义

      只有在函数调用生效,函数结束失效

    def func(x,y):
        z=3
    #x,y,z都是局部

    三者加载顺序:内置名称空间、全局名称空间、局部名称空间

    x=0
    def f1():
        x=1
        def f2():
            x=2
            def f3():
                x=3
                print(x)
            f3()
        f2()
    
    f1()

    作用域:作用范围

    全局作用域

      内置命名空间全局有用,全局名称空间对于全局都有用

    局部作用域

      局部命名空间局部有用,只在函数内部有效

    找名字:从局部到全局,全局的局部是全局,函数的作用域范围在定义时候就固定死了

    def func():
        # print(globals())    #全局和内置名称
        print(dir(globals()['__builtins__'])    #全局和内置名称
        print(locals())     #局部名称
    print(globals() is locals())

    函数嵌套

    函数的嵌套调用:

    def max2(x,y):
        if x> y :
            return x
        elif:
            return y
    def max4(a,b,c,d):
        res1=max2(a,b)
        res2=max2(res1,c)
        res3=max2(res2,d)
        return res3

    函数的嵌套定义:

    def f1():
        def f2():
            def f3():
                print('from f2')
            print('from f2')
            f3()
        print('from f1')
        f2()

    函数对象

    函数是第一类对象: 指的是函数可以被当做数据传递

    函数可以被引用

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

    可以当作函数的参数

    def func():
        print('from func')
    def foo(x):
        print(x)
        x()
    foo(func)

    可以当做函数的参数

    def foo():
        print('from foo')
    def bar():
        return foo
    f=bar()
    print(f)
    print(foo)

    可以当作容器类型的元素

    def select():
        print('select function')
    func_dic={
        'select':select,
    }
    # print(func_dic['select'])
    func_dic['select']()
  • 相关阅读:
    leetcode 268. Missing Number
    DBSCAN
    python二维数组初始化
    leetcode 661. Image Smoother
    leetcode 599. Minimum Index Sum of Two Lists
    Python中的sort() key含义
    leetcode 447. Number of Boomerangs
    leetcode 697. Degree of an Array
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月3日)
    北京Uber优步司机奖励政策(1月2日)
  • 原文地址:https://www.cnblogs.com/lidagen/p/7049216.html
Copyright © 2011-2022 走看看