python学习笔记之初识函数

初识函数

函数的定义

def my_len(s):  #定义函数用def ,参数可写可不写
    i = 0
    for k in s:
        i += 1
    return i  #返回值

ret1 = my_len('今天也要努力工作呀')  #传递参数:传参,实际参数,实参
ret2 = my_len([1,2,3,4,5])  #传递参数:传参
print(ret1)
print(ret2)

函数的参数

定义函数的时候:
位置参数 : 直接定义参数
默认参数,关键字参数 :参数名 = '默认的值'
动态参数 : 可以接受任意多个参数
                参数名之前加*,习惯参数名args,即*args
                参数名之前加,习惯参数名kwargs,即kwargs
顺序:位置参数,*args,默认参数,kwargs

函数的返回值

返回值的3种情况:
1.没有返回值 —— 返回None
        不写return
        只写return:结束一个函数的继续
        return None  —— 不常用
2.返回1个值
        可以返回任何数据类型
        只要返回就可以接收到
        如果在一个程序中有多个return,那么只执行第一个
3.返回多个值
        用多个变量接收:有多少返回值就用多少变量接收
        用一个变量接收: 得到的是一个元组

函数的注释

def func():
    '''
    这个函数实现了什么功能
    参数1:
    参数2:
    :return: 是字符串或者列表的长度
    '''
    pass

函数小结

1.函数的定义 def
2.函数的调用
3.函数的返回值 return
4.函数的参数
    形参:
        位置参数 : 必须传
        *args :可以接收任意多个位置参数
        默认参数 : 可以不传
        kwargs : 可以接收多个关键字参数
    实参:按照位置传参,按照关键字传参

函数
    内置函数
    自定义函数 

函数进阶

函数的命名空间和作用域

命名空间的本质:存放名字与值的绑定关系
命名空间 有三种
内置命名空间 —— python解释器
    就是python解释器一启动就可以使用的名字存储在内置命名空间中
    内置的名字在启动解释器的时候被加载进内存里
全局命名空间 —— 我们写的代码但不是函数中的代码
    是在程序从上到下被执行的过程中依次加载进内存的
    放置了我们设置的所有变量名和函数名
局部命名空间 —— 函数
    就是函数内部定义的名字
    当调用函数的时候 才会产生这个名称空间 随着函数执行的结束 这个命名空间就又消失了

在局部:可以使用全局、内置命名空间中的名字
在全局:可以使用内置命名空间中的名字,但是不能用局部中使用
在内置:不能使用局部和全局的名字的
三种命名空间之间的加载与取值顺序:
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值:
  在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间

作用域

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。 全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效 局部作用域:局部名称空间,只能在局部范围内生效

globals和locals方法

# 在全局上调用globlas和locals
print(globals())
print(locals())

# 在局部上调用globals和locals
def func():
    a = 12
    b = 20
    print(locals())
    print(globals())

func()

# global关键字
a = 10
def func():
    global a
    a = 20

print(a)
func()
print(a)

函数的嵌套和作用域链

函数的嵌套调用

def max2(x,y):
    m  = x if x>y else y
    return m

def max4(a,b,c,d):
    ret1 = max2(a,b)
    ret2 = max2(ret1,c)
    ret3 = max2(ret2,d)
    return ret3

ret = max4(23,-7,31,11)
print(ret)

函数的嵌套定义

def f1():
    print("in f1")
    def f2():
        print("in f2")

    f2()
f1()
def f1():
    def f2():
        def f3():
            print("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
    
f1()

函数的作用域链

def f1():
    a = 1
    def f2():
        print(a)
    f2()

f1()
def f1():
    a = 1
    def f2():
        def f3():
            print(a)
        f3()
    f2()

f1()
def f1():
    a = 1
    def f2():
        a = 2
    f2()
    print('a in f1 : ',a)

f1()

nonlocal关键字

1.外部必须有这个变量

2.在内部函数声明nonlocal变量之前不能再出现同名变量

3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效

def f1():
    a = 1
    def f2():
        nonlocal a
        a = 2
    f2()
    print('a in f1 : ',a)

f1()

函数名的本质

函数名本质上就是函数的内存地址

1.可以被引用

def func():
    print('in func')

f = func
print(f)

2.可以被当作容器类型的元素

扫描二维码关注公众号,回复: 8520598 查看本文章
def f1():
    print('f1')


def f2():
    print('f2')


def f3():
    print('f3')

l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#调用
l[0]()
d['f2']()

3.可以当作函数的参数和返回值,就当普通变量用

第一类对象(first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体。

函数总结

命名空间 和 作用域
三种:内置 全局 局部
函数的定义和调用
def 函数名(形参):
    函数体
    return 返回值
调用 函数名(实参)
站在形参的角度上 : 位置参数,*args,默认参数(陷阱),kwargs
站在实参的角度上 : 按照位置传,按照关键字传
返回值:没有返回值 返回一个值 返回多个值
接收返回值:没有返回值不接收,返回一个值用一个变量接收,返回多个值用一个变量或者对应数目的变量接收

作用域:全局 局部 globals() locals()
        global  在局部声明一个全局变量
        nonlocal 在局部声明最近的上一层局部中的变量
作用域链 : 小范围用变量的时候,先从自己的名字空间找,
            找不到就一层一层向外层找,知道找到为止。
            找不到就报错。
函数的嵌套调用和嵌套定义
    定义在函数内部的函数不能被外界直接调用
    内部函数可以使用外部的变量
函数名的本质
    就是一串内存地址
    可以赋值、可以作为容器类型的元素、函数的参数和返回值 —— 第一类对象

闭包 : 内部函数使用外部函数的变量

def outer():
    a = 1
    def inner():
        print(a)
    return inner

i = outer()
i()

猜你喜欢

转载自www.cnblogs.com/zhangcheng94/p/12179619.html