一、函数参数的两大分类

形式参数
    在函数定义阶段括号内所填写的参数,简称"形参"
	def func(a, b):
		pass
	# a和b就是函数func的形参
实际参数
    在函数调用阶段括号内传入的参数,简称"实参"
	func(1, 2)
	# 1和2就是函数func的实参
形参和实参的关系
    我们可以将形参看成是变量名,实参看成是变量值
	两者在函数调用阶段临时绑定,函数运行结束断开

形参的表现形式只有一种就是变量名
实参的表现形式有很多种,但是其核心还是数据值

二、形参与实参的具体使用

位置参数
    按照从左往右的顺序依次填入的参数
位置形参
    在函数定义阶段括号内按照从左往右的顺序依次填入的变量名
位置实参
    在函数调用阶段括号内按照从左往右的顺序依次填入的数据值

# 定义一个可以比较大小的函数(传入两个值,返回较大的)
	def my_max(a, b):
		if a > b:
			return a
		return b
	# res = my_max(b=123,a=222)  # 指名道姓的传
	# res = my_max(111,b=222)  # 可以

关键字实参(可以打破位置顺寻)
    在函数调用阶段通过形参名=数据值的形式指名道姓的传值
"""
1.位置形参与位置实参在函数调用阶段,按照位置一一对应绑定
2.位置参数在绑定的时候多一个不行少一个也不行
"""
'''注:格式越简单的越靠前,格式越复杂的越靠后'''

默认参数
    默认形参
	函数在定义阶段就可以给形参赋值了
	1.该形参在函数调用阶段如果不给值,则使用默认的
	2.该形参在函数调用阶段可以继续给值,则使用给的

	def register(name, age, sex='male'):
		print('%s:%s:%s' % (name, age, sex))
	register('jason', 18) # jason:18:male
	register('lil', 18, 'female') # lili:18:female
	register('lil', 18, gender='female') # lili:18:female

"""
位置形参与默认值形参在定义的时候
    位置形参必须在默认值形参的前面
"""

# m = 200
# def func(a, b, c=m):
#     print(a, b, c)
# m = 400
# func(1, 2)  # 1 2 200

"""
角度1
    默认值形参在函数定义阶段就已经固定死了 不会随着后续的变化而变化
角度2(更容易理解)
    变量名与值的绑定关系
"""

可变长参数

# 1.函数无论传入多少位置参数都可以正常运行
可变长形参
	def func(*a):
	    print(a)
	# func()  # ()
	# func(1)  # (1,)
	# func(1, 2, 3, 4, 5, 6, 7)  # (1, 2, 3, 4, 5, 6, 7)
	def func(x, y, *a):
	    print(x, y, a)
	# func(1,2)  # 1 2 ()
	# func(1,2,3,4,5,6,7,8,9)  # 1 2 (3, 4, 5, 6, 7, 8, 9)
"""
*号在形参中的使用
    用于接收多余的位置参数,并组织成元组的形式赋值给*号后面的变量名
"""


# 2.函数无论传入多少关键字参数都可以正常运行
	def index(**b):
	#     print(b)
	# index()  # {}
	# index(a=1,b=2,c=3,d=4)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
	def index(x, y, **b):
	    print(x, y, b)
	# index(y=2, x=1)  # 1 2 {}
	# index(y=2, x=1, u=222, k=111, l=444)  # 1 2 {'u': 222, 'k': 111, 'l': 444}
"""
**号在形参中的使用
    用于接收多余的关键字参数,并组织成字典的形式赋值给**号后面的变量名
"""


# 3.定义一个函数无论传入多少位置参数和关键字参数都可以正常运行
	def index(*a,**b):
	#     print(a,b)
	# index()  # () {}
	# index(1,2,3,4)  # (1, 2, 3, 4) {}
	# index(a=1,b=2,c=3)  # () {'a': 1, 'b': 2, 'c': 3}
	# index(1,2,3,4,a=1,b=2,c=3)  # (1, 2, 3, 4) {'a': 1, 'b': 2, 'c': 3}
"""
墨守成规
    可变长形参 *与**后面的变量名其实是可以随便定义的
	但是python中推荐使用
	   *args
	   **kwargs
def index(*args, **kwargs):
    pass
"""
# def index(a, b, c):
#     print(a,b,c)
# new_list = [11,22,33]
'''如果index形参是*args 列表里面有很多元素 如何实现按照位置一一传入'''
# def index1(*args):
#     print(args)
# new_list1 = [11,22,33,44,55,66,77,88,99]
# index1(*new_list1)  # index1(11,22,33,44,55,66,77,88,99)
# (11, 22, 33, 44, 55, 66, 77, 88, 99)
"""
*号在实参中的使用
    会将列表、元组内的元素打散成位置参数的形式一一传值
"""

# def index2(**kwargs):
#     print(kwargs)
new_dict = {'username':'jason','pwd':123}
# index2(**new_dict)  # index2(username='jason',pwd=123)
# {'username': 'jason', 'pwd': 123}
"""
**号在实参中的使用
    会将字典内的键值对打散成关键字参数传入
"""

函数参数补充(了解)

命名关键字参数
	def register(name,age,*,sex,height):
		pass

	# register('jason',18,'male',183) # TypeError: register() takes 2 positional arguments but 4 were given

	register('lili',18,sex='male',height='1.8m') #正确使用
	# lili 18 male 1.8m

"""
sex height在传入实参的时候必须以关键字参数的形式
ps:该类型的参数几乎不用 也几乎很少能碰到
"""

三、名称空间

# 什么是名称空间(namespaces)
    用于存放变量名与变量值绑定关系的地方(类似于民政局)

# 名称空间的分类(重要)
1.内置名称空间
    python解释器提前给你定义好的 
	print()
	len()
	...
2.全局名称空间
    在py文件中顶格编写的代码运行之后都会存入全局名称空间
	name = 'jason'  # name全局
	def func():     # func全局
	    pass
	if 1:
	    a = 123     # a全局
	for i in range(10):
	    print(i)    # i全局
	while True:
	    a = 123     # a全局
3.局部名称空间
    函数体代码运行之后产生的都是局部名称空间


# 存活周期
1.内置名称空间
    python解释器启动与关闭而创建和销毁
2.全局名称空间
    随着py文件的运行与结束而创建和销毁
3.局部名称空间
    随着函数体代码的执行与结束而创建和销毁

名字的查找顺序

# 在查找名字的时候 要先确定自己当前在哪
1.如果你在局部
    局部 >>> 全局 >>> 内置
2.如果你在全局
    全局 >>> 内置

# 局部名称空间的嵌套 
'''函数在定义阶段名字的查找顺序就已经固定死了(特例)'''
x = 111
def f1():
    x = 222
    def f2():
        x = 333
        def f3():
            x = 444
            def f4():
                x = 555
                print(x)
                # x = 555  特例
            f4()
        f3()
    f2()
# 通过调用f1 执行所有的函数
f1()

image

三、作用域

作用域:名称空间所能够作用的范围

内置名称空间:程序任何阶段任何位置均可使用(全局有效)
全局名称空间:程序任何阶段任何位置均可使用(全局有效)
局部名称空间:一般情况下只在各自的局部名称空间中有效

global与nonlocal关键字使用

# x = 111
# def index():
#     # 局部修改全局变量 需要使用关键字声明
#     global x
#     x = 222
# index()
# print(x) # 222


# name_list = ['jason', 'kevin']
# def index():
#     name_list.append('heiheihei')
# index()
# print(name_list) # ['jason', 'kevin', 'heihei']

"""
如果想在局部修改全局数据
    如果数据为不可变类型则需要关键字global声明
    如果数据为可变类型则无需关键字global声明
"""
def index():
    x= 11
    def func():
        # 内部局部修改外部局部
        nonlocal x
        x = 222
    func()
    print(x)
index() # 222

def index():
    # x = 111
    l1 = [11,22]
    def func():
        # 内部局部修改外部局部
        l1.append(333)
    func()
    print(l1)
index() # [11, 22, 33]
"""
如果想要在内部的局部修改外部局部的不可变类型数据
需要关键字nonlocal声明
"""
posted on 2021-11-15 19:15  幽星  阅读(295)  评论(0)    收藏  举报