函数(参数+名称空间)

# 函数(参数+名称空间)

1.函数前戏

l = [11, 22, 33, 44, 55, 66, 77, 88]
print(len(l))  # 假设len无法使用

def my_len():
    n = 0
    for i in l:
        n += 1
    print(n)
print(my_len())
"""
1.我们现在所写的代码无法做到精简 需要用就必须重复写
    模仿len的内部源码
2.我们现在所写的代码兼容性极差(无法解决)
3.我们现在所写的代码没有返回值(无法解决 使用之后的返回结果)
函数简介
    函数就类似于是工具 提前定义好之后可以反复使用
"""

2.函数语法结构

# 函数语法结构
"""
def 函数名(参数1,参数2):
    '''函数注释'''
    函数体代码
    return 返回值
    
1.def(必须的)
    是定义函数的关键字
2.函数名(必须的)
    是函数的名字 相当于变量名
    函数名的命名规范与风格遵循变量名的
3.参数1,参数2(可选的)
    参数可以没有也可以有多个 
    表示在使用函数之前需要满足的一些条件
4.函数注释(可选的)
    类似于产品说明书
    主要用于介绍函数功能 参数使用 及其他情况
5.函数体代码(必须的)
    函数核心的代码逻辑(重要)
6.return返回值(可选的)
    使用函数之后反馈给使用者的结果 可以有也可以没有
"""

3.函数的定义与调用

###########################################################
1.函数必须先定义后调用(顺序不能乱)
2.函数在定义阶段只检测语法不执行代码
3.函数在调用阶段才会执行函数体代码
	如何调用函数
    	函数名加括号 如果函数在定义阶段有参数则在调用阶段也需要给参数
###########################################################
函数在定义与调用阶段底层原理
1.在内存空间中申请一块空间存储函数体代码
2.将函数体代码所在的空间地址绑定给函数名
3.函数名加括号则会执行函数体代码

4.函数的分类

1.内置函数
	python解释器自带的(提前给你定义好了 你直接使用即可)
2.自定义函数
	程序员自己写的函数
    2.1.无参函数
    2.2.有参函数
    2.3.空函数
 
# 无参函数:在函数定义阶段括号内没有写参数(变量名)
# def my_func():
#     print('这个函数很牛逼')

# 有参函数:在函数定义阶段括号内写了参数(变量名)
# def my_func(a,b):
#     print('这个函数更牛逼')
# my_func(1,2)

# 空函数:函数体代码为空(pass ...)
"""
虽然空函数本身没有含义 但是空函数可以提前规定好编写代码的思路
"""
def run():
    pass
def fight():
    pass
def talk():
    pass

4.函数参数的两大分类

1.形式参数

在函数定义阶段括号内填写的参数,简称:形参
image

2.实际参数

在函数调用阶段括号内填写的参数,简称:实参
image

形参与实参两者之间的差别
形参可以看成是变量名,而实参就是变量值
两者在运行函数式进行临时绑定,不运行时互不干扰,相安无事。
*形参只有一种形式就是变量名,而实参不然,可以是多种形式数据值

5.形参与实参的表现方法

*位置参数

位置参数定义:就是按照从左往右的顺序依次填写参数
1.位置形参
定义:在函数定义阶段按照从左往右的顺序依次填入的参数
image

2.位置实参
定义:在函数调用阶段按照从左往右的顺序依次填入的参数
image

定义一个可以比较大小的函数(传入两个值 返回较大的)

*默认参数

默认参数就是默认形参,函数在定义阶段就可以给形参赋值了
1.该形参如果在函数被调用的时候不给值,则使用默认的
2.该形参在函数被调用的时候可以继续给值,就是使用你给的值
image
PS:位置形参必须在默认形参的前面,格式越简单的越靠前。

*关键字实参(可以打破顺序)

定义:在函数调用时候,形参名=数据值的形式,指名道姓的传值。
image

可变长参数

可变长函数就是函数无论传入多少位置参数都可以正常运行。

1.可变长形参

1.1在形参的变量名前面加一个星号 *变量名

image
一个星号在形参中的作用:用于接受多余的位置参数,并组织成元组的形式赋值给星号后面的变量名

1.2在形参的变量名前面加两个星号 **变量名

image
两个星号在形参中的作用:用于接收多余的关键字参数 并组织成字典的形式赋值给号后面的变量名**

1.3.定义一个函数无论传入多少位置参数和关键字参数都可以正常运行

image
PS:墨守成规的书写规则,可变长形参 *与**后面的变量名最好写成 *args **kwargs
image

2.实际应用

如果index形参是*args 列表里面有很多元素 如何实现按照位置一一传入
image
星号在应用中会将列表、元组内的元素打散成位置参数的形式一个个的传值。

如果index形参是**kwargs
image
星号在应用中会将字典内的键值对打散成关键字参数传入

3.函数参数补充(了解)

def register(name,age,*,sex,height):
    pass

# register('jason',18,'male',183)
register('lili',18,sex='male',height='1.8m') #正确使用
"""
sex height在传入实参的时候必须以关键字参数的形式

ps:该类型的参数几乎不用 也几乎很少能碰到
"""

名称空间 namespace

1.定义:用于存放变量名和变量值关系的地方

2.分类(重点)

2.1内置名称空间

python解释器提前给你定义好的 如print() len()等

2.2全局名称空间

在py文件中顶格编写的代码运行之后都会存入全局名称空间。
image

2.3局部名称空间

函数体代码运行之后产生的都是局部名称空间
image

名字的查找顺序(笔试题)

记住:在查找名字的时候 要先确定自己当前在哪,自己在哪一层那就是哪一层
image
题目的代码如下

# 局部名称空间的嵌套 
'''函数在定义阶段名字的查找顺序就已经固定死了(特例)'''
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()
输出结果是555

问题在于嵌套在 def f4中的变量x,如果顺序变换后,输出结果是什么?
image

名称空间的作用域

定义:就是名称空间能够作用的范围
image

global 和 nonlocal 关键字使用

要想在局部修改全局数据,如果数据为不可变类型则需要关键字global声明,如果数据为可变类型则无需关键字global声明
<<<局部修改全局变量 需要使用关键字声明>>>
不可变类型:
image
可变类型:
image
<<<内部局部修改外部局部变量>>>
image
如果想要在内部的局部修改外部局部的不可变类型数据,需要关键字nonlocal声明
image
image

posted @ 2021-11-12 16:59  Panda_Xin  阅读(29)  评论(0编辑  收藏  举报