python3--函数

1.函数定义

def 函数名(形参):
    '''注释'''
    函数体
    return 返回值

函数名:只能包含字母、数字、下划线且不能以数字开头。函数名尽量简短,并能表达函数功能。

函数名的本质就是函数的内存地址(可被引用、可被当作函数的参数和返回值、可被当作容器类型的元素)

注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。

返回值:如果没有return,默认返回值为None;返回值可以有一个或者多个,多个返回值作为一个元组被返回。

调用:函数名(实参) 

参数类型:位置参数、默认参数、动态参数。

位置参数
1)按照位置传值

2)按照关键字传值

3)位置、关键字混用

def func(a,b):
    print(a,'***',b)
func(1,2)  # 1 *** 2  按位置传参
func(b=2,a=1)  # 1 *** 2  按关键字传参
# func(a=1,2)  # 错误
func(1,b=2)  # 1 *** 2  位置和关键字混用

特别注意:

①位置、关键字传值混用时,位置参数必须在关键字参数的前面;

②一个形参只能赋值一次;     

③位置参数必须传值。


默认参数(将参数值变化小的参数设置为默认参数)

def fun(a,b=1):
    print(a,'>>>',b)
fun(3)  # 3 >>> 1
fun(3,3)  # 3 >>> 3

特别注意:当默认参数类型为可变数据类型时的陷阱

如果默认参数的值是一个可变的数据类型,那么每一次调用函数使用默认参数值时,这个参数相当于一个全局变量,会受其他几次调用的影响。

def funcc(a,b=[]):
    b.append('aabb')
    print(a,'&&&',b)
funcc(1)  # 1 &&& ['aabb']
funcc(2,[2])  # 2 &&& [2, 'aabb']
funcc(3)  # 3 &&& ['aabb', 'aabb']
funcc(4,[4])  # 4 &&& [4, 'aabb']
funcc(5)  # 5 &&& ['aabb', 'aabb', 'aabb']

动态参数

   *args(任意多个位置参数),组成的是元组;**kwargs(任意多个关键字参数),组成的是字典;*args,**kwargs组合使用,可以传任意个参数。

特别注意:*args必须在**kwargs之前 。

def sum(*args):
    '''数字求和'''
    cal = 0
    for i in args:
        cal += i
    return cal
print(sum(1,2,5,7))  # 15 与下面传参方式等价
print(sum(*[1,2,5,7]))  # 15 列表前加上*,就是将列表按照顺序打散
def funs(**kargs):
    for i in kargs:
        print(i,'@@@',kargs[i])
funs(name='maty',sex='male')  # 与下面传参方式等价
funs(**{'name':'maty','sex':'male'})  # 字典前加上**,就是将字典打散
# sex @@@ male
# name @@@ maty
def gun(*args,v=[1],**kwargs):
    print(v)
    for i in args:
        print(i)
    for i in kwargs:
        print(i,'@@@',kwargs[i])
gun(1,7,v=[2],a=3,b=4)
#[2]
# 1
# 7
# b @@@ 4
# a @@@ 3

三种类型参数顺序:必须先定义位置参数,再定义动态参数*args,再默认参数,再动态参数**kwargs

2.命名空间

命名空间存放名称与值的对应关系。

命名空间的类型:全局命名空间global、局部命名空间local、内置命名空间built-in

1)内置命名空间-- python解释器一启动就可以使用的名字,存储在内置命名空间中,如list()... 。内置的名字在启动解释器的时候被加载进内存。

2)全局命名空间--编码者写的除函数内的代码。程序从上到下执行的过程中依次加载进内存 ,放置了我们设置的所有变量名和函数名。

3)局部命名空间--函数内部定义的名字 。当函数调用的时候,产生此名称空间,随着函数执行的结束,这个命名空间被释放了。

命名空间加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

命名空间的取值顺序:

1)局部调用时,局部命名空间->全局命名空间->内置命名空间,如果局部没有就会找上一级全局要,全局没有再找内置要,不能逆向。

2)全局调用时,全局命名空间->内置命名空间,如果全局没有就找内置要。

x=10
def fung(x):
    print(locals())
    print(x)
fung(20)  # 20  局部变量
print(x)  # 10  全局变量
print(min)  # <built-in function min> 内置函数

3.作用域

作用域就是作用范围。

作用域分类:全局作用域和局部作用域。

1)全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效。

内置函数globals(),可查看所有的全局名称。

2)局部作用域:局部名称空间,只能在局部范围内生效。

内置函数locals(),放在函数中可查看所有的局部名称,但是放在全局作用域则和globals()查询结果相同

作用域中关键字。

1)global关键字。

对于不可变数据类型,在局部可查看全局作用域中的变量,但不可直接修改,如果想修改,须在程序一开始添加global声明。 如果一个局部内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效 。

y = 10
def fund():
    y=11
    print(y)  
fund()  # 11    局部变量
print(y)  # 10  全局变量

  修改全局变量

y = 10
def fund():
    global y
    y = 11
    print(y)
fund()  # 11   全局变量
print(y)  # 11 全局变量

2)nonlocal关键字。

nonlocal只能用于局部变量(对全局无效),声明了一个上层局部变量(离得最近的局部变量),从而可以修改上层局部变量的值。

def fun1():
    x = 3
    def fun2():
        nonlocal x
        x = 4
        print(x)
    fun2()    # 4
    print(x)  # 4
fun1()

4.闭包

闭包函数:内部函数包含对外部作用域而非全局作用域名称的引用。

# 内部函数名.__closure__,有cell说明是闭包,如果为None,则非闭包函数

def outer():
    a = 1  # 外部函数变量
    def inner():
        print(a)  # 内部函数调用外部函数的变量
    print(inner.__closure__)  # (<cell at 0x0000021F7872ADF8: int object at 0x000000006357EF30>,)
    return inner
inn = outer()  # 获得inner内存地址
inn()  # 1  调用inner函数

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值