python如何定义和调用函数_python函数定义与调用基础教程

冰火之心
发布: 2025-09-14 22:29:01
原创
436人浏览过
Python中定义函数使用def关键字,调用函数则执行其代码块。函数由定义(蓝图)和调用(执行)两部分组成,通过参数接收输入,可返回处理结果。形参是定义时的占位符,实参是调用时传入的具体值,支持位置传递和关键字传递。可设置默认参数提升灵活性,但需避免可变对象作为默认值导致的共享陷阱。函数可通过return语句返回单个或多个值(元组),并立即终止执行;无return时隐式返回None。良好实践包括:编写文档字符串说明功能、遵循单一职责原则拆分复杂函数、使用有意义的命名、添加类型提示增强可读性。掌握这些核心概念与规范能显著提升代码质量与可维护性。

python如何定义和调用函数_python函数定义与调用基础教程

在Python中,定义函数就像是为一段可重复使用的代码块命名,而调用函数则是执行这段代码。这不仅仅是为了代码的整洁,更是为了提升复用性和模块化,让我们的程序逻辑更清晰,也更容易维护。从我的经验来看,一旦你掌握了函数的使用,就等于拿到了构建复杂程序的基石,它让代码从一堆指令变成有组织、有意义的模块。

解决方案 理解Python中的函数,可以从两个核心动作开始:定义它,然后调用它。

定义函数

在Python里,我们使用

def
登录后复制
关键字来定义一个函数。这就像是告诉Python解释器:“嘿,我要在这里创建一个名为XXX的代码块,它能完成特定的任务。”

一个基本的函数定义结构是这样的:

立即学习Python免费学习笔记(深入)”;

def 函数名(参数1, 参数2, ...):
    """
    这里是函数的文档字符串(docstring),
    用来解释函数的功能、参数和返回值。
    这是一个非常好的习惯,能让你的代码更易懂。
    """
    # 函数体:这里是函数要执行的代码块
    # 注意,函数体必须缩进
    结果 = 参数1 + 参数2
    return 结果 # 使用return语句返回一个值,也可以不返回
登录后复制

我们来拆解一下:

  • def
    登录后复制
    : 这是定义函数的关键词,不可或缺。
  • 函数名
    登录后复制
    : 你给函数起的名字,应该能清晰地表达函数的功能。比如,一个计算和的函数,可以叫
    calculate_sum
    登录后复制
  • ()
    登录后复制
    : 括号里可以包含零个或多个参数(parameters)。参数是函数在执行时需要接收的输入。如果没有参数,括号也必须保留。
  • :
    登录后复制
    : 冒号标志着函数定义的结束,以及函数体(即要执行的代码)的开始。
  • """docstring"""
    登录后复制
    : 这是可选的,但强烈推荐。它用于描述函数的功能,其他开发者(包括未来的你)可以快速理解函数的作用。
  • 函数体: 缩进的代码块,包含了函数执行的所有指令。Python通过缩进来识别代码块,这是它的一大特色。
  • return
    登录后复制
    : 这是可选的。如果函数需要将某个结果传递回调用它的地方,就使用
    return
    登录后复制
    语句。一个函数可以返回任何类型的值,甚至多个值(作为元组)。如果没有
    return
    登录后复制
    语句,函数会隐式返回
    None
    登录后复制

调用函数

定义好函数之后,它并不会自动执行。你需要“调用”它,才能让它动起来。调用函数非常直接,只需写出函数名,后面跟上括号,并在括号内提供必要的参数(如果函数定义时有参数的话)。

# 定义一个简单的函数
def greet(name):
    return f"你好,{name}!欢迎来到Python世界。"

# 调用函数并打印结果
message = greet("小明")
print(message) # 输出:你好,小明!欢迎来到Python世界。

# 调用一个没有参数的函数
def show_message():
    print("这是一个没有参数的函数。")

show_message() # 输出:这是一个没有参数的函数。

# 调用一个返回多个值的函数
def get_user_info():
    return "Alice", 30, "工程师"

name, age, job = get_user_info()
print(f"{name},{age}岁,职业是{job}。") # 输出:Alice,30岁,职业是工程师。
登录后复制

从我的经验看,初学者很容易混淆定义和调用的时机。记住,定义是蓝图,调用才是实际的建造过程。

理解Python函数中的参数:形参、实参与默认值

在Python函数的定义与调用中,参数机制是其灵活性和强大功能的核心。我们常常会听到“形参”和“实参”,以及“默认参数”这些概念,它们在实际编码中扮演着不同的角色。

形参(Parameters)

形参,顾名思称,是形式上的参数。它们是在函数定义时,函数名后面括号里声明的变量。这些变量是函数内部使用的占位符,它们告诉函数,在被调用时需要接收哪些类型的数据。

def add_numbers(x, y): # x和y就是形参
    return x + y
登录后复制

这里的

x
登录后复制
y
登录后复制
就是形参。它们在函数定义时存在,但在函数被调用之前,它们并没有具体的值。

实参(Arguments)

实参,则是实际的参数。它们是在函数调用时,传递给函数的具体值。这些值会“填充”到函数定义时的形参中,供函数内部使用。

result = add_numbers(5, 3) # 5和3就是实参
print(result) # 输出:8
登录后复制

在这里,

5
登录后复制
3
登录后复制
就是实参,它们分别被赋给了函数
add_numbers
登录后复制
的形参
x
登录后复制
y
登录后复制

参数传递方式:位置参数与关键字参数

  • 位置参数 (Positional Arguments): 这是最常见的传递方式。实参的顺序必须与形参的顺序严格匹配。例如,

    add_numbers(5, 3)
    登录后复制
    中,
    5
    登录后复制
    对应
    x
    登录后复制
    3
    登录后复制
    对应
    y
    登录后复制

  • 关键字参数 (Keyword Arguments): 你可以通过显式指定参数名来传递实参。这种方式的好处是,你可以不按顺序传递,并且代码可读性更高。

    def create_user(name, age, city):
        return f"用户:{name}, 年龄:{age}, 城市:{city}"
    
    # 使用位置参数
    print(create_user("张三", 25, "北京"))
    # 使用关键字参数,顺序可以打乱
    print(create_user(city="上海", name="李四", age=30))
    登录后复制

默认参数值 (Default Parameter Values)

有时候,函数的一些参数在大多数情况下都有一个常用的值。这时,我们可以为这些形参设置默认值。这样,在调用函数时,如果不想改变这个常用值,就可以省略这个参数;如果想改变,就显式传递一个新的值。

硅基智能
硅基智能

基于Web3.0的元宇宙,去中心化的互联网,高质量、沉浸式元宇宙直播平台,用数字化重新定义直播

硅基智能 62
查看详情 硅基智能
def greet_person(name, greeting="你好"): # greeting有一个默认值
    return f"{greeting},{name}!"

print(greet_person("王五"))          # 输出:你好,王五!
print(greet_person("赵六", "早上好")) # 输出:早上好,赵六!
登录后复制

默认参数的一个小陷阱是,如果默认值是可变对象(如列表、字典),那么所有对该默认值的修改都会在函数调用之间共享,这可能会导致意想不到的行为。一个常见的实践是使用

None
登录后复制
作为默认值,然后在函数内部检查并初始化。

def append_item(item, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(item)
    return my_list

list1 = append_item(1)
print(list1) # [1]
list2 = append_item(2)
print(list2) # [2]
登录后复制

通过这些参数机制,Python函数变得异常灵活,能够应对各种复杂的输入场景。对我来说,掌握这些是写出健壮、可读性强代码的关键一步。

Python函数的返回值:何时以及如何有效利用它?

函数的返回值是其与外部世界交互的重要方式之一。一个函数执行完毕后,它可能需要把处理结果、计算结果或者状态信息传递给调用它的那部分代码。这就是

return
登录后复制
语句的职责。

return
登录后复制
语句的作用

  1. 返回一个值或多个值: 函数可以使用

    return
    登录后复制
    语句将一个或多个值传回给调用者。如果返回多个值,Python会把它们打包成一个元组(tuple)。

    def calculate_area(length, width):
        area = length * width
        return area # 返回计算出的面积
    
    def get_coordinates():
        x = 10
        y = 20
        return x, y # 返回x和y两个值,作为元组
    
    area_result = calculate_area(5, 4)
    print(f"面积是: {area_result}") # 输出:面积是: 20
    
    coord_x, coord_y = get_coordinates()
    print(f"坐标是: ({coord_x}, {coord_y})") # 输出:坐标是: (10, 20)
    登录后复制
  2. 终止函数执行: 当

    return
    登录后复制
    语句被执行时,函数会立即停止执行,并将控制权交还给调用者。
    return
    登录后复制
    语句后面的任何代码都不会被执行。

    def find_first_even(numbers):
        for num in numbers:
            if num % 2 == 0:
                return num # 找到第一个偶数就立即返回
        return None # 如果没有找到偶数,返回None
    
    print(find_first_even([1, 3, 5, 2, 4])) # 输出:2
    print(find_first_even([1, 3, 5]))      # 输出:None
    登录后复制
  3. 隐式返回

    None
    登录后复制
    : 如果函数体中没有
    return
    登录后复制
    语句,或者
    return
    登录后复制
    语句后面没有跟任何值,那么函数会隐式地返回
    None
    登录后复制

    def print_greeting(name):
        print(f"你好,{name}!")
    
    result = print_greeting("小李")
    print(f"函数返回的值是: {result}") # 输出:函数返回的值是: None
    登录后复制

    在我看来,理解

    None
    登录后复制
    的隐式返回非常重要,它避免了当你忘记
    return
    登录后复制
    时程序报错,但同时也是一个容易被忽视的细节。

何时有效利用返回值

  • 计算结果: 当函数的主要目的是执行某种计算并产生一个结果时,
    return
    登录后复制
    是必须的。比如数学运算、数据转换等。
  • 状态查询: 函数可以返回一个布尔值来表示某种条件是否满足,或者返回一个状态码来指示操作的结果。
  • 数据生成: 函数可以生成新的数据结构,如列表、字典、对象等,并通过
    return
    登录后复制
    将它们传递出去。
  • 函数组合: 返回值使得函数可以被链式调用,或者一个函数的输出作为另一个函数的输入,这是构建复杂逻辑的基础。

避免过度依赖副作用

一个好的实践是,尽量让函数通过返回值与外部交互,而不是过度依赖“副作用”(Side Effects),比如直接修改全局变量,或者直接打印输出而不是返回结果。当然,有些函数就是为了产生副作用而存在的(例如打印日志的函数),但要明确区分。一个“纯粹”的函数,只依赖其输入参数,并只通过返回值影响外部,这样的函数更容易测试、理解和维护。我个人在设计函数时,会优先考虑它是否能通过返回值清晰地表达其产出,这通常能带来更健壮的代码。

Python函数定义与调用:常见误区与提升代码质量的实践

函数是Python编程的基石,但即便如此,在使用过程中也常会遇到一些“坑”或者可以改进的地方。从我的经验来看,以下几个方面是值得注意的。

常见误区

  1. 可变默认参数的陷阱 这是Python函数中最经典的一个陷阱。当函数的默认参数是一个可变对象(如列表、字典)时,这个默认值只会在函数定义时被创建一次。这意味着,每次调用函数且不提供该参数时,都会使用同一个默认对象,对其的修改会累积。

    def add_to_list(item, my_list=[]): # 这里的[]只创建一次
        my_list.append(item)
        return my_list
    
    list1 = add_to_list(1)
    print(list1) # 输出: [1]
    list2 = add_to_list(2)
    print(list2) # 预期是 [2],实际输出: [1, 2] - 噢,这就是问题!
    
    # 正确的做法是这样:
    def add_to_list_fixed(item, my_list=None):
        if my_list is None:
            my_list = [] # 每次调用时都创建一个新的列表
        my_list.append(item)
        return my_list
    
    list3 = add_to_list_fixed(1)
    print(list3) # 输出: [1]
    list4 = add_to_list_fixed(2)
    print(list4) # 输出: [2]
    登录后复制

    这个细节常常让新手感到困惑,甚至一些有经验的开发者也会偶尔犯错。理解其背后的原理(默认参数在函数定义时求值一次)是关键。

  2. 忽略文档字符串(Docstrings) 很多开发者在编写函数时,往往跳过编写文档字符串。然而,良好的文档字符串是提高代码可读性和可维护性的最简单、最有效的方法之一。

    def calculate_average(numbers):
        # 缺少文档字符串,其他人(或未来的你)很难快速理解这个函数是做什么的
        return sum(numbers) / len(numbers)
    
    # 更好的做法:
    def calculate_average_documented(numbers):
        """
        计算给定数字列表的平均值。
    
        参数:
            numbers (list): 包含数字的列表。
    
        返回:
            float: 列表中所有数字的平均值。如果列表为空,则返回0。
        """
        if not numbers:
            return 0
        return sum(numbers) / len(numbers)
    登录后复制

    通过

    help(calculate_average_documented)
    登录后复制
    或IDE的提示,文档字符串能提供即时帮助。

  3. 函数过于庞大或职责不清 一个函数承担了过多的任务,或者其功能边界模糊,这会导致函数难以理解、测试和重用。

提升代码质量的实践

  1. 遵循单一职责原则(SRP) 一个函数应该只做一件事,并且把它做好。如果你的函数名中出现了“and”、“or”这样的连接词,或者你需要用很长的句子来描述它的功能,那可能就是它承担了太多职责的信号。

    # 不好的例子:一个函数既处理数据又保存到文件
    def process_and_save_data(data):
        processed_data = data.upper()
        with open("output.txt", "w") as f:
            f.write(processed_data)
        return processed_data
    
    # 更好的做法:拆分成两个函数
    def process_data(data):
        return data.upper()
    
    def save_data_to_file(data, filename):
        with open(filename, "w") as f:
            f.write(data)
    
    my_data = "hello world"
    processed = process_data(my_data)
    save_data_to_file(processed, "output.txt")
    登录后复制

    拆分函数不仅让每个函数更专注,也提高了它们的复用性。

  2. 使用有意义的函数名和参数名 函数名应该清晰地表达其功能,参数名应该清晰地表达其含义。避免使用

    a
    登录后复制
    ,
    b
    登录后复制
    ,
    x
    登录后复制
    ,
    y
    登录后复制
    等无意义的名称,除非在非常简单的数学运算中。

    # 不好的例子
    def f(a, b):
        return a * b + 10
    
    # 更好的例子
    def calculate_adjusted_product(factor1, factor2):
        return factor1 * factor2 + 10
    登录后复制

    这听起来简单,但在实际项目中,清晰的命名能极大提升代码的可读性。

  3. 利用类型提示(Type Hints) Python是动态类型语言,但从Python 3.5开始引入了类型提示。虽然类型提示不会强制类型检查(除非你使用

    mypy
    登录后复制
    这样的工具),但它们极大地提高了代码的可读性,并有助于IDE提供更好的自动补全和错误检查。

    def greet_user(name: str) -> str:
        """
        根据提供的名字生成问候语。
        """
        return f"Hello, {name}!"
    
    def add(a: int, b: int) -> int:
        return a + b
    登录后复制

    对我来说,类型提示就像是为我的函数写了一份迷你契约,清晰地表明了它期望什么输入和会产生什么输出,这在团队协作和大型项目中尤其宝贵。

通过避免这些常见误区并采纳这些实践,你不仅能写出能运行的代码,更能写出易于理解、维护和扩展的高质量Python代码。这不仅仅是技术细节,更是一种编程思维的体现。

以上就是python如何定义和调用函数_python函数定义与调用基础教程的详细内容,更多请关注php中文网其它相关文章!

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号