当前位置: 首页 > news >正文

Python 函数全攻略:函数基础

函数(Functions)基础

  1. 什么是函数?

    • 一个命名的代码块,代指一大堆代码。

    • 定义: def function_name(): (使用def关键字,英文括号,冒号,缩进代码块)。

    • 执行/调用: function_name() (写函数名加括号)。

    • 特性: 定义时不执行,调用时才执行。可重复调用。

  2. 为什么学习函数?(优势与应用场景)

    • 增强代码重用性: 将重复或公共的代码块提取成函数,需要时调用即可,避免复制粘贴。

    • 提高代码可读性: 将复杂逻辑拆分成多个小函数,每个函数负责一个清晰的功能,使主逻辑更简洁易懂。就像将大任务分解为小任务并命名。

  3. 函数参数(Function Parameters)

    • 基本使用:

      • 定义参数: 在函数名后的括号中定义变量名(形参)。

      • 传递参数: 调用函数时传入值(实参)。

      • 位置传参: 按参数在函数定义中的顺序传值。

        • 示例:def func(x1, x2): ... 调用 func(1, 2)

      • 关键字传参: 调用时指定参数名赋值。顺序不重要。

        • 示例:func(x2=2, x1=1)

      • 混合传参: 位置参数必须在前,关键字参数在后。

        • 示例:func(1, x2=2) (正确),func(x1=1, 2) (错误)。

      • 类型: 任意类型(int, str, list, dict等)都可以作为参数传递。

    • 参数默认值:

      • 定义: def func(x1, x2=default_value): ...

      • 行为: 调用时如果不传该参数,则使用默认值;如果传入,则覆盖默认值。

      • 注意: 带默认值的参数必须放在不带默认值的参数之后。

    • 动态参数(*args**kwargs):

      • *args (星号参数/可变位置参数):

        • 定义: def func(*args): ...

        • 接收: 接收任意数量的位置参数。这些参数会被打包成一个元组(tuple)

        • 示例:func(1, 2, 'hello')args将是(1, 2, 'hello')

        • 不传参数时,args为空元组()

        • 易错点: 传入的列表/元组本身会作为一个整体元素放入args元组中,而不是被解包。

      • **kwargs (双星号参数/可变关键字参数):

        • 定义: def func(**kwargs): ...

        • 接收: 接收任意数量的关键字参数。这些参数会被打包成一个字典(dict)

        • 示例:func(name='Alice', age=30)kwargs将是{'name': 'Alice', 'age': 30}

        • 不传参数时,kwargs为空字典{}

      • 混合使用(*args**kwargs):

        • 定义顺序: 必须是 def func(normal_param, *args, **kwargs): ...

        • 传参顺序: func(位置参数, *args打包的参数, **kwargs打包的参数)

        • 惯例: 动态参数名通常写为 *args**kwargs

        • 应用: 常见于内置函数(如print())和框架/库中,用于灵活接收用户传入的任意参数。

实践案例:Python发送邮件

  • 实现思路: 借助于第三方邮箱服务器(如网易126邮箱)的SMTP服务。

    1. 注册邮箱并开启SMTP服务: 登录邮箱设置,找到POP3/SMTP服务,开启并获取授权码(替代邮箱密码用于代码登录)。记录SMTP服务器地址(如smtp.126.com)。

    2. 导入模块: import smtplibfrom email.mime.text import MIMEText

    3. 构建邮件内容: 使用MIMEText创建邮件对象,指定主题、发件人、收件人、正文。

    4. 发送邮件:

      • 创建SMTP连接:smtp_obj = smtplib.SMTP_SSL('smtp.126.com', 465) (SMTP_SSL使用SSL加密,端口通常为465)。

      • 登录邮箱:smtp_obj.login(sender_email, authorization_code)

      • 发送:smtp_obj.sendmail(sender_email, [receiver_email], msg.as_string())

      • 退出:smtp_obj.quit()

  • 结合函数: 可将发送邮件逻辑封装成函数,通过参数动态传入收件人、主题、内容,实现更灵活的邮件发送功能。


函数的返回值(Return Values)

  • 作用: 执行完函数后,将结果返回给调用者。

  • 语法: return 值

  • return vs. print

    • print:仅输出到控制台。

    • return:将值返回给调用者,可被变量接收。

  • 特性:

    1. 任意类型: 返回值可以是任意Python类型。

    2. 默认 None 函数若无 return 语句,默认返回 None

    3. 终止函数: 函数内部一旦遇到 return,立即终止执行后续代码。

  • 多值返回: return val1, val2, val3 实际返回一个元组。调用时可利用解包 a, b, c = func()

函数内调用函数 (嵌套调用)

  • 函数内部可以调用其他函数。

  • 调用发生时,会先执行被调用的函数,待其执行完毕(及处理返回值)后,再回到原函数继续执行。

函数参数传递:引用 vs. 值

  • 结论: Python函数参数传递的是引用,不会重新拷贝数据。

  • 证明:

    • 可变类型 (如列表): 函数内部对参数的修改(如 append, remove)会直接影响到外部传入的原始数据,因为它们指向同一内存地址。

    • 不可变类型 (如字符串、数字、元组): 虽然传递的是引用,但由于不可变类型本身无法被原地修改,任何"修改"操作(如 str.upper())都会生成新对象,原引用保持不变。

作用域(Scope)

  • 定义: 一块共享的区域,区域内数据可被访问。

  • Python中的作用域:

    1. 全局作用域: 最外层代码块,全局变量可在任何地方被访问。

    2. 函数作用域: 每个函数都是一个独立的作用域(局部作用域)。

  • 查找规则: 在函数内部查找变量时,优先在自身局部作用域查找;若无,则向上一级(父级,通常是全局作用域)查找。

  • 局部变量 vs. 全局变量:

    • 局部变量: 函数内部定义的变量,仅在该函数内有效。

    • 全局变量: 在任何函数之外定义的变量。

    • 规范: 全局变量通常使用大写命名,局部变量使用小写。

  • global 关键字:

    • 作用:在函数内部声明变量为全局变量。

    • 效果:使用 global var_name 后,函数内部对 var_name 的任何操作都将直接作用于全局作用域中的同名变量,而不是在局部作用域内创建新变量。

    • 示例:global name; name = 'new_val' 会修改全局 name

函数名本质是一个变量

  • 概念: 函数名像其他变量一样,可以被赋值、作为参数传递、存储在数据结构(列表、字典)中。

  • func vs. func()

    • func:代表函数本身(函数对象),不执行。

    • func():表示调用并执行函数,获取其返回值。

  • 应用场景:

    1. 批量执行: 将多个函数名存储在列表/元组中,通过循环统一调用执行,避免重复代码。

    2. 调度中心 (命令模式): 使用字典将功能编号/名称映射到对应的函数名。根据用户选择获取并执行相应函数,简化 if/elif/else 结构。

拉姆达式(Lambda Expressions)/ 匿名函数

  • 定义: 一种用于创建小型、单行匿名函数的简洁方式。

  • 语法: lambda 参数: 表达式

    • lambda:关键字。

    • 参数:函数参数,可省略或多个。

    • 表达式:函数体,执行后隐含 return

  • 特点:

    • 匿名: 没有名称。

    • 单行: 只能包含一个表达式,结果被隐式返回。

    • 简洁: 适用于逻辑简单的函数。

  • 应用: 常用于作为参数传递给其他高阶函数(如 map, filter, sortedkey 参数),如filter(lambda x:x>5, [1,6,3]),或作为数据结构中的元素。


http://www.xdnf.cn/news/922591.html

相关文章:

  • JavaSec-SpringBoot框架
  • JAVA理论第三章-多线程
  • Python实例题:Python计算微积分
  • 2025年06月07日Github流行趋势
  • go语言学习 第9章:映射(Map)
  • 推客系统小程序开发:告别低效推广,开启精准获客新时代
  • C++课设:实现简易文件加密工具(凯撒密码、异或加密、Base64编码)
  • 25N60-ASEMI电源管理领域专用25N60
  • 基于ROS2,撰写python脚本,根据给定的舵-桨动力学模型实现动力学更新
  • 【CSS-4】掌握CSS文字样式:从基础到高级技巧
  • Qt/C++学习系列之Excel使用记录
  • 第二部分 方法,还是方法——“信管法则”的四大要点
  • 高保真组件库:数字输入框
  • FlashAttention 公式推导
  • [AI绘画]sd学习记录(二)文生图参数进阶
  • Rapidio门铃消息FIFO溢出机制
  • TongWeb7.0动态密钥说明
  • 实战:子组件获取父组件订单信息
  • 【学习笔记】如何给软件加数字签名
  • 在 Windows 11 或 10 上将 Git 升级到最新版本的方法
  • 【Linux】LInux下第一个程序:进度条
  • 十一、【ESP32开发全栈指南: TCP通信服务端】
  • 1-3 Linux-虚拟机(2025.6.7学习篇- mac版本)
  • Sentry 接口返回 Status Code 429 Too Many Requests
  • 【优选算法】C++滑动窗口
  • 在ubuntu等linux系统上申请https证书
  • Redis内存淘汰策略
  • redis集群
  • [最全总结]城市灾害应急管理系统
  • Linux虚拟化技术:从KVM到容器的轻量化革命