函数的参数内容

  • 函数参数
  • 名称空间与作用域
  • 名字的查找顺序

函数参数之位置参数

    """
    补充:当子代码只有一行并且很简单的情况下,可以直接在冒号后面编写,不用换行
    """
    位置形参:
        函数定义阶段括号内从左往右依次填写的变量名
        def l1(a, b, c, d):pass
    位置实参
        函数调用阶段括号内从左往右依次填写的变量名
        l1(1, 2, 3, 4)
    def funcl(a, b):
        print(a, b)
    funcl(1, 2)  # 1 2  按照位置一一对应
    funcl(1,)  # 少一个不行会报错,那多一个也不行
    funcl(a=1, b=2)  # 关键字传参(指名道姓的传)
    funcl(b=1, 1)  # 关键字传参要在位置参数后面,要不会报错
    funcl(2, b=1)  # 这样就可以
    funcl(1, a=2, b=3)  # 同一个形参不能多次赋值
    name = 'jason'
    pwd = 123
    funcl(name, pwd)  # 实参没有固定的定义,可以传数据值,也可以传绑数据值的变量名
    funcl(a=name, b=pwd)  # 同上
    """
    越短的越简单的越靠前
    越长的越复杂的越靠后
    但是遇到下面的情况下除外
        同一个形参在调用的时候不能多次赋值
    """

关键字实参

    在函数调用阶段,变量名=实参
        也叫关键字传参,以以下出现
        def funcl(a, b):
            print(a, b)
         funcl(a=1, b=2)

默认参数(关键字形参)

    本质其实就是关键字形参
            别名叫默认参数:提前就以及给了,用户可以传,也可以不传
     '''默认参数的定义也遵循短的简单的靠前 长的复杂的靠后''' 
    def register(name, age, gender='male'):
        print(f"""
        --------学员信息---------
        姓名:{name}
        年龄:{age}
        性别:{gender}
        ------------------------
        """)
    register('jason', 18)  # 会自动用默认参数的性别补上
    register('lili', 28, 'female')  # 给出参数,默认参数直接修改为给给出的参数

    # register('jason', 18, 'male')
	 # register('tony', 28, 'male')
	 # register('kevin', 38, 'male')

可变长形参

    ef funcl(*args):  # 括号内加*号,后面紧跟变量名args
        print(args)
    funcl()  #()没有任何数据,直接给了一个空的元组
    funcl(1)  #(1,)一个数据,以元组的形式展现
    funcl(1, 2, 3, 4)  #(1, 2, 3, 4)如何实现实参丢多少数据形参都可以接收
    def funcl(b, *args):  # 一个位置形参+可变长形参
    print(args, b)
    funcl()  #会直接报错,至少需要一个实参给到位置形参b
    funcl(1, 2)  # 1给b多余的直接给args组成元组
    funcl(1, 2, 3, 4)  # 1给b多余的直接给args组成元组
"""
*号在形参中
	用于接收多余的位置参数,组织成元组赋值给*号后面的变量名
"""
    def func3(**kwargs):  # **用于接收多余的关键字实参转成字典给变量名kwargs
        print(kwargs)
    func3()  # 没有多余的关键字实参为一个空集合
    func3(a=1)  #{'a': 1}组成一个字典
    func3(a=1, b=2, c=3)  #{'a': 1, 'b': 2, 'c': 3}实现形参接收多个关键字实参
    def func4(a, **kwargs):
    print(a, kwargs)
    func4()  # 同位置参数,也需要给a一个关键字实参,要不会报错
    func4(a=1)  # 关键字实参传给位置形参a,没有多余的便组成一个空一个
    func4(a=1,b=2)  # 关键字实参传给位置形参a,剩余b传给kwargs
"""
**号在形参中
	用于接收多余的关键字参数,组织成字典的形式赋值给**号后面的变量名
"""
    def func5(*args, **kwargs):
        print(args, kwargs)
    func5()  # 没有多余的参数所以是() {}
    func5(1, 2, 3)  # 只有位置实参(1, 2, 3) {}
    func5(a=1, b=2, c=3)  # 只有关键字实参() {'a': 1, 'b': 2, 'c': 3}
    func5(1, 2, 3, a=1, b=2, c=3)  # 位置实参,关键字实参(1, 2, 3) {'a': 1, 'b': 2, 'c': 3}
    def func6(n, *args, **kwargs):
    print(n, args, kwargs)
    func6(1)  #1,空元组,空集合
    func6(1, 2, 3,)  #1.(2, 3){}
    func6(1, 2, 3, a=1, b=2) #1,(2, 3){'a':1, 'b':2}
"""
由于*和**在函数的形象中使用频率很高,后面跟的变量名推荐使用
	*args
	**kwargs
def index(*arge, **kwarfgs):pass
"""

可变长实参

    def index(a, b, c):
        print(a, b, c)


    l1 = [11, 22, 33]
    t1 = (11, 22, 33)
    s1 = 'tom'
    se = {123, 321, 222}
    d1 = {'username':'jason', 'pwd':123, "age": 18}
    # 以上的代码数据值取出来传给函数的三个位置形参
    index(*l1)  # 11 22 33,打散列表
    index(*t1)  # 11 22 33,打散元组
    index(*s1)  # t o m,打散字符串
    index(*se)  # 321 123 222,打散集合
    index(*d1)  # username pwd age 特别注意取出来的是键
    """*在实参中
        类似于for循环,将所有循环遍历出来的数据按照位置参数一次性传给
    函数
    """
    def index(username, pwd, age):
        print(username, pwd, age)


    d1 = {'username': 'jason', 'pwd': 123, 'age': 18}
    # index(username=d1.get('username'), pwd=d1.get('pwd'), age=d1.get('age'))
    index(**d1)  # index(username='jason',pwd=123,age=18)
    """
    **在实参中
        将字典打散成关键字蚕食的形式传递给函数
    """

命名关键字参数(了解)

'''形参必须按照关键字参数传值>>>:命名关键字参数'''


def index(name, *args, gender='male', **kwargs):
    print(name, args, gender, kwargs)

# index('jason',1,2,3,4,a=1,b=2)
index('jason', 1, 2, 3, 4, 'female', b=2)

名称空间

"""
name = 'jason'
底层原理:
1.申请内存空间存储jason
2.给jason绑定一个变量名name
3.后续通过变量名name就可以访问jason
"""
名称空间就是用来存储变量名与数据值绑定关系的地方(也可以理解为存储变量名的地方)
1.内置名称空间
	解释器运行自动产生,里面包含了很多名字
    比如:len print input
2.全局名称空间
	py文件运行产生,里面存放文件级别的名字
    	name = 'jason'
        
       if name:
         age = 18
            
       while True:
         gender = 'male'
            
       def index():pass
    
   		class MyClass(object):
            pass
      name\age\genger\index\MyClass
3.局部名称空间
	函数体代码运行\类体代码运行  产生的空间

image

名称空间存活周期及作用范围(域)

存活周期
	内置名称空间
    python解释器启动则创建,关闭则销毁
  	 全局名称空间
    py文件执行则创建,运行结束则销毁
    局部名称空间
    函数体代码运行创建,函数体代码结束则销毁
    
    
    内置名称空间
    	解释器级别的全局有效
    全局名称空间
    	py文件级别的全局有效
     局部名称空间
    	函数体代码内有效

名字的查找顺序

涉及到名字的查找,一定要先搞明白自己在哪个空间
1.当我们在局部名称空间中的时候:
	局部名称空间>>>全局名称空间>>>内置名称空间
2.当我们在全局名称中间中的时候
	全局名称空间>>>内置名称空间
查找名字的顺序也可以理解为从自己空间出发向外寻找,不会向内
ps:其实名字的查找顺序是可以打破的

image

查找循序案例

1.相互独立的局部名称空间默认不能够互相访问
    def func1():
        name = 'jason'
        print(age)


    def func2():
        age = 17
        print(name)
2.局部名称空间嵌套
	先从自己的局部名称空间查找,之后由内而外依次查找
    
函数体代码中名字的查找顺序在函数定义阶段就已经固定死了
    x = '干饭了'
    def funcl():
        x = 1
        def func2():
            x = 2
            def func3():
                x = 3
                print(x)
            func3()
        func2()
    funcl()

作业

money = 100
def index():
     money = 666
print(money)
money的值是100,函数indec()并没有引用,不会产生局部名称空间

money = 100
def func1():
    money = 666
     def func2():
     	money = 888
    func2()
print(money)
money的值是100,因为我们所处的空间是在全局名称空间,虽然函数func2调用了,但是按照名字查找顺序自身在全局名称空间不会到局部名称空间寻找
posted @   雪语  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示