侧边栏壁纸
博主头像
soulballad博主等级

技术文章记录及总结

  • 累计撰写 169 篇文章
  • 累计创建 26 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

【Python】-4.Python中的函数

soulballad
2020-09-06 / 0 评论 / 0 点赞 / 46 阅读 / 6,897 字
温馨提示:
本文最后更新于 2022-03-03,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

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

例如,我们开发一个支持人与人之间对话的社交网站,“对话”这个功能实现起来比较复杂,我们可以将它封装为一个函数,每次调用函数就可以发起对话。大型网站都有日志功能,所有重要操作都会记录日志,而日志处理需要由多行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 内置函数

abs()divmod()input()open()staticmethod()
all()enumerate()int()ord()str()
any()eval()isinstance()pow()sum()
basestring()execfile()issubclass()print()super()
bin()file()iter()property()tuple()
bool()filter()len()range()type()
bytearray()float()list()raw_input()unichr()
callable()format()locals()reduce()unicode()
chr()frozenset()long()reload()vars()
classmethod()getattr()map()repr()xrange()
cmp()globals()max()reverse()zip()
compile()hasattr()memoryview()round()import()
complex()hash()min()set()
delattr()help()next()setattr()
dict()hex()object()slice()
dir()id()oct()sorted()exec 内置表达式

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'>}
0

评论区