Python学习之函数

一、定义函数

函数的一般语法如下:

def function_name(parameters):
    """函数文档字符串"""   #1. 可选,一种记录函数行为的方式。
    
    #2. 函数体,包含一系列操作 

    return expression    #3. 可选,用于返回值

下图是函数的各部分介绍:

其中:

  • def 关键字用于定义函数。
  • function_name 是函数的名称,按照命名规范,应该是小写字母,单词间可以用下划线 _ 分隔。
  • parameters 是函数的参数列表,可以是零个或多个,多个参数之间用逗号 , 分隔。
  • 函数体是缩进的代码块,包含了函数的操作。
  • return 语句可选,用于返回函数的结果。

调用函数也非常简单,只需使用函数名称和相应的参数即可:

result = function_name(arguments)

这里的 arguments 是函数调用时传递给函数的实际值,这些值会被传递给函数的参数,但是在定义函数的时候,它只是形式参数,是为了方便我们写代码的逻辑的。在函数执行后,可以用 result 变量保存返回的结果。 

二、函数参数的不同类型

上面我们讲了函数的声明和定义,这里我们要详细讲一下Python 中有几种不同类型的函数参数,这涉及到函数参数的使用问题。

🐡 1. 位置参数(Positional Arguments)

这是最常见的参数类型,参数按照函数定义的顺序传递。

# 定义
def greet(name, greeting):
    print(f"{greeting},{name}!")

# 调用
greet("Python","Hello") # 输出:Hello, Python
🐡 2. 关键字参数(Keyword Arguments)

通过参数名指定参数值,可以不按照函数定义的顺序传递。

# 定义
def greet(name, greeting):
    print(f"{greeting},{name}!")

# 调用
greet(greeting='Hi', name='Python') # 输出:Hi, Python
🐡 3. 默认参数(Default Arguments)

定义函数时为参数指定默认值,在调用时可以不传递这些参数。

# 定义
def greet(name, greeting = 'Hello'):
    print(f"{greeting},{name}")

# 调用
greet('Python') # 输出:Hello Python!
🐡 4. 可变参数(Variable Arguments)

允许函数接受可变数量的参数,有两种类型:*args 和 **kwargs

🦋 *args用于接收任意数量的位置参数,它将这些参数作为元组(tuple)处理。

# 定义
def add(*args):
    total = 0
    for num in args:
        total += num
    return total

print(add(1,2,3,4)) # 输出 10

🦋 **kwargs 用于接收任意数量的关键字参数,它将这些参数作为字典(dictionary)处理。

# 定义
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}:{value}")

# 调用
print_info(name='Python', age = 30, city = "New York")

# 输出结果:
# name:Python
# age:30
# city:New York

函数的参数虽然可以任意组合使用,但需要遵循一定的顺序:位置参数、默认参数、可变位置参数 *args、可变关键字参数 **kwargs

三、处理函数的返回值

处理函数的返回值需要根据函数的具体情况和调用需求。下面是一些常用的方法:

# 1.存储到变量中:
# 将函数的返回值存储到一个变量中,以便后续使用。

result = my_function(argument) 


# 2.直接使用:
# 在需要的地方直接使用函数的返回值。

print(my_function(argument)) 


# 3.条件判断:
# 根据返回值的情况执行不同的操作。

if my_function(argument):    
     # 如果返回值为真,执行某些操作
     pass
else:
     pass
     # 如果返回值为假,执行其他操作 


# 4.传递给其他函数:
# 将函数的返回值作为参数传递给另一个函数。

another_function(my_function(argument))  


# 5.解构返回的元组或列表:
# 如果函数返回的是元组或列表,可以通过解构来获取各个元素。

a, b = return_tuple() 

四、匿名函数

🐡 1. Lambda函数的语法

匿名函数(Anonymous Functions)是指没有具体名称的函数,通常使用 lambda 关键字创建。使用匿名函数可以避免定义一个完整的函数,简化代码结构。

匿名函数的一般语法如下:

lambda arguments: expression
  • lambda 是关键字。
  • arguments 是函数的参数,类似于常规函数的参数。
  • expression 是函数的主体,也就是函数要执行的操作。
  • 是区分参数和函数主体的标志。

示例代码:

# 简单的函数加法
add = lambda x,y : x + y
print(add(3,5)) # 输出:8

# 作为函数的返回值
def make_incrementor(n):
    return lambda x: x + n
increment_by_5 = make_incrementor(5)
print(increment_by_5(10))  # 输出:15
🐡 2. Lambda函数的用法

🦋 作为参数传递给其他函数

Lambda函数常用于将简单的逻辑作为参数传递给高阶函数,如map()filter()等。

# 🌾:使用Lambda函数和map()函数将列表中的每个元素都平方
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x * x, numbers))
print(squared)  # 输出: [1, 4, 9, 16, 25]

# 🌾:使用Lambda函数和filter()函数筛选出列表中的偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # 输出: [2, 4]

🦋 在高阶函数中使用Lambda函数

# 🌾:使用Lambda函数定义一个自定义的排序规则
students = [
    {'name': 'Tiyong', 'grade': 90},
    {'name': 'Bob', 'grade': 85},
    {'name': 'Toy', 'grade': 95}
]

# 🌾:按照学生的成绩进行排序
sorted_students = sorted(students, key=lambda x: x['grade'], reverse=True)
print(sorted_students)

# 🌾 输出:[{'name': 'Toy', 'grade': 95}, {'name': 'Tiyong', 'grade': 90}, {'name': 'Bob', 'grade': 85}]

🦋 创建简单的匿名函数

Lambda函数可以用于需要一个简单函数来执行一些基本操作的情况。

# 🌾:求两个数的和
add = lambda a, b: a + b
result = add(10, 20)
print(result)  # 输出: 30

# 🌾:求一个数的平方
square = lambda x: x * x
result = square(5)
print(result)  # 输出: 25 
🐡 3. lambda的应用示例

🦋 map()函数

map()函数接受一个函数和一个可迭代对象作为参数,然后将该函数应用于可迭代对象的每个元素,返回一个结果列表。

# 使用Lambda函数和map()函数将列表中的每个元素都平方
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x * x, numbers))
print(squared)  # 输出: [1, 4, 9, 16, 25]

🦋 filter()函数

filter()函数用于过滤序列中的元素,接受一个函数和一个可迭代对象作为参数,然后根据函数的返回值是True还是False来决定是否保留元素。

# 使用Lambda函数和filter()函数筛选出列表中的偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # 输出: [2, 4]

🦋 在排序中的应用

在排序的应用中,可以把Lambda函数作为排序的关键字,根据特定的条件对序列进行排序。

# 使用Lambda函数对列表进行排序
names = ['Tiyong', 'Bob', 'Toy', 'Alice']
sorted_names = sorted(names, key=lambda x: len(x))
print(sorted_names)  # 输出: ['Bob', 'Toy', 'Alice', 'Tiyong']

五、函数装饰器(Function Decorators)

函数装饰器是Python中用于修改或扩展函数功能的语法糖。它允许开发者在不更改函数代码的前提下,动态地为函数添加新的行为或功能。在Python中,装饰器是通过使用@decorator语法来实现的。

简单展示一个装饰器的使用

# 🌾:定义一个函数,里面嵌套了一个函数
def a(func):
    def b():
        print("我是b()函数里,调用函数  前 的句子!")
        func()
        print("我是b()函数里,调用函数  后 的句子!")
    return b

# 🌾:定义第二个函数
def c():
    print("我是c函数!")


# 一般形式,我们将c函数作为参数传入a,再赋值给afunc
afunc = a(c)

'''
我们调用afunc()函数,
注意:当你把一对小括号放在后面,这个函数就会执行;
然而如果你不放括号在它后面,那它可以被到处传递,
并且可以赋值给别的变量而不去执行它。 
'''

# 这时,afunc()作为函数输出。
afunc()


###############【重点来啦】#################
#我们使用@
@a
def d():
    """我是一个函数装饰器"""
    print("我是一个函数装饰器")


# 这时候我们再调用d(),就直接输出:
d()

'''
输出如下:
我是b()函数里,调用函数  前 的句子!
我是一个函数装饰器
我是b()函数里,调用函数  后 的句子!
'''

# 特别解释: @a 就等价于  afunc = a(d) 

装饰器的优势:

  • 代码更简洁,易于维护
  • 提高代码复用性
  • 符合 Python 的“开闭原则”

装饰器的注意事项

  • 装饰器会改变函数的签名,因此在使用装饰器时,需要确保被装饰函数的签名与装饰器兼容。
  • 装饰器可能会影响函数的性能,因此在使用装饰器时,需要进行性能测试。

六、编写函数文档

上面有那么多函数,这时候每个函数的文档说明,就会成为理解这个函数的重要信息。那么如何编写清晰明了的文档字符串(docstrings)呢?

所谓的文档字符串(docstrings)是函数、类或模块的第一个逻辑行,用于描述该函数、类或模块的作用、参数、返回值等信息。良好的文档字符串可以让其他开发者快速了解你的代码,并且方便生成文档。

一般情况下,使用三重引号 """ 或 ''' 来编写文档字符串。下面是一个示例:

def my_function(parameter1, parameter2):
    # 就是把功能说明,通过""" 或者 ''' 写在了函数内部,给其它语言写在外边类似
    """
    这是一个示例函数的文档字符串。

    参数:
    - parameter1: 描述参数1的作用
    - parameter2: 描述参数2的作用

    返回值:
    - 返回值的说明

    示例用法:
    >>> my_function(1, 2)
    3
    """

    return parameter1 + parameter2

下面是一些编写清晰文档字符串的建议:

  • 概述:简要概述函数的作用和功能。
  • 参数说明:详细描述函数的参数,包括参数名、类型以及每个参数的作用。
  • 返回值说明:明确描述函数的返回值,包括返回值的类型以及它的具体含义。
  • 示例用法:提供函数的示例用法,展示输入参数和期望的输出结果。
  • 其他信息:根据需要添加其他相关信息,如函数的实现细节、注意事项等。

七、总结

在函数式编程中,函数被视为一等公民,可以作为参数传递给其他函数,也可以作为函数的返回值。但是,在编写函数时,避免不必要的函数调用也是提高性能的重要方面之一。下面是一些优化函数性能的技巧:

  • 函数内联,避免函数调用的开销;
  • 条件语句优化,将频繁执行的条件判断提前到函数外部;
  • 缓存结果,尤其适用于递归函数,避免重复计算;
  • 惰性计算,延迟计算直到需要的时候。

posted on 2024-12-04 10:46  梁飞宇  阅读(72)  评论(0)    收藏  举报