python里的函数学习_14-Python基础知识学习---函数基础

定义函数

函数是带有名称的代码块,用于完成具体的工作,通过调用函数可以执行其中定义的特定任务。如果需要在程序中多次执行同一项任务,这时候就无需反复编写完成该任务的代码,只要执行该任务的函数,让Python执行其中的代码即可。

函数的使用必须遵循 "先定义,后使用" 的原则。函数的定义就相当于事先将函数体代码保存起来,然后将内存地址赋值给函数名,函数名就是对这段代码的引用,这个变量的定义是相似的。简单的函数定义的语法如下:

def 函数名(参数1,参数2,...):

函数体

return 值

def:该关键词用来告诉Python要定义一个函数

函数名:函数名指向函数内存地址,是对函数体代码的引用( 函数的命名应该反映出函数的功能 )

括号:括号内用来定义参数, 参数是可有可无的,且无需指定参数的类型

冒号:括号后面需要加上冒号,然后在下一行开始编写函数体的代码

函数体:由语句和表达式组成

return值:定义函数的返回值, return是可有可无的

def say_hello():

'''

作者:FQYY

描述:定义了一个打印消息的函数

返回值:无

参数:无

'''

print("Hello World")

定义函数的时候发生的事情:

申请内存空间保存函数的代码

将上述的内存地址绑定到函数名

定义函数的时候不会执行函数体的代码,但是会检测函数体的语法

函数的调用使用 函数名() 的方式,只有在函数调用的时候才会执行函数体代码:

def say_hello():

'''

作者:FQYY

描述:定义了一个打印消息的函数

返回值:无

参数:无

'''

print("Hello World")

say_hello() # Hello World

调用函数的时候发生的事情:

通过函数名找到函数内存地址

加括号就是在触发函数体代码的执行

函数可以调用多次:

def say_hello():

'''

作者:FQYY

描述:定义了一个打印消息的函数

返回值:无

参数:无

'''

print("Hello World")

say_hello() # Hello World

say_hello() # Hello World

当函数体代码为 pass 的时候表示什么都不做,称之为空函数 。在程序设计的开始,往往是先想好程序都需要完成什么功能,然后将所有的功能都列举出来用pass充当函数体占位符。这使得程序的体系结构立见、代码清晰且可读性强。后期可以根据编程任务去选择性的实现上述功能来替换掉pass,从而提高开发的效率:

def connect():

'''

链接数据库

'''

pass

返回值

函数并不总是用来直接显示输出的,有时候也需要处理一些数据并返回一个或者多个值:

def get_message():

'''

返回一个字符串

'''

return "Hello World"

print(get_message()) # Hello World

当省略return语句或者return后面没有值的时候,函数的返回值是None:

def getMessage():

return

def sayHello():

pass

print(getMessage()) # None

print(sayHello()) # None

函数的返回值是没有类型限制的:

# 返回字符串

def returnString():

return "Hello World"

# 返回数字

def returnNumber():

return 12

# 返回列表

def returnList():

return [1, 2, 3, 4]

# 返回字典

def returnDic():

return {"name": "张三", "age": 12}

# 返回元祖

def returnTuple():

return (1, 2, 3)

# 或者

def returnValue():

return 1, 2, 3

return是一个函数结束的标志,函数内可以有多个return语句,但是只执行一次return语句就结束了:

def getMessage():

return "Hello World"

return "Hello Python"

print(getMessage()) # Hello World

传递参数

在定义函数的时候可以传递参数,函数的参数分为形参和实参:

形参:在定义函数的时候括号内声明的参数。形参本质就是一个变量名,用来接受外部传来的值

实参:调用函数时括号内传入的值,值可以是变量、常量、表达式或者三者的组合

def say_hello(username):

print("Hello {}".format(username))

say_hello("Jack")

在上面的案例中,username 就是一个形参,而在调用函数的时候传入的 Jack 就是一个实参,即在调用函数的时候将 Jack 传递给了 username 。

注意: 在调用有参数函数时,实参(值)会赋值给形参(变量名)。在Python中,变量名与值只是单纯的绑定关系,而对于函数来说这种绑定关系只有在调用函数的时候生效,函数调用结束后就解散。

在函数定义的时候可以包含多个形参,因此调用函数的时候也可以包含多个实参,向函数传递实参的方法很多,下面介绍的是几个常见的函数传递方法。

位置参数

位置参数是基于参数的顺序,要求实参的顺序和形参的顺序相同:

def greet_user(username, age):

print("My name is {}, I'm {} years old".format(username, age))

greet_user("Jack", 16)

greet_user("Tom", 18)

关键字参数

每个实参都是由变量名和值组成,因为直接在实参中将名称和值关联起来,所以向函数传递实参的时候不会发生混淆。关键字参数让你无需考虑函数调用中的实参的顺序,还清楚地指出了函数调用中各个值的用途:

def greet_user(username, age):

print("My name is {}, I'm {} years old".format(username, age))

greet_user(username="Jack", age=16)

greet_user(age=18, username="Tom")

使用关键字参数的时候需要注意下面几点:

使用关键字实参的时候,务必准确地指定函数定义的形参名

必须保证关键字参数在位置参数后面

不可以对一个形参重复赋值

def printInfo(username, age, gender):

print("name: {}, age: {}, gender: {}".format(username, age, gender))

printInfo(username="Jack", age=18, sex="man")

# TypeError: printInfo() got an unexpected keyword argument 'sex'

printInfo(username="Jack", 18, gender="man")

# SyntaxError: positional argument follows keyword argument

printInfo(username="Jack", age=18, gender="man", gender="woman")

# SyntaxError: keyword argument repeated

默认值

编写函数的时候可以给每个参数指定默认值,如果在调用函数的时候给这些形参指定了实参,Python将使用传递的实参值,否则将使用形参的默认值:

def greet_user(username, age=20):

print("My name is {}, I'm {} years old".format(username, age))

greet_user(username="Jack", age=19) # My name is Jack, I'm 19 years old

greet_user(username="Tom") # My name is Tom, I'm 20 years old

注意:有默认值的形参必须放在没有默认值的形参的后面。

可变长度的参数

有时候预先不知道要接受多少个实参,Python允许函数从调用语句中传递任意数量的实参。

可变长度的位置参数

如果在最后一个形参名前面加上 "*" ,那么在调用函数的时候,所有多出来的位置实参都会被该参数接收,并且会以元祖的形式保存下来( 即便只收到一个值 ,Python 也会将实参封装到一个元祖中 ):

def find_user(*user):

print(user)

find_user("Jack")

find_user("Jack", "Tom")

# ('Jack',)

# ('Jack', 'Tom')

如果想要让函数接受不同类型的参数,必须在函数定义中将可变长度的形参放在最后,Python会先匹配位置实惨和关键字实惨,再将余下的实参都收集到最后一个形参中:

def func_user(num1, *numbers):

print(num1)

print(numbers)

func_user(12,12,32,23)

# 12

# (12, 32, 23)

也可以将一个列表传递给可变参数:

def func_user(num1, *numbers):

print(num1)

print(numbers)

func_user(1, *[2, 3, 4])

# 1

# (2, 3, 4)

传入列表的时候在前面加上 "*" 的意思是将列表中的值进行解压,然后赋值给可变参数。如果这里不加就会将列表当作一个整体传递给可变参数:

def func_user(num1, *numbers):

print(num1)

print(numbers)

func_user(1, [2, 3, 4])

# 1

# ([2, 3, 4],)

可变长度的关键字实惨

如果在最后一个形参名前加 "**" ,那么在调用函数时,所有多出来的关键字参数都会被该形参接收,并且会以字典的形式保存下来:

def func_user(first_name, last_name, **user_info):

print(first_name)

print(last_name)

print(user_info)

func_user("Stephen", "Curry", local="American", age=32)

# Stephen

# Curry

# {'local': 'American', 'age': 32}

也可以将字典传递给可变参数:

def func_user(first_name, last_name, **user_info):

print(first_name)

print(last_name)

print(user_info)

info = {"local": "American", "age": 32}

func_user("Stephen", "Curry", **info)

# Stephen

# Curry

# {'local': 'American', 'age': 32}

如果在传入字典的时候没有在字典前面加上 "**" ,那么该字典就是只是一个普通的位置参数了,这个时候运行程序就会报错:

def func_user(first_name, last_name, **user_info):

print(first_name)

print(last_name)

print(user_info)

info = {"local": "American", "age": 32}

func_user("Stephen", "Curry", info)

# TypeError: func_user() takes 2 positional arguments but 3 were given

命名关键字参数

在定义了可变长度的关键字参数后就可以传入任意的关键字参数,但如果函数体代码的执行就需要依赖与某个key,此时就必须在函数内进行判断:

def func_user(first_name, last_name, **user_info):

if "gender" in user_info:

pass

如果想要限定函数的调用者必须以 key=value 的形式传入一些值,在Python3中可以在定义形参的时候使用一个 "*" 作为分隔符号,在这个 "*" 之后的形参称之为 命名关键字参数 。对于这类参数,在函数调用的时候必须按照 key=value 的形式为其传值,且必须得传值:

def printInfo(name, age, *, gender, salary):

pass

printInfo('lili', 18, gender='male', salary=12) # 正确使用

printInfo('lili', 18, 'male', 12)

# # TypeError: printInfo() takes 2 positional arguments but 4 were given

printInfo('lili', 18, gender='male')

# TypeError: printInfo() missing 1 required keyword-only argument: 'salary'

命名关键字参数也可以有默认值:

def printInfo(name, age, *, gender="male", salary):

pass

printInfo('lili', 18, salary=12)

注意: 这里的形参 gender='male' 属于命名关键字参数的默认值,因而即便是放到形参 salary 之前也不会有问题。

如果形参中已经创建了一个可变长度的参数,那么命名关键字参数就不再需要一个单独的 "*" 作为分隔符:

def printInfo(name, age, *info, gender="male", salary):

pass

printInfo('lili', 18, 1,salary=12)

组合参数

前面介绍的所有的参数都可以任意组合使用,但定义的顺序必须是: 位置参数、默认参数、*定义的可变参数、命名关键字参数、**定义的可变参数 :

def printInfo(name, age=20, *args, gender="male", **kwargs):

print(name, age, args, gender, kwargs)

printInfo("Jack", *[1,2,3], salary=20)

# Jack 1 (2, 3) male {'salary': 20}

注意: *args、**kwargs中的args和kwargs可以被替换成其它的名称,但使用args、kwargs是约定俗成的。

列表参数

在函数中是可以修改列表的,也就是说如果将列表传入到函数中,那么在函数中对列表的操作会影响到列表本身:

user = ["Tom", "Jack", "Clair"]

del_user = []

def func_del_user(old_user, new_user):

while old_user:

new_user.append(old_user.pop())

func_del_user(user, del_user)

print(user) # []

print(del_user) # ['Clair', 'Jack', 'Tom']

注意: python传递的是内存地址。

如果不想修改原列表,可以使用下面的方法:

user = ["Tom", "Jack", "Clair"]

del_user = []

def func_del_user(old_user, new_user):

while old_user:

new_user.append(old_user.pop())

func_del_user(user[:], del_user)

print(user) # ["Tom", "Jack", "Clair"]

print(del_user) # ['Clair', 'Jack', 'Tom']

函数类型提示

在Python3.5之后,可以对函数的参数和返回值设置类型提示:

def register(name:str, age:int=18)->int:

print(name)

return 1

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值