跳至主要內容

Python中的函数

soulballad扩展PythonPython约 2989 字大约 10 分钟

在编程中,我们经常要调用相同或者类似的操作,这些相同或者类似的操作是由同一段代码完成的,而函数的出现,可以帮助我们避免重复编写这些代码。函数的作用就是把相对独立的某个功能抽象出来,使之成为一个独立的实体。

例如,我们开发一个支持人与人之间对话的社交网站,“对话”这个功能实现起来比较复杂,我们可以将它封装为一个函数,每次调用函数就可以发起对话。大型网站都有日志功能,所有重要操作都会记录日志,而日志处理需要由多行Python文件操作的相关代码组成,将这些代码组装为函数,每次写日志调用此函数即可。

1. 函数的定义

定义一个函数以 def 开头

def function_name(arg1, arg2):
function body
return value

  • 函数名(function_name): 和Python中其他标识符命名规则相同,有效的函数名以字母或下划线开头,后面可以跟字母、数字或下划线,函数名应该能反映函数的功能。

    注意: Python 中函数名区分大小写,字母相同但是大小写不同的函数视为两个不同的函数

  • 函数参数(arg1, arg2): 调用一个函数时可以传递的参数,参数可以有一个或多个,也可以没有参数

  • 函数内容(function body): 任何有效的代码都可以出现在函数内部。函数内容和 def 缩进 4 个空格

  • 函数返回值(return value): 函数执行完成后返回的值。也可以不返回任何内容,不返回内容可视为返回 “None”

def introduce(name):
    print("Hello", name)


introduce("world") # Hello world
introduce("soulballad") # Hello soulballad

2. 函数的参数

在创建函数时,可以设置参数,也可以不设置参数。对于设置参数的函数,调用时需要向函数内传递参数,被传入的参数称为实参,函数定义时的参数为形参。

Python 中的参数可以分为以下几种类型:

  • ❤ 1. 必须参数
  • ❤ 2. 关键字参数
  • ❤ 3. 默认参数
  • ❤ 4. 可变参数
  • ❤ 5. 组合参数

2.1 必须参数

必须参数:顾名思义就是函数调用时必须传入,并且在调用时数量和顺序必须和定义时参数保持一致

def add(a, b):
    print("a + b =", a + b)

add(1, 2) # a + b = 3

add(1) # 如果只传入一个参数,出现错误: TypeError: add() missing 1 required positional argument: 'b'
add(1,2,3) # 如果多传入一个参数,出现错误: TypeError: add() takes 2 positional arguments but 3 were given

2.2 关键字参数

使用关键字参数可以不按函数定义时的参数顺序来调用函数,Python解释器能够根据函数定义时的参数名字来匹配参数

def hello(name, age):
    print("姓名:", name)
    print("年龄:", age)

# 按顺序传递参数
hello(name="零一", age=18)
# 姓名: 零一
# 年龄: 18

# 不按顺序传递参数
hello(age=3, name="小明")
# 姓名: 小明
# 年龄: 3

hello(name="张三",age=20,gender="男") # 传入没有定义的参数,出现错误: TypeError: hello() got an unexpected keyword argument 'gender'

2.3 默认参数

在定义函数时可以给函数添加默认值,如果调用函数时没有传入参数,函数就会使用默认值,并且不会像必传参数那样报错

def default_value(name, age=18):
    print("我的名字是:", name)
    print("我今年:", age, "岁")

default_value("零一")
# 我的名字是: 零一
# 我今年: 18 岁

注意: 默认参数必须定义在最后,而且在默认参数之后定义必须参数会报错

def default_value(age=10, name):
    print("我的名字是:", name)
    print("我今年:", age, "岁")
# SyntaxError: non-default argument follows default argument

默认参数用法:

def student_score(name, score=60, location="Shanghai"):
    print("姓名:", name)
    print("成绩:", score)
    print("地区:", location)

print("---------- 传入所有参数 ----------")
student_score("张三", 100, "Beijing")
print("---------- 不传最后一个参数 ----------")
student_score("小明", 80)
print("---------- 不传中间参数 ----------")
student_score("小红", location="广州")
print("---------- 只传必须参数 ----------")
student_score("胖虎")
print("---------- 只传关键字参数 ----------")
student_score(name="元太")

# ---------- 传入所有参数 ----------
# 姓名: 张三
# 成绩: 100
# 地区: Beijing
# ---------- 不传最后一个参数 ----------
# 姓名: 小明
# 成绩: 80
# 地区: Shanghai
# ---------- 不传中间参数 ----------
# 姓名: 小红
# 成绩: 60
# 地区: 广州
# ---------- 只传必须参数 ----------
# 姓名: 胖虎
# 成绩: 60
# 地区: Shanghai
# ---------- 只传关键字参数 ----------
# 姓名: 元太
# 成绩: 60
# 地区: Shanghai

2.4 可变参数

在某些情况下,不能再定义时就确定参数的数量和内容,这时就可以使用可变参数

2.4.1 语法

可变参数语法如下:

some_func(*args, **kwargs)

  • some_func 为函数名
  • *args 和 **kwargs 为可变参数

2.4.2 *args可变参数

def foo(*args):
    print(args)

foo()
foo(1, 2)
foo("Python", "function", "parameters")

# ()
# (1, 2)
# ('Python', 'function', 'parameters')

2.4.3 **kwargs可变参数

def foo(**kwargs):
    print(kwargs)

foo()
foo(name="python study")

# {}
# {'name': 'python study'}

2.4.4 混合参数

从上面例子可以看出: *args 参数获取到的是一个元组**kwargs 参数获取到的是一个字典。在日常使用中,*args 和 **kwargs 经常出现,用于解决一些未知问题

def calculate_sum(*args, **kwargs):
    s = 0
    for i in args:
        s += i
    print("输入的数字之和是:", s)
    for k, v in kwargs.items():
        print(k, v)

calculate_sum(1, 2, 3, 4, 5, name="python")

# 输入的数字之和是: 15
# name python

2.4.5 可变参数传递未知参数

使用可变参数的方式来传递未知参数

def exp(*args, **kwargs):
    print(args)
    print(kwargs)

l = (1, 2, 3, 4)
d = {"参数1": "arg1", "参数2": "arg2"}
exp(l, d)
exp(*l, **d)

# ((1, 2, 3, 4), {'参数1': 'arg1', '参数2': 'arg2'})
# {}
# (1, 2, 3, 4)
# {'参数1': 'arg1', '参数2': 'arg2'}

3. 变量作用域

Python 中有两种最基本的变量作用域:局部变量和全局变量

3.1 局部变量

一般情况下,在函数内赋值的变量,不做特殊声明的变量都是局部变量

def foo():
    x = "hello"
    print(x)

foo() # hello

3.2 全局变量

在函数外赋值的变量就是全局变量,全局变量可以在整个程序范围内被访问

3.2.1 全局变量使用

x = "hello"

def foo():
    print(x)

foo() # hello
print(x) # hello

3.2.2 重写全局变量

函数体内重写赋值的同名变量,不会改变函数体外的全局变量

x = "函数体外"

def foo():
    x = "函数体内"
    print(x)

foo() # 函数体内
print(x) # 函数体外

3.2.3 修改全局变量

使用 global 关键字在函数体内对函数体外的全局变量进行修改

x = "函数体外"

def foo():
    global x
    x = "函数体内"
    print(x)

foo() # 函数体内
print(x) # 函数体内

4. 函数返回值

如果想要获取函数中的局部变量,可以使用 “return” 关键字进行返回

4.1 有返回值

def foo():
    x = "局部变量"
    return x

result = foo()
print(result) # 局部变量

4.2 无返回值

def no_return():
    print("没有return")

def no_return_value():
    print("有return没有返回值")
    return

def has_return():
    x = "局部变量"
    print("有return有返回值")
    return x

result1 = no_return()
print(result1) 
# 没有return
# None

result2 = no_return_value()
print(result2) 
# 有return没有返回值
# None

result3 = has_return()
print(result3)
# 有return有返回值
# 局部变量

4.3 多个返回值

def multi_value():
    r1 = "第一个返回值"
    r2 = "第二个返回值"
    r3 = "第三个返回值"
    r4 = "第四个返回值"
    r5 = "第五个返回值"
    return r1, r2, r3, r4, r5

s = multi_value()
print(s) # ('第一个返回值', '第二个返回值', '第三个返回值', '第四个返回值', '第五个返回值')

从执行结果来看,有多个返回结果时,Python 会返回一个元组;当Python返回了元祖时,就可以赋值给多个变量了

4.4 获取多个返回值

    return "第一个返回值", "第二个返回值"

r1, r2 = two_value()
print(r1) # 第一个返回值
print(r2) # 第二个返回值

5. Lambda表达式

Lambda 表达式也称作匿名函数。

5.1 Lambda 定义

以 “lambda” 开头,就表示是 lambda 表达式。它由 “:” 分为两部分,左边的是函数的参数,右边的是要返回的值。

lambda 表达式不需要用 return 关键字返回内容,函数默认会返回 “:” 右边的值

def add(x, y):
    return x+y

lambda x,y: x+y

5.2 Lambda 使用场景

lambda 表达式一般有两种使用情况:

  1. 程序只执行一次,不需要定义函数,使用 lambda 表达式方便定义,且节省了内存中变量的定义
  2. 在某些函数中必须以函数作为参数,但是函数本身十分简单且在一处使用
f = lambda x, y: x+y

z = f(1,2)
print(f) # <function <lambda> at 0x000001D1DC518B80>
print(z) # 3

5.3 filter过滤

filter 是 Python的内置函数,用于过滤序列,过滤掉不符合条件的元素。

filter 函数的第一个参赛需要传入另一个函数,传入的函数用来作为筛选条件,满足条件的返回 “True”,否则返回 “False”。

l1 = [1,2,3,4,5,6,7,8]
l2 = [item for item in filter(lambda x: x>5, l1)]
print(l2) # [6, 7, 8]

6. 扩展知识

6.1 文档字符串

使用 def 定义的函数,第一行可以是字符串,这个字符串就是文档字符串

def add(x, y):
    """
    返回参数x和y的两数之和
    :param x: int 第一个参数
    :param y: int 第二个参数
    :return: 返回 x+y
    """
    return x + y


print(add(1, 2)) # 3

# 可以使用 __doc__ 方式获取文档字符串
print(add.__doc__)
#   返回参数x和y的两数之和
#   :param x: int 第一个参数
#   :param y: int 第二个参数
#   :return: 返回 x+y

6.2 内置函数

Python 解释器内置了很多不同功能和类型的函数,可以直接使用

截取自菜鸟教程:Python 内置函数open in new window

abs()open in new windowdivmod()open in new windowinput()open in new windowopen()open in new windowstaticmethod()open in new window
all()open in new windowenumerate()open in new windowint()open in new windoword()open in new windowstr()open in new window
any()open in new windoweval()open in new windowisinstance()open in new windowpow()open in new windowsum()open in new window
basestring()open in new windowexecfile()open in new windowissubclass()open in new windowprint()open in new windowsuper()open in new window
bin()open in new windowfile()open in new windowiter()open in new windowproperty()open in new windowtuple()open in new window
bool()open in new windowfilter()open in new windowlen()open in new windowrange()open in new windowtype()open in new window
bytearray()open in new windowfloat()open in new windowlist()open in new windowraw_input()open in new windowunichr()open in new window
callable()open in new windowformat()open in new windowlocals()open in new windowreduce()open in new windowunicode()
chr()open in new windowfrozenset()open in new windowlong()open in new windowreload()open in new windowvars()open in new window
classmethod()open in new windowgetattr()open in new windowmap()open in new windowrepr()open in new windowxrange()open in new window
cmp()open in new windowglobals()open in new windowmax()open in new windowreverse()open in new windowzip()open in new window
compile()open in new windowhasattr()open in new windowmemoryview()open in new windowround()open in new windowimport()open in new window
complex()open in new windowhash()open in new windowmin()open in new windowset()open in new window
delattr()open in new windowhelp()open in new windownext()open in new windowsetattr()open in new window
dict()open in new windowhex()open in new windowobject()slice()open in new window
dir()open in new windowid()open in new windowoct()open in new windowsorted()open in new windowexec 内置表达式open in new window

6.3 函数注释

函数注释是一个可选功能,它允许在函数参数和返回值中添加任意的元数据

函数注释定义如下:

def function_name(a:expression, b:expression) -> expression:
function body
return value

def compile(source: "something compilable",
            filename: "where the compilable thing comes from",
            mode: "is this a single statement or a suite?") -> bool:
    return True

print(compile.__annotations__)
# {'source': 'something compilable', 'filename': 'where the compilable thing comes from', 'mode': 'is this a single statement or a suite?', 'return': <class 'bool'>}
上次编辑于:
贡献者: soulballad