16.Python基础篇-函数

函数的基本使用

函数的含义:

函数是执行特定任务的独立代码块,函数可以接受参数,并返回值,帮助我们简化代码,并在不同地方复用相同的功能。

特点:可读性强,可复用性强

函数的定义与调用

定义:

使用def关键字定义一个函数

def 函数名(参数1,参数2):
    函数体
    return返回值

调用语法

函数名(参数)  # 方式一:调用函数,不接受返回值

返回值 = 函数名(参数)  # 方式二:接收函数的返回值,赋值给一个变量

函数的参数,分为形参与实参

形参与实参:形参是在定义函数时,用来指定函数可以接收的参数名称;实参是在调用函数时,传递给函数的真实值。实参是传递给形参的具体数据。

形参:

位置参数

def func(a, b):
    print(a + b)

默认参数

def func(a, b=1):  # b为默认参数,默认值为1
    print(a + b)


# 将1赋值给a,b使用默认值,默认值为1。则输出结果为:2
func(1)  # 默认参数可以不传

# 将1复制给a,b赋值为3,不使用默认值。输出结果为:4
func(1, 3)  

可变参数:*args

args,只是一个变量名,可以自定义,但是一般都使用args(约定俗成)

def func(*args):  # args实际为一个元组,传入的每一个参数为元组中一个元素
    print(args)


func(1)  # 可以传1个值

func(1, 2, 3, 4)   # 也可以传多个值

可变参数:**kwargs

kwargs,只是一个变量名,可以自定义,但是一般都使用kwargs(约定俗成)

def func(**kwargs):  # kwargs实际为一个字典,接收到的参数存储为键值对
    print(kwargs)


func(name='mingbo', age=18)  # 往kwargs这个字典中传入两个键值对

# 输出:
{'name': 'mingbo', 'age': 18}

定义形参的顺序

位置参数--->*args--->默认参数-->**kwargs

def func(name, *args, age=18, **kwargs):
 print(name)
 print(args)
 print(age)
 print(kwargs)


# mingbo赋值给name
# (1,2,3)赋值给args
# 19赋值给age
# {sex:男}赋值给kwargs
func('mingbo', 1, 2, 3, age=19, sex='')

# 输出:
邵明博
(1, 2, 3)
19
{'sex': ''}

实参

按照位置传参

def func(a, b):
 print(a, b)
 
func(1, 2)  # 按照位置传参,将1传给a,2传给b

# 输出:
1 2

按照关键字传参

def func(a, b):
 print(a, b)

func(a=1, b=2)  # 按照关键字传参

# 输出:
1 2

*args和**kwargs可以使用星号*和**传入一个List、字典。

def func1(*args):
 print(args)


li = [1, 2, 3, 4]
func1(*li)  # 将li这个列表中的元素,分别传入到args中
# 输出:(1, 2, 3, 4)



def func2(**kwargs):
 print(kwargs)

dic = {'name': 'mingbo', 'age': 18}
func2(**dic)  # 将dic这个字典中的键值对,分别传入到kwargs中
# 输出:{'name': 'mingbo', 'age': 18}

传参的注意点:位置参数必须在关键字传参之前。

def func(a, b):
 print(a, b)

func(1, b=2)  # 位置传参与关键字传参混合使用

# 输出:
1 2

函数的返回值

1.没有返回值(不写return)

不写return

def func():
 pass


print(func())  # 不写return,默认返回None


# 输出:
None

只写return

def func():
 return 


print(func())  # 只写return,默认也返回None

# 输出:
None

return None

def func():
 return None


print(func())  # 返回None

# 输出:
None

2.返回1个值

结束函数,并返回一个值

def func(a, b):
 return a + b


ret = func(1, 2)  # 接收返回值,存储到变量ret中
print(ret)

# 输出:
3

3.返回多个值:多个值之间使用英文逗号隔开,实际返回的是一个元组,每个返回值为其中的一个元素。 

用1个变量接收

def func(a, b):
 return a, b  # 实际返回的是一个元组(a, b),每个返回值为其中一个元组


ret = func(1, 2)  # 使用1个参数接收返回值
print(ret)  # 输出为元组类型的(1, 2)

#输出:
(1, 2)

用等量的多个变量接收

def func(a, b):
 return a, b 


a, b = func(1, 2)  # 使用变量a和b,分别接收1和2
print(a, b)  # 输出a和b

# 输出:
1 2

注意点

1.先定义后调用

2.只定义不调用,就一定不会执行

3.默认参数的陷阱:如果默认参数的值是一个可变教据类型,那么每一次调用函数的时候,如果不传值就公用这个数据类型的资源

def func(li=[]):
    li.append(1)
    print(li)


func()  # 输出:[1]
func()  # 输出:[1, 1]
func([])  # 输出:[1]
func()  # 输出:[1, 1, 1]

 命名空间与作用域

三种命名空间

1.内置命名空间--- python解释器

  就是python解释器一启动就可以使用的名字,存储在内置命名空间中。

  内置的名字在启动解释器的时候被夹在进内存里。比如print、input等

2.全局命名空间----我们自己写的代码,但不是函数中的代码

  是在程序从上到下被执行的过程中依次加载进内存的

  放置了我们设置的所有变量名和函数名

3.局部命名空间----函数中

  就是函数内部定义的名字

  当调用函数的时候,才会产生这个名称空间。随着函数执行的结束 这个命名空间就又消失了。

x = 10  # x 为全局变量

def func1():  # func1这个函数名也是全局变量
    y = 20  # 函数体中的y为局部变量

调用顺序

当前名字空间有该名字的时候,就不找上一级要了;如果当前名字空间没有,就会找上一级要。如果一直到内置的名字空间都没有,就会报错。

局部命名空间中有该名字,则优先使用局部的;

局部命名空间中没有改名字,则使用全局的;

如果全局也没有,则使用内置的;

如果内置也没有,则报错。

作用域

全局作用域

作用在全局,内置和全局命名空间中的名字都属于全局作用域。

局部作用域

作用在局部,函数(局部命名空间中的名字属于局部作用域)

注意点:

1.多个局部命名空间之间是隔离的,不能共享。并且只能是局部用全局、内置的,或者是全局用内置的,反过来则不行,比如:

内置不能使用全局,全局也不能用局部。

2.对于不可变数据类型,局部只能查看全局作用域中的变量,不能修改。如果修改,需要在程序开始处天剑global生命。

如果在一个局部(函数)内生命了一个global变量,那么这个变量在局部的所有操作会对全局的变量有效。

相关方法及关键字

global关键字

用于在函数内部声明变量为全局变量。使用 global 允许你在函数中修改全局作用域中的变量,而不是创建一个局部变量。

x = 10  # x为全局变量


def update_global():
    global x  # 声明 x 为全局变量,声明之后可以修改
    x += 5  # 修改全局变量


update_global()
print(x)  # 此时的全局变量已经在方法中被修改,并且全局生效。

输出:15

globals()方法

打印全局变量的名字

x = 10
y = 20


def func():
    z = 10


print(globals())

输出:
{...   'x': 10, 'y': 20, 'func': <function func at 0x100cba7a0>}}

nolocal

nonlocal 关键字用于在嵌套函数(即函数内部定义的函数)中声明一个变量,它作用于最近的外层函数的作用域,而不是全局作用域。使用 nonlocal 关键字可以在内层函数中修改外层函数中的局部变量。

def outer_function():
    x = "outer"

    def inner_function():
        nonlocal x  # 声明 x 来自外层函数
        x = "inner"  # 修改外层函数的局部变量

    inner_function()
    print(x)  

outer_function()

输出结果:
inner

 

globals与nolocal的区别

nonlocal 只影响最近的外层函数的作用域,还是局部作用域;而 global 影响全局作用域。

locals()方法

根据调用的位置所处的作用域,打印当前作用域下的名字。

x = 10
y = 20


def func():
    z = 10
    print('局部作用域中使用locals:' + str(locals()))  # 在局部作用域中使用,会返回局部作用域的变量


func()
print('全局作用域中使用locals:' + str(locals()))# 在全局作用域中使用,会返回全局作用域的变量

#输出结果:
  局部作用域中使用locals:{'z': 10}
  全局作用域中使用locals:{... 'x': 10, 'y': 20, 'func': <function func at 0x1049867a0>}

基础阶段总结:

在局部:可以使用全局、内置命名空间中的名字。

在全局:可以使用内置命名空间中的名字,但是不能用局部的。

在内置:不能使用全局的和局部的

posted @ 2024-10-04 01:49  邵杠杠  阅读(24)  评论(0编辑  收藏  举报