一口气学完Python编程语言的基础内容

文章目录

第1章 Python简介

1.1 Python简介

  • Python是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。

  • Python的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。

  • Python是一种解释型语言: 意味着开发过程中没有编译这个环节。类似于PHP语言。

  • Python是交互式语言: 意味着可以在一个 Python 提示符 >>> 后直接执行代码。

  • Python是面向对象语言: 意味着Python支持面向对象的风格或代码封装在对象的编程技术。

  • Python是初学者的语言:Python对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到WWW浏览器再到游戏。

1.2 Python历史

  1. 创立与发展
  • 1989年:Guido van Rossum 在圣诞节期间开始设计 Python,目的是创造一种更易于阅读和编写的编程语言。
  • 1991年:发布了第一个公开版本 Python 0.9.0。
  • 1994年:发布了 Python 1.0 版本,引入了函数式编程的概念,如 lambda、map、filter 和 reduce。
  1. Python 2.x
  • 2000年:Python 2.0 发布,引入了垃圾回收机制,并支持 Unicode。
  • 2008年:Python 2.6 发布,增加了对多线程的支持,并改进了异常处理。
  1. Python 3.x
  • 2008年:Python 3.0 发布,这是 Python 的一次重大更新,引入了许多改进,包括更好的 Unicode 支持、简化语法和改进的库。
  • 2010年:Python 3.2 发布,带来了更好的安全性、性能改进和新特性。
  • 2014年:Python 3.4 发布,引入了 asyncio 模块,支持异步 I/O。
  • 2015年:Python 3.5 发布,进一步增强了 asyncio,并引入了新的类型提示功能。
  • 2018年:Python 3.7 发布,带来了新的数据类(data classes)、异步上下文管理器和其他改进。
  • 2019年:Python 3.8 发布,引入了新的赋值表达式(walrus operator :=)和其他新特性。
  • 2020年:Python 3.9 发布,改进了类型提示,增加了新的字符串替换方法,并增强了字典解包等功能。
  • 2021年:Python 3.10 发布,引入了模式匹配(Pattern Matching)和其他新特性。
  • 2022年:Python 3.11 发布,带来了性能提升、改进的错误处理和新的类型检查工具等。
  1. Python 2.x 的退役
  • 2020年1月1日:Python 2.7 正式停止支持,不再提供安全更新和改进。Python 社区鼓励用户迁移到 Python 3.x。
  1. 当前状态
  • 截至2024年,Python 3.x 是当前的活跃版本,Python 3.11 和 3.12 已经发布,带来了新的特性和改进。
  1. 未来展望
  • Python 社区持续推动语言的发展,计划中的版本将继续带来性能改进、新特性和对现代编程趋势的支持。
  1. 社区与生态系统
  • Python 拥有一个庞大的社区和丰富的第三方库生态系统,支持广泛的领域,从Web开发、科学计算到机器学习和人工智能。
  1. 重要人物
  • Guido van Rossum:Python 的创始人,被称为“Benevolent Dictator for Life”(终身仁慈独裁者),直到2018年卸任。

1.3 Python特点

  1. 简洁易读
  • 语法简单:Python 的语法设计旨在提高代码的可读性,使得代码更易于理解和维护。
  • 缩进:Python 使用缩进来表示代码块,而不是使用花括号 {},这使得代码更加整洁。
  1. 动态类型
  • 动态类型:Python 是一种动态类型语言,变量无需事先声明类型即可使用。
  • 动态绑定:变量的类型可以在运行时改变。
  1. 面向对象
  • 一切皆对象:在 Python 中,几乎所有的东西都是对象,包括数字、字符串、函数等。
  • 类和对象:Python 支持面向对象编程,允许定义类、创建对象、继承和多态。
  1. 可移植性
  • 跨平台:Python 可以在多种操作系统上运行,包括 Windows、macOS 和各种 Linux 发行版。
  1. 强大的标准库
  • 标准库:Python 拥有一个庞大且功能丰富的标准库,涵盖了网络、文件、GUI、数据库等多种领域。
  1. 易于集成
  • 与其他语言集成:Python 可以轻松地调用 C/C++ 代码,也可以被其他语言调用。
  • 脚本语言:Python 常被用作脚本语言来快速开发简单的工具或脚本。
  1. 解释型
  • 解释执行:Python 代码在运行时被逐行解释执行,不需要预先编译。
  • 动态执行:这使得调试和开发过程更加高效。
  1. 强大的社区支持
  • 开源:Python 是一个开源项目,拥有庞大的开发者社区和丰富的第三方库。
  • 文档齐全:Python 有详尽的官方文档和大量的第三方资源。
  1. 应用广泛
  • Web 开发:使用框架如 Django 和 Flask 开发 Web 应用。
  • 数据科学:利用 Pandas、NumPy 和 SciPy 等库进行数据分析。
  • 机器学习:使用 TensorFlow、PyTorch 和 Scikit-learn 等库进行机器学习和深度学习。
  • 自动化脚本:编写自动化脚本来简化日常任务。
  • 游戏开发:使用 Pygame 等库开发游戏。
  1. 强大的第三方库生态系统
  • 丰富的库:Python 拥有大量高质量的第三方库,几乎涵盖了所有可能的应用领域。
  1. 开发效率高
  • 快速原型:Python 的简洁性和强大的库支持使得开发原型非常快速。
  • 迭代开发:Python 支持敏捷开发和迭代开发方法。
  1. 可扩展性
  • C扩展:可以使用 C 语言编写扩展模块来提高性能。
  • 多线程和多进程:Python 支持多线程和多进程编程,尽管全局解释器锁 (GIL) 限制了多线程的并发性能。
  1. 自动内存管理
  • 垃圾回收:Python 自动管理内存,无需手动释放内存。

1.4 Python的应用场景

  1. Web 开发
  • Web 框架:Django 和 Flask 是两个非常流行的 Python Web 框架,用于构建 Web 应用程序和服务。
  • API 开发:可以使用 Flask 或 FastAPI 构建 RESTful API 和微服务。
  1. 数据科学与分析
  • 数据处理:Pandas 是一个强大的库,用于数据清洗、转换和分析。
  • 统计分析:SciPy 和 Statsmodels 提供了大量的统计工具。
  • 数据可视化:Matplotlib 和 Seaborn 可以用于创建图表和图形。
  1. 机器学习与人工智能
  • 机器学习库:Scikit-learn 是一个广泛使用的机器学习库。
  • 深度学习框架:TensorFlow 和 PyTorch 用于构建神经网络和深度学习模型。
  1. 自动化脚本
  • 系统管理:编写自动化脚本来执行重复性的任务,如文件备份、系统监控等。
  • 网络爬虫:使用 Beautiful Soup 和 Scrapy 等库来抓取网页数据。
  1. 游戏开发
  • 游戏引擎:Pygame 是一个用于开发 2D 游戏的库。
  • Unity 插件:可以使用 Python 编写 Unity 的插件和脚本。
  1. 科学计算
  • 数值计算:NumPy 提供高性能的数组运算。
  • 科学计算:SciPy 包含用于科学计算的各种工具,如线性代数、优化、信号处理等。
  1. 桌面应用
  • GUI 应用:Tkinter、PyQt 和 Kivy 可以用于开发跨平台的桌面应用程序。
  1. 网络编程
  • Socket 编程:Python 标准库中的 socket 模块用于网络通信。
  • 异步编程:使用 asyncio 和 aiohttp 进行异步 I/O 编程。
  1. 云计算与 DevOps
  • 云服务:许多云服务提供商(如 AWS、Azure 和 Google Cloud)支持使用 Python 编写脚本和工具。
  • 自动化部署:使用 Ansible、Fabric 和 SaltStack 等工具进行自动化部署和配置管理。
  1. 教育与教学
  • 编程入门:Python 的简单语法使其成为教授编程概念的理想选择。
  • 在线课程:许多在线教育平台使用 Python 来创建互动课程和练习。
  1. 金融与量化交易
  • 量化分析:使用 Pandas 和 NumPy 进行数据处理和分析。
  • 交易策略:开发算法交易策略和回测系统。
  1. 生物信息学
  • 基因组分析:处理生物序列数据,如 DNA 和 RNA。
  • 蛋白质结构预测:使用 BioPython 和其他库进行生物信息学研究。
  1. 图像处理与计算机视觉
  • 图像处理:使用 OpenCV 和 Pillow 进行图像处理。
  • 计算机视觉:使用 OpenCV 和 scikit-image 进行特征检测、识别等任务。
  1. 自然语言处理 (NLP)
  • 文本分析:NLTK 和 spaCy 用于分词、语法解析、情感分析等 NLP 任务。
  • 机器翻译:使用 TensorFlow 和 PyTorch 构建机器翻译系统。
  1. 嵌入式系统
  • 微控制器:使用 MicroPython 在微控制器上运行 Python 脚本。
  1. 物联网 (IoT)
  • 设备控制:使用 Python 控制物联网设备并通过网络发送数据。
  • 智能家居:开发智能家庭设备的控制软件。
  1. 游戏服务器
  • 多人游戏服务器:使用 Python 构建游戏服务器逻辑。
  1. 软件测试
  • 自动化测试:使用 unittest 和 pytest 开发自动化测试脚本。
  1. 机器人技术
  • 机器人控制:使用 ROS (Robot Operating System) 和 Python 控制机器人。
  1. 区块链技术
  • 智能合约:使用 Python 开发智能合约和区块链应用。

1.5 Python的版本

Python 有两个主要版本系列:Python 2.x 和 Python 3.x。每个系列都有多个版本发布。

Python 2.x

  • Python 2.0:2000年发布,引入了一些重要的新特性,如列表推导式、垃圾回收机制等。
  • Python 2.6:2008年发布,增加了对多线程的支持,并改进了异常处理。
  • Python 2.7:2010年发布,这是 Python 2.x 系列的最后一个主要版本,包含了许多改进和修复,并支持 Unicode。
  • Python 2.x 的退役:2020年1月1日,Python 2.7 正式停止支持,不再提供安全更新和改进。Python 社区鼓励用户迁移到 Python 3.x。

Python 3.x

  • Python 3.0:2008年发布,这是 Python 的一次重大更新,引入了许多改进,包括更好的 Unicode 支持、简化语法和改进的库。
  • Python 3.1:2009年发布,引入了新的上下文管理器和语法改进。
  • Python 3.2:2011年发布,带来了更好的安全性、性能改进和新特性。
  • Python 3.3:2012年发布,引入了新的标准库模块和改进。
  • Python 3.4:2014年发布,引入了 asyncio 模块,支持异步 I/O。
  • Python 3.5:2015年发布,进一步增强了 asyncio,并引入了新的类型提示功能。
  • Python 3.6:2016年发布,引入了 f-strings 和类型注解的新语法。
  • Python 3.7:2018年发布,带来了新的数据类(data classes)、异步上下文管理器和其他改进。
  • Python 3.8:2019年发布,引入了新的赋值表达式(walrus operator :=)和其他新特性。
  • Python 3.9:2020年发布,改进了类型提示,增加了新的字符串替换方法,并增强了字典解包等功能。
  • Python 3.10:2021年发布,引入了模式匹配(Pattern Matching)和其他新特性。
  • Python 3.11:2022年发布,带来了性能提升、改进的错误处理和新的类型检查工具等。
  • Python 3.12:预计将于2024年发布,预计将带来新的特性和改进。

第2章 Python环境搭建

2.1 Python软件安装

  1. 下载 Python
  • 访问 Python 官方网站:https://www.python.org/downloads/

  • 选择你需要的 Python 版本。通常情况下,建议选择最新的稳定版本,即 Python 3.x(如 Python 3.12)。

  1. 安装 Python
  • Windows:

    • 下载完成后,双击 .exe 文件启动安装程序。
    • 在安装界面中勾选 “Add Python to PATH” 选项,以便将 Python 添加到系统路径中。
    • 点击 “Install Now” 进行安装。
  • macOS:

    • 下载完成后,双击 .pkg 文件启动安装程序。
    • 按照安装向导的提示完成安装。
  • Linux:

    • 对于 Debian/Ubuntu 类的系统,可以使用 apt-get

      sudo apt-get update
      sudo apt-get install python3
      
    • 对于 Fedora 类的系统,可以使用 dnf

      sudo dnf install python3
      
  1. 验证安装
  • 打开命令行或终端。

  • 输入 python --version 来查看已安装的 Python 版本。

  • 如果安装成功,会显示类似于 Python 3.12.0 的输出。

2.2 编辑器安装

  1. 下载 PyCharm
  • 访问 PyCharm 官方网站:https://www.jetbrains.com/pycharm/download/

  • 选择适合你的操作系统的版本。PyCharm 有两种版本:Professional(专业版)和 Community(社区版)。社区版是免费的,而专业版提供了更多高级功能。

  • 选择相应的下载链接,下载安装包。

  1. 安装 PyCharm
  • Windows

    • 下载完成后,双击 .exe 文件启动安装程序。
      • 按照安装向导的提示进行安装。
      • 选择安装位置。
      • 选择是否创建桌面快捷方式。
      • 选择是否启动 PyCharm 后自动创建项目。
    • 完成安装后,启动 PyCharm。
  • macOS

    • 下载完成后,双击 .dmg 文件。
    • 将 PyCharm.app 拖拽到 Applications 文件夹。
    • 通过 Launchpad 或者 Finder 中的 Applications 文件夹启动 PyCharm。
  • Linux

    • 下载完成后,解压缩 .tar.gz 文件。
    • 打开终端,进入解压后的文件夹。
    • 运行 bin/pycharm.sh 来启动 PyCharm。

第3章 Python基础语法

3.1 第一个Python程序

3.1.1 使用 Python 命令行
  • 打开命令提示符 win + R --> cmd enter

  • 输入 python 来启动 Python 解释器

>>> print("hello world")
hello world
3.1.2 使用 IPython

IPython 是一个增强的 Python shell,提供了比标准 Python shell 更多的功能,如语法高亮、自动补全等

  • 安装 IPython(如果还没有安装的话)

  • 在命令行或终端中输入 ipython 来启动 IPython

In [1]: print('hello world')
hello world
3.1.3 使用 PyCharm
  • 打开或创建一个 Python 文件
  • 在编辑器中输入代码
  • python 文件名 或编辑器启动

3.2 注释

注释是用来添加说明性文本,帮助其他开发者理解代码的目的和功能

3.2.1 单行注释

单行注释使用 # 符号开始,直到行尾都是注释内容

# 这是一个单行注释
print("hello world")  # 这也是一个单行注释
3.2.2 多行注释

Python并没有内置的多行注释符号,但可以使用三个引号 (""" ''') 来创建一个多行字符串,作为多行注释使用。三个引号通常用于文档字符串(docstrings)

"""
这是一个多行注释,
可以跨越多行,
并且包含任何文本。
"""

print("hello world")  # 这里可以继续写代码

注意:文档字符串 (docstrings)

文档字符串是一种特殊的注释形式,通常用于描述模块、函数、类或方法的用途和用法。它们是用三个引号括起来的字符串,位于定义的开头。文档字符串可以被 __doc__ 属性访问。

def greet(name):
    """
    打印一个友好的问候信息给 name 参数指定的人。

    参数:
        name (str): 被问候的人的名字。
    """
    print(f"Hello, {name}!")

greet.__doc__  # 获取文档字符串

3.3 变量

变量是用来存储数据的标识符。Python是一种动态类型的语言,不需要在声明变量时指定其类型。当你给一个变量赋值时,它的类型就确定了。

3.3.1 变量的赋值

可以直接将值赋给变量

age = 25

height = 1.75

name = "buddha"

is_student = True
3.3.2 变量的命名
  1. 合法字符

    • 变量名只能包含字母、数字和下划线。
    • 变量名不能以数字开头。
  2. 大小写敏感

    • Python中的变量名是区分大小写的。例如,Variable, variable, 和 VARIABLE 是三个不同的变量。
  3. 避免使用保留字

    • 不要使用Python的关键字(如 if, for, while, class, def 等)作为变量名。
  4. 有意义的名字

    • 使用描述性的变量名可以使代码更容易理解。例如,使用 total_sales 而不是 ts
  5. 避免使用单个字母

    • 尽管使用单个字母作为变量名是合法的,但通常最好使用更具描述性的名称,除非在特定情况下单个字母足够清楚(例如循环索引变量 ij)。
  6. 避免使用内置函数名

    • 避免使用Python内置函数名作为变量名,如 list, str, min, max 等。
  7. 驼峰命名法与下划线命名法

    • 在Python中,推荐使用下划线分隔单词(snake_case),而不是驼峰式命名法(CamelCase)。例如,使用 this_is_a_variable 而不是 thisIsAVariable
      • 对于类名,则推荐使用驼峰式命名法。
  8. 全局变量和局部变量

    • 全局变量通常建议使用大写字母加下划线(ALL_CAPS_WITH_UNDERSCORES),例如 MAX_CONNECTIONS
    • 局部变量和函数参数通常使用小写字母加下划线。
  9. 特殊变量名

    • Python有一些特殊变量名,如 __name__, __doc__, __package__ 等,这些应该仅用于它们预定的目的。
  10. PEP 8 标准

    • Python有一个官方的风格指南 PEP 8,它提供了一系列关于变量命名以及其他编码风格的最佳实践。

示例:

# 好的变量命名示例
number_of_students = 20
average_score = 75.5
is_valid = True

# 不好的变量命名示例
a = 20
b = 75.5
c = True

3.4 关键字

关键字是指在语言本身具有特殊意义的保留字。这些关键字不能用作变量名、函数名或其他标识符的名称。Python有一套固定的关键字集,这些关键字用于定义语法结构,比如控制流语句、异常处理、类定义等。

3.4.1 Python3.x关键字
In [1]: import keyword

In [2]: keyword.kwlist
Out[2]:
['False',
 'None',
 'True',
 'and',
 'as',
 'assert',
 'async',
 'await',
 'break',
 'class',
 'continue',
 'def',
 'del',
 'elif',
 'else',
 'except',
 'finally',
 'for',
 'from',
 'global',
 'if',
 'import',
 'in',
 'is',
 'lambda',
 'nonlocal',
 'not',
 'or',
 'pass',
 'raise',
 'return',
 'try',
 'while',
 'with',
 'yield']

关键字在Python程序中都有特定的用途。例如:

  • if: 用于条件判断。
  • for: 用于迭代序列。
  • def: 用于定义函数。
  • class: 用于定义类。
  • import: 用于导入模块或包。
  • try: 用于异常处理。
  • return: 用于从函数返回值。
  • pass: 用于创建一个空的代码块。
  • raise: 用于引发异常。

示例:

# 使用 def 定义函数
def greet(name):
    if name == "buddha":
        return "hello buddha"
    else:
        return "hello world"

3.5 基本数据类型

在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。

  1. 整数 (int)

    • 整数是没有小数部分的数字,可以是正数也可以是负数。
    age = 25
    
  2. 浮点数 (float)

    • 浮点数是有小数部分的数字,同样可以是正数也可以是负数。
    height = 1.75
    
  3. 复数 (complex)

    • 复数由实部和虚部组成,虚部以 jJ 结尾。
    z = 3 + 5j
    
  4. 布尔值 (bool)

    • 布尔值表示逻辑值,只有两个可能的值:TrueFalse
    is_student = True
    
  5. 字符串 (str)

    • 字符串是由零个或多个字符组成的序列,可以用单引号 ' 或双引号 " 来包围。
    greeting = "Hello, world!"
    
  6. 列表 (list)

    • 列表是有序的元素集合,可以包含不同类型的数据,并且支持修改。
    numbers = [1, 2, 3, 4, 5]
    
  7. 元组 (tuple)

    • 元组也是有序的元素集合,但一旦创建就不能修改。
    point = (10, 20)
    
  8. 字典 (dict)

    • 字典是键值对的集合,其中每个键都是唯一的。
    person = {"name": "Bob", "age": 30}
    
  9. 集合 (set)

    • 集合是无序的不重复元素的集合。
    unique_numbers = {1, 2, 3, 4, 5}
    
  10. None

    • None 类型只有一个值 None,通常用来表示一个没有值的对象。
    result = None
    

3.6 数据类型转换

在Python中,数据类型转换可以分为两种主要形式:强制类型转换(也称为显式类型转换)和自动类型转换(也称为隐式类型转换)

3.6.1 强制类型转换

通过调用特定的数据类型转换函数来完成的,如int(), float(), str(), bool()

# 显式转换示例
x = 10          # x 是整数
y = 10.5        # y 是浮点数
s = "123"       # s 是字符串

# 转换为浮点数
x_float = float(x)
print(x_float)  # 输出: 10.0

# 转换为整数
y_int = int(y)
print(y_int)    # 输出: 10

# 转换为整数
s_int = int(s)
print(s_int)    # 输出: 123

# 转换为字符串
x_str = str(x)
print(x_str)    # 输出: '10'

# 转换为布尔值
x_bool = bool(x)
print(x_bool)   # 输出: True
3.6.2 自动类型转换

指Python在某些操作中自动进行的数据类型转换。这种转换主要发生在算术运算中,例如当混合了整数和浮点数的操作时。

# 隐式转换示例
a = 10         # a 是整数
b = 20.5       # b 是浮点数

# 混合类型的加法
result = a + b
print(result)  # 输出: 30.5

# 在比较运算中,字符串与数字不会发生隐式转换
# 下面这行代码会引发错误
# c = "100" + 200  # TypeError: can only concatenate str (not "int") to str

布尔值可以被隐式转换为整数。True被视为1,而False被视为0

3.7 运算符

运算符是在编程语言中用来执行特定类型的操作的符号

3.7.1 算术运算符
  • + 加法
  • - 减法
  • * 乘法
  • / 除法(结果为浮点数)
  • // 整数除法(结果为整数,向下取整)
  • % 取模(得到除法的余数)
  • ** 幂运算(指数)
a = 10
b = 3
print(a + b)  # 输出 13
print(a - b)  # 输出 7
print(a * b)  # 输出 30
print(a / b)  # 输出 3.3333333333333335
print(a // b) # 输出 3
print(a % b)  # 输出 1
print(a ** b) # 输出 1000
3.7.2 比较运算符
  • == 等于
  • != 不等于
  • < 小于
  • > 大于
  • <= 小于或等于
  • >= 大于或等于
x = 5
y = 10
print(x == y) # 输出 False
print(x != y) # 输出 True
print(x < y)  # 输出 True
print(x > y)  # 输出 False
print(x <= y) # 输出 True
print(x >= y) # 输出 False
3.7.3 赋值运算符
  • = 赋值
  • += 加法赋值
  • -= 减法赋值
  • *= 乘法赋值
  • /= 除法赋值
  • //= 整数除法赋值
  • %= 取模赋值
  • **= 幂运算赋值
  • &= 按位与赋值
  • |= 按位或赋值
  • ^= 按位异或赋值
  • <<= 左移位赋值
  • >>= 右移位赋值
# = 简单赋值
x = 10
print(x)  # 输出: 10

# 加法赋值 +=
x = 5
x += 3  # 等同于 x = x + 3
print(x)  # 输出: 8

# 减法赋值 -=
x = 10
x -= 4  # 等同于 x = x - 4
print(x)  # 输出: 6

# 乘法赋值 *=
x = 2
x *= 5  # 等同于 x = x * 5
print(x)  # 输出: 10

# 除法赋值 /=
x = 15
x /= 3  # 等同于 x = x / 3
print(x)  # 输出: 5.0

# 整数除法赋值 //=
x = 15
x //= 3  # 等同于 x = x // 3
print(x)  # 输出: 5

# 取模赋值 %=
x = 10
x %= 3  # 等同于 x = x % 3
print(x)  # 输出: 1

# 幂运算赋值 **=
x = 2
x **= 3  # 等同于 x = x ** 3
print(x)  # 输出: 8

# 按位与赋值 &=
x = 5  # 二进制: 0101
x &= 3  # 二进制: 0011 (等同于 x = x & 3)
print(x)  # 输出: 1 (二进制: 0001)

# 按位或赋值 |=
x = 5  # 二进制: 0101
x |= 3  # 二进制: 0011 (等同于 x = x | 3)
print(x)  # 输出: 7 (二进制: 0111)

# 按位异或赋值 ^=
x = 5  # 二进制: 0101
x ^= 3  # 二进制: 0011 (等同于 x = x ^ 3)
print(x)  # 输出: 6 (二进制: 0110)

# 左移位赋值 <<=
x = 5  # 二进制: 0101
x <<= 1  # 等同于 x = x << 1
print(x)  # 输出: 10 (二进制: 1010)

# 右移位赋值 >>=
x = 10  # 二进制: 1010
x >>= 1  # 等同于 x = x >> 1
print(x)  # 输出: 5 (二进制: 0101)
3.7.4 逻辑运算符
  • and 逻辑与
  • or 逻辑或
  • not 逻辑非
bool1 = True
bool2 = False
print(bool1 and bool2) # 输出 False
print(bool1 or bool2)  # 输出 True
print(not bool1)       # 输出 False
3.7.5 成员运算符
  • in 判断元素是否在序列中
  • not in 判断元素是否不在序列中
list1 = [1, 2, 3, 4, 5]
print(3 in list1)      # 输出 True
print(6 not in list1)  # 输出 True
3.7.6 身份运算符
  • is 判断两个变量是否指向同一个对象
  • is not 判断两个变量是否不指向同一个对象
list1 = [1, 2, 3, 4, 5]
list2 = list1
print(list1 is list2)  # 输出 True
print(list1 is not list2) # 输出 False
3.7.7 位运算符
  • ~ 按位取反
  • & 按位与
  • | 按位或
  • ^ 按位异或
  • << 左移
  • >> 右移
num1 = 5  # 二进制: 0101
num2 = 3  # 二进制: 0011
print(num1 & num2)     # 输出 1 (0001)
print(num1 | num2)     # 输出 7 (0111)
print(num1 ^ num2)     # 输出 6 (0110)
print(~num1)           # 输出 -6
print(num1 << 1)       # 输出 10 (1010)
print(num1 >> 1)       # 输出 2 (0010)

3.8 type() 和 input()函数

3.8.1 type() 函数

type() 函数用于返回对象的数据类型。

a = 5
b = "Hello"
c = [1, 2, 3]

print(type(a))  # 输出: <class 'int'>
print(type(b))  # 输出: <class 'str'>
print(type(c))  # 输出: <class 'list'>
3.8.2 input() 函数

input() 函数用于从用户那里获取输入。它总是返回一个字符串。如果需要其他类型的值,需要强制类型转换

name = input("请输入你的名字: ")
print("你好,", name)

# 获取整数输入
age = int(input("请输入你的年龄: "))
print("你的年龄是:", age)

# 获取浮点数输入
height = float(input("请输入你的身高(米): "))
print("你的身高是:", height, "米")

3.9 字符串运算

3.9.1 拼接字符串

使用 + 运算符来拼接两个字符串

s1 = "Hello"
s2 = "World"
result = s1 + s2
print(result)  # 输出: HelloWorld
3.9.2 重复字符串

使用 * 运算符来重复字符串

repeat = "*" * 3
print(repeat)  # 输出: ***

3.10 格式化输出

在 Python 中,格式化输出是指将变量的值插入到字符串中,生成易于阅读的输出。

3.10.1 使用 % 运算符

这是 Python 2 中常用的字符串格式化方法,但在 Python 3 中仍然可用。

name = "曹操"
age = 38

# 使用 %s 表示字符串,%d 表示整数
output = "My name is %s and I am %d years old." % (name, age)
print(output)  # 输出: My name is 曹操 and I am 38 years old.
3.10.2 使用 str.format()

str.format() 方法是 Python 2.6 及以上版本引入的一种更灵活的字符串格式化方法。

name = "曹操"
age = 38

# 使用 {} 占位符,并通过 format 方法传入参数,默认按顺序匹配
output = "My name is {} and I am {} years old.".format(name, age)
print(output)  # 输出: My name is 曹操 and I am 38 years old.

# 指定占位符的位置,使用索引匹配
output = "My name is {0} and I am {1} years old.".format(name, age)
print(output)  # 输出: My name is 曹操 and I am 38 years old.

# 使用关键字参数,使用关键字匹配
output = "My name is {name} and I am {age} years old.".format(name=name, age=age)
print(output)  # 输出: My name is 曹操 and I am 38 years old.
3.10.3 使用 f-string (f-strings)

从 Python 3.6 开始,引入了 f-string,这是一种更为简洁和直观的格式化字符串的方法。

name = "曹操"
age = 38

# 使用 f-string
output = f"My name is {name} and I am {age} years old."
print(output)  # 输出: My name is 曹操 and I am 38 years old.

# 更复杂的表达式
output = f"My name is {name} and I am {age * 2} years old next year."
print(output)  # 输出: My name is 曹操 and I am 76 years old next year.
3.10.4 使用 str() 和字符串拼接

虽然不是真正的格式化,但可以使用 str() 函数将其他类型的值转换为字符串,然后使用 + 进行拼接。

name = "曹操"
age = 38

output = "My name is " + name + " and I am " + str(age) + " years old."
print(output)  # 输出: My name is 曹操 and I am 38 years old.
3.10.5 格式符号

用于指定变量类型和格式化样式的占位符。格式符号主要用于 % 运算符和 str.format() 方法中。

使用 % 运算符

  • %s - 字符串 (string)
  • %d - 整数 (decimal integer)
  • %f - 浮点数 (floating point)
  • %.nf - 浮点数,其中 n 是小数点后的位数
  • %e%E - 科学记数法 (exponential notation)
  • %g%G - 自动选择 %f%e 中较短的一个
  • %c - 字符 (character)
  • %r - 原始数据 (raw data) 或 repr() 的输出
age = 38
height = 1.757
name = "曹操"

# 使用 % 运算符
print("Name: %s, Age: %d, Height: %.2f" % (name, age, height))

# 使用 str.format()
print("Name: {}, Age: {}, Height: {:.2f}".format(name, age, height))

# 使用 f-string
print(f"Name: {name}, Age: {age}, Height: {height:.2f}")

第4章 基本控制结构

基本控制结构是编写任何程序的基础。基本控制结构包括顺序结构、选择结构和循环结构。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.1 顺序结构

顺序结构是最简单的控制结构,按照代码出现的顺序依次执行。

print("第一步")
print("第二步")
print("第三步")

4.2 选择结构

选择结构,也称为条件分支或分支结构。根据不同的条件执行不同的代码块。Python 中的选择结构主要包括 if 语句、if-else 语句以及 if-elif-else 语句。

4.2.1 if 语句

if 语句用于基于一个条件执行一段代码。如果条件为真(True),则执行该段代码;否则跳过。

num = 5
if num > 3:
    print("num 大于 3")
4.2.2 if-else 语句

if-else 语句用于基于一个条件执行两段不同的代码。如果条件为真,则执行 if 后面的代码块;否则执行 else 后面的代码块。

age = 15
if age >= 18:
    print("已成年")
else:
    print("未成年")
4.2.3 if-elif-else 语句

if-elif-else 语句用于基于多个条件执行不同的代码块。程序会从上到下检查每个条件,当遇到第一个为真的条件时,执行对应的代码块,并且不再检查后面的条件。

score = 75
if score >= 90:
    print("优秀")
elif score >= 80:
    print("良好")
elif score >= 60:
    print("及格")
else:
    print("不及格")
4.2.4 选择结构的嵌套

在一个 ifif-elseif-elif-else 结构内部,可以包含另一个完整的选择结构。

score = 85

if score >= 90:
    print("优秀")
elif score >= 80:
    if score < 85:
        print("良好但未达到 85 分")
    else:
        print("良好且达到 85 分")
elif score >= 70:
    print("中等")
else:
    print("较差")

注意:选择结构的嵌套可以处理更加复杂的条件逻辑,使程序能够根据多个层次的条件做出准确的决策。但过度嵌套会导致代码的可读性降低,实际编程中应尽量保持代码结构清晰。

4.3 循环结构

循环结构允许重复执行一段代码,直到满足某个条件为止。主要分为 for 循环和 while 循环。

4.3.1 for循环

for 循环通常用于遍历一个可迭代对象(如列表、元组、字符串等)

# 遍历列表
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# 遍历字符串
for char in "hello":
    print(char)

# 使用 range() 函数指定循环次数
for i in range(5):  # 相当于 for i in [0, 1, 2, 3, 4]
    print(i)
4.3.2 while循环

while 循环只要指定的条件为真,就会一直执行循环体中的代码

count = 0
while count < 5:
    print(count)
    count += 1
4.3.3 break关键字

break 用于立即终止当前所在的循环结构,无论循环条件是否仍然为真。

for i in range(10):
    if i == 5:
        break
    print(i)
4.3.4 continue关键字

continue 用于跳过当前循环中的剩余语句,直接开始下一次循环。

for i in range(10):
    if i % 2 == 0:
        continue
    print(i)

for、while完整结构

for 临时变量 in 变量:
    执行True代码
else:
    执行False代码

    
while 条件:
    执行True代码
else:
    执行条件为False代码

第5章 函数

5.1 定义与调用

函数的作用:能够将复杂的程序逻辑分解为可重复使用的模块。

业务→业务逻辑→程序逻辑

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

语法:

# 定义一个函数
def 函数名(参数列表):
    """
    这个函数的功能是实现xxx功能
    """
    函数体
    
# 调用函数
函数名(参数列表)

示例:

# 定义一个函数
def hello():
    """
    这个函数的功能是实现输出hello,world功能
    """
    print("HelloWorld")
    
# 调用函数
hello()

5.2 函数名

命名规则

1、可以由字母、数字和下划线组成

2、不能以数字开头

3、不能是 Python 中的关键字(如 ifforwhile 等)

合法函数名示例

def my_function():
    pass

def add_numbers():
    pass

def calculate_sum():
    pass

不合法函数名示例

# 以数字开头
def 123function():
    pass

# 是关键字
def if():
    pass

函数最佳命名规则

1、使用小写字母和下划线,函数名应全部使用小写字母,并使用下划线 (_) 分隔单词。例如,add_numbers

2、简洁但具有描述性,函数名应该尽可能简短,但也要足够描述其功能。例如,get_totalgt 更好

3、使用动词,函数名通常以动词开头,因为它表示一个动作。例如,read_file, send_email

4、使用名词,如果函数用于获取某些信息,可以使用名词。例如,get_list, fetch_data

5、使用前缀或后缀,使用前缀或后缀可以帮助区分不同类型的函数。例如,is_valid 表示一个布尔检查函数,get_ 通常用于获取信息

6、避免使用数字,尽量不要在函数名中使用数字,除非它们有特殊意义。例如,process_data_v2 可能表示这是数据处理函数的第二个版本

最佳函数命名示例

def add_numbers():
    pass

def get_total():
    pass

def read_file():
    pass

def send_email():
    pass

def get_list():
    pass

def fetch_data():
    pass

def is_valid():
    pass

def process_data_v2():
    pass

5.3 函数参数

在 Python 函数中,函数可以没有参数,也可以有参数。如果有参数,函数参数是用来传递数据给函数的变量。根据不同的需求,Python 支持多种类型的参数,包括位置参数、关键字参数、默认值参数、不定长参数等。

5.3.1 位置参数

位置参数是按照顺序来传递给函数的。

def multiply(x, y):
    print(x * y)

    
multiply(3, 5)  # 3 和 5 是位置参数

5.3.2 关键字参数

关键字参数允许你在调用函数时通过参数名指定参数值,这样就不必关心参数的实际位置了。关键字参数可以在任何位置使用,并且可以与位置参数混合使用。

def multiply(x, y):
    print(x * y)

    
multiply(x=3, y=5)    # 使用关键字参数
multiply(3, y=5)      # 混合使用位置参数和关键字参数

当位置参数和关键字参数混合使用时,位置参数必须出现在关键字参数之前

5.3.3 默认值参数

默认值参数是在定义函数时为参数指定一个默认值。如果调用函数时没有提供这个参数的值,那么就会使用默认值。

def multiply(x, y=5):
    print(x * y)


multiply(3, 6)
multiply(3)
multiply(x=3, y=6)
multiply(x=3)

5.3.4 不定长参数

不定长参数允许函数接受不定数量的位置参数或关键字参数。

*不定长位置参数 (args)

当参数列表前面加上星号 (*) 时,可以接收任意数量的位置参数。

def add_numbers(*args):
    numbers_sum = 0
    for i in args:
        numbers_sum += i
    print(numbers_sum)


add_numbers(1, 2)
add_numbers(1, 2, 3)

*不定长关键字参数(*kwargs)

当参数列表前面加上两个星号 (**) 时,可以接收任意数量的关键字参数。

def print_message(**kwargs):
    for key, value in kwargs.items():
        print(key + "=" + str(value))


print_message(name="buddha", age=18, height=1.75)
print("*" * 20)
print_message(name="buddha", age=18)

5.3.5 参数组合

一个函数的参数可以有位置参数、默认值参数、不定长位置参数、不定长关键字参数的组合。如果有参数组合,其函数定义时,参数从左到右的顺序是:位置参数、默认值参数、不定长位置参数、不定长关键字参数。

def show(name, height=1.80, *args, **kwargs):
    print(f'{name},{height}')
    for i in args:
        print(i)
    for key, value in kwargs.items():
        print(f'{key}-{value}')


show("buddha", 1, 2, says="hello,world")

5.4 函数返回值

1、返回值,就是函数执行完毕,返回给调用者的结果。如果函数没有显式地返回任何值,则通常返回None

2、函数需要显示地返回返回值,用关键字return

3、函数内可以有多个return,碰到第一个return关键字就结束了函数的调用

4、在Python中,可以返回一个值,或用元组的方式返回多个值

返回一个值的示例

# 函数返回一个值
def add_numbers(a, b):
    return a + b


sum_numbers = add_numbers(1,2)
print(sum_numbers)  # 3

返回多个值的示例

# 函数返回元组,元组中含有多个值
def do_numbers(a, b):
    return a + b, a - b


numbers = do_numbers(1, 2)
print(numbers[0], numbers[1])

5.5 作用域

作用域是指变量在程序中的可见性范围。

1、局部作用域:

  • 在函数内部定义的变量具有局部作用域,只能在该函数内部访问。
  • 当函数调用结束时,局部变量的作用域也随之结束。

2、全局作用域:

  • 在函数外部定义的变量具有全局作用域,可以在整个程序中访问。
  • 全局变量在程序执行开始时创建,在程序结束时销毁。

3、封闭作用域:

  • 当一个函数内部定义了另一个函数时,内部函数可以访问外部函数的变量(局部变量)。
  • 外部函数的变量(局部变量)对于内部函数来说处于封闭作用域。

4、内置作用域:

  • Python 提供了一系列内置函数和常量,如 print()type()input()等,它们在所有作用域中都是可用的。

内层使用外层变量

# 全局变量
x = "全局变量"


def outer_function():
    y = "外部函数的局部变量"  # 封闭作用域

    def inner_function():
        z = "内部函数的局部变量"  # 局部作用域
        print(z)
        print(y)  # 访问封闭作用域中的变量
        print(x)  # 访问全局作用域中的变量

    inner_function()


outer_function()

# 下面这行会抛出 NameError,因为 y 是封闭作用域中的变量
# print(y)

# 下面这行会打印全局变量 x 的值
print(x)

原则是:内层可以使用外层,外层使用不了内层

内层修改外层变量

函数内部修改全局变量,该全局变量需要在函数内部用global关键字声明

内层函数修改外层函数的变量,该外层函数的局部变量在内层函数中用nonlocal关键字声明

外层不直接使用内层的变量,这样子破坏了函数的封装性

5.6 函数的嵌套

在 Python 中,函数的嵌套是指在一个函数内部定义另一个函数。这样的设计可以用来创建更加复杂的功能组合,同时保持代码的整洁和模块化。

简单嵌套

def outer():
    print("这是外部函数被调用")

    def inner():
        print("这是内部函数被调用")

    inner()


outer()

返回内部函数

def outer_function():
    print("外包函数...")

    def inner_function():
        return "内部函数..."

    return inner_function  # 返回内部函数的引用


inner = outer_function()  # 获取内部函数的引用
print(inner())  # 调用内部函数

嵌套的应用

def factorial(n):
    """
    实现阶乘的功能,内部函数是递归函数
    """
    def recursive_factorial(n):
        if n == 0:
            return 1
        else:
            return n * recursive_factorial(n - 1)

    return recursive_factorial(n)


print(factorial(3))  # 输出 6

5.7 匿名函数

在 Python 中,匿名函数也称为 lambda 函数。它是一种简洁的方式来定义一个小型的、一次性使用的函数。

匿名函数的语法:

lambda 参数: 表达式

说明:

  • 参数:可以是一个或多个参数,多个参数之间用逗号分隔
  • 表达式:是一个单一的表达式,表达式的结果作为函数的结果返回

示例:

# 示例 1:计算两个数的和
add = lambda x, y: x + y
print(add(3, 5))  

# 示例 2:对一个数进行平方运算
square = lambda x: x ** 2
print(square(4))  

# 示例 3:判断一个数是否为偶数
is_even = lambda x: x % 2 == 0
print(is_even(6))  

5.8 文档字符串

文档字符串是放在函数、类或模块的第一个逻辑行上的字符串,用于描述该对象的用途、行为或用法。__doc__ 属性可以用来获取这些文档字符串的内容。

示例:

def function(*args):
    """函数的文档字符串
    :param args: 参数说明
    :return: 函数返回值说明
    """
    pass


# 通过 函数名.__doc__ 获取文档字符串
print(function.__doc__)
# 通过 help(函数名) 获取文档字符串
help(function)

5.9 内置函数

Python 中提供了大量的内置函数,这些函数可以直接在程序中使用。

5.9.1 获取内置函数帮助信息

方式一:官方手册地址:https://docs.python.org/3/library/functions.html

方式二:函数名.__doc__

方式三:help(函数名)

5.9.2 常见内置函数示例
# print() 用于输出文本或变量的值
print("Hello, World!")
num = 5
print(num)

# len() 返回对象(如字符串、列表、元组等)的长度
str = "Python"
print(len(str))  
list = [1, 2, 3, 4, 5]
print(len(list))

# range() 用于生成一个整数序列
for i in range(5):
    print(i)
    
# sum() 计算可迭代对象(如列表、元组等)中所有元素的总和
numbers = [1, 2, 3, 4, 5]
print(sum(numbers))

# max() 和 min() 分别返回可迭代对象中的最大值和最小值
numbers = [5, 2, 8, 1, 9]
print(max(numbers))
print(min(numbers))

# abs() 返回一个数的绝对值
num = -5
print(abs(num))

# type() 返回对象的类型
num = 5
print(type(num))

# input() 用于获取用户的输入
name = input("请输入您的名字:")
print(f"您好,{name}!")

第6章 面向对象

6.1 面向过程和面向对象

在 Python 中,你可以使用两种主要的编程风格来编写代码:面向过程(Procedural Programming)和面向对象(Object-Oriented Programming, OOP)。

6.1.1 面向过程编程

面向过程编程是一种结构化的编程范式,它将程序视为一系列的过程或者函数。

  • **强调过程和步骤:**面向过程编程关注解决问题的具体步骤和流程,将问题分解为一系列的函数或过程,按照顺序依次执行来完成任务。

  • **数据与操作分离:**数据和对数据的操作通常是分开定义的,数据在各个函数之间传递。

  • **以函数为基本单元:**程序主要由一个个函数组成,函数负责完成特定的任务。

  • **注重流程控制:**通过顺序、选择(如 if-else 语句)和循环(如 forwhile 语句)等控制结构来决定程序的执行流程。

  • **程序的可读性依赖于流程的清晰性:**由于重点在于步骤的执行顺序,代码的可读性很大程度上取决于流程是否容易理解。

  • **较难维护和扩展:**当程序规模较大或需求发生变化时,修改和扩展代码可能会比较困难,因为一个函数的修改可能会影响到其他依赖它的部分。

  • **不利于代码复用:**虽然函数可以在一定程度上实现代码复用,但相对面向对象编程来说,复用的程度和灵活性较低。

6.1.2 面向对象编程

面向对象编程是一种编程范式,它将程序设计成由对象(Object)组成的世界。对象包含数据(属性)和对这些数据的操作(方法)。面向对象编程强调的是数据的封装、继承和多态等特性。

  • **封装性(Encapsulation):**将对象的属性(数据)和方法(行为)封装在一起,形成一个独立的单元。外部无法直接访问对象的内部实现细节,只能通过定义好的公共接口(方法)来与对象进行交互。

  • **继承性(Inheritance):**允许创建新的类(子类),这些子类可以继承现有类(父类)的属性和方法,并可以在此基础上添加新的属性和方法,或者修改父类的方法。

  • **多态性(Polymorphism):**不同的对象可以对相同的消息(方法调用)做出不同的响应。这意味着可以使用相同的方法名在不同的类中实现不同的功能。

  • **抽象性(Abstraction):**提取出对象的共同特征和行为,形成类的定义,忽略具体的实现细节。

  • **对象的独立性和自治性:**每个对象都是独立的实体,具有自己的状态和行为,并且能够独立地处理自身的数据和逻辑。

  • **可维护性和可扩展性:**由于封装、继承和多态等特性,使得代码更容易维护和扩展。新的功能可以通过添加新的类或修改现有类来实现,而不会影响到不相关的部分。

  • **代码复用性高:**通过继承和组合等方式,可以重复利用已有的代码和设计,减少重复开发。

6.2 类和对象

6.2.1 类 (Class)

类是对象的模板或蓝图,它定义了一组相关的属性和方法。类可以看作是一种自定义的数据类型,定义了一组具有相同属性和方法的对象的蓝图或模板,用于描述具有相同属性和行为的对象。

6.2.2 类的定义

在 Python 中,定义一个类使用 class 关键字:

class Person:
    # 属性
    # 方法

说明:

  • 属性:属性是类中的变量,用于存储对象的状态信息。属性可以是任何数据类型,如整数、字符串等。

  • 方法:方法是类中的函数,用于描述对象的行为。方法通常定义了如何操作类的属性。

class Person:
    name = '小明'
    age = 6
        
    def eat(self):
        print(f'{self.name}在吃饭饭...')

类名采用驼峰命名规范

6.2.3 对象 (Object)

对象是类的具体实例。通过类创建对象的过程称为实例化。

对象具有类所定义的属性和方法,可以对其进行操作和使用。

6.2.4 创建对象

通过类的实例化,创建了该类的一个对象

p = Person()
6.2.5 访问属性和方法

在外部,访问属性和方法,通过对象名.属性名对象名.方法名()

# 访问属性
p.name
# 访问方法
p.eat()

在内部,访问属性和方法,通过self.属性名 self.方法名()

# 访问属性
self.name
# 访问方法
self.eat()
6.2.6 构造方法

类实例化对象的时候,会触发一个内置的方法就是__init__,叫构造方法,也叫初始化方法;在特定的情况下由解释器自动调用;常用来实例化的同时,完成对象的初始化设置

class Person:
    name = '小明'
    age = 6

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self):
        print(f'{self.name}在吃饭饭...')


p = Person("小王", 8)
print(p.name)
p.eat()

6.3 魔术方法

在Python面向对象中,方法名类似__xxx___,在特定情况下由解释器自动调用,称为魔术方法。

6.3.1 __init__(self,...)方法
  • 触发时机:对象被初始化的时候
  • 作用:完成对象初始化配置
class Person:
    def __init__(self, name):
        self.name = name


p = Person("小王")
print(p.name)
6.3.2 __str__(self)方法
  • 触发时机:打印对象的时候
  • 作用:执行__str__()方法里的代码,能够返回一个字符串
class Person:
    name = "小明"
    age = 18

    def __str__(self):
        return f"该实例化对象:名字叫{self.name}, 年龄是{self.age}岁!"


p = Person()
print(p)
6.3.3 __del__(self)方法
  • 触发时机:当一个对象被垃圾回收或显式删除时
  • 作用:主要用于执行一些清理工作,例如关闭文件、释放资源等。

注意事项:

  • 不确定性:Python 的垃圾回收机制并不保证在程序结束时立即释放所有对象。因此,__del__() 方法的调用时机可能是不确定的。
  • 避免引发异常:在 __del__() 方法中引发异常可能会导致程序崩溃,因为 Python 无法处理这些异常。尽量避免在 __del__() 中执行可能引发异常的操作,或者确保能够妥善处理这些异常。
  • 显式删除:可以使用 del 语句显式删除对象,这会触发 __del__() 方法的调用。
class Person:
    def __del__(self):
        print("触发__del__()方法")


p = Person()
# 显示删除对象
del p

6.4 面向对象三大特征

6.4.1 封装

​ 封装,指的是隐藏对象的内部状态和实现细节,只暴露必要的接口,不能对内部数据直接访问,只能通过特定的方法操作。助于保护数据的完整性、安全性。

公有属性和方法

属性和方法可以被类的外部直接访问。在Python中,默认情况下,类的所有属性和方法都是公有的。

class Person:
    def __init__(self, name, age):
        self.name = name   # 公有属性
        self.age = age     # 公有属性
 
    def get_name(self):
        return self.name   # 公有方法
 
# 外部直接使用公有属性和方法
p = Person("buddha", 18)
print(p.name)  # 输出: buddha
print(p.get_name())  # 输出: buddha

私有属性和方法

属性和方法不可以被类的外部直接访问。在 Python 中,可以在属性名或方法名前加上**单下划线_双下划线 __**来定义私有属性和方法。

class Person:
    def __init__(self, name, age):
        self.__name = name  # 私有属性
        self.__age = age  # 私有属性

    def __display_info(self):
        return f"Name: {self.__name}, Age: {self.__age}"  # 私有方法


# 外部无法直接访问私有属性和方法
p = Person("buddha", 18)
# print(p.__name)  # 这会引发错误,因为__name是私有属性
# print(p.__display_info())  # 这会引发错误,因为__display_info()是私有方法

单下划线或双下划线是Python社区遵循的一种约定,在 Python 中,并没有严格意义上的私有属性或方法。

class Person:
    def __init__(self, name, age):
        self.__name = name  # 私有属性
        self.__age = age  # 私有属性

    def __display_info(self):
        return f"Name: {self.__name}, Age: {self.__age}"  # 私有方法


# 外部依然可以直接访问私有属性和方法
p = Person("buddha", 18)
print(p._Person__name)
print(p._Person__display_info())

双下划线导致名称改编,通过_类名__属性名_类名__方法名访问

class Person:
    def __init__(self, name, age):
        self._name = name  # 私有属性
        self._age = age  # 私有属性

    def _display_info(self):
        return f"Name: {self._name}, Age: {self._age}"  # 私有方法


# 外部依然可以直接访问私有属性和方法
p = Person("buddha", 18)
print(p._name)
print(p._display_info())
class Person:
    def __init__(self, name, age):
        self._name = name  # 私有属性
        self._age = age  # 私有属性

    def _display_info(self):
        return f"Name: {self._name}, Age: {self._age}"  # 私有方法


# 外部依然可以直接访问私有属性和方法
p = Person("buddha", 18)
print(p._name)
print(p._display_info())
6.4.2 继承

在 Python 中,继承是一种创建新类的方式,新类可以从一个或多个已有的类中继承属性和方法,这个新类被称为子类,而被继承的类称为父类(也可称为基类、超类)。子类可以继承父类的所有公有属性和方法,但不能继承私有属性和方法。

单继承

单继承是指一个子类只继承一个父类。

语法:

class 子类名(父类名):
    # 子类的属性和方法

示例:

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "汪汪汪!我是{}".format(self.name)

多继承

多继承是指一个子类同时继承多个父类

语法:

class 子类名(父类名 1, 父类名 2,...):
    # 子类的属性和方法

示例:

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

class Flyable:
    def fly(self):
        return "我可以飞!"

class Bird(Animal, Flyable):
    def speak(self):
        return "叽叽叽!我是{}".format(self.name)

当多个父类中存在同名方法时,Python 会按照特定的顺序来确定调用哪个父类的方法。这个顺序是通过方法解析顺序(Method Resolution Order,MRO)来确定的

print(子类名.__mro__)

方法重写

子类中重新定义父类中的方法。当子类继承父类时,可能会发现父类中的某些方法不能完全满足子类的需求。这时,子类可以重写父类的方法,以实现更适合子类的行为。

class Animal:
    def make_sound(self):
        print("动物发出声音")

class Dog(Animal):
    def make_sound(self):
        print("汪汪汪!")

子类重写的方法可以访问父类中被重写的方法,使用super()函数来调用父类的方法。

class Animal:
    def make_sound(self):
        print("动物发出声音")

class Dog(Animal):
    def make_sound(self):
        super().make_sound()
        print("汪汪汪!")

当需要在子类中,对父类的构造方法进行重写时,必须在子类的构造方法中,显式地调用父类的构造方法,否则父类的初始化逻辑将不会被执行,可能导致继承自父类的属性无法正确初始化。

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name, breed):
        self.breed = breed
        super().__init__(name)

属性遮蔽

在子类中定义了与父类同名的属性,从而遮蔽了父类中的属性。

class Parent:
    attr = "Parent's attribute"

class Child(Parent):
    attr = "Child's attribute"

c = Child()
print(c.attr)  # 输出:Child's attribute
6.4.3 多态

指允许不同类的对象对同一消息作出响应的能力。

方法重写

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "汪汪汪!"

class Cat(Animal):
    def speak(self):
        return "喵喵喵!"

def animal_speak(animal):
    print(animal.speak())

dog = Dog()
cat = Cat()

animal_speak(dog)  # 输出: 汪汪汪!
animal_speak(cat)  # 输出: 喵喵喵!

鸭子类型

不关注对象的类型,而是关注对象是否具有特定的方法和属性。

class Duck:
    def quack(self):
        print("嘎嘎嘎!")


class Person:
    def quack(self):
        print("我在模仿鸭子叫!")


def make_quack(obj):
    obj.quack()

6.5 属性

6.5.1 类属性

类属性,属于类本身的属性,类所有实例化的对象都可以使用,定义类的时候直接定义类属性,位于类的方法外,可以通过类名.属性名类实例化对象.属性名访问。

class Circle:
    pi = 3.14  # 类属性

    def __init__(self, radius):
        self.radius = radius

c1 = Circle(5)
c2 = Circle(3)

print(Circle.pi)  # 3.14
print(c1.pi)  # 3.14
print(c2.pi)  # 3.14

Circle.pi = 3.14159
print(c1.pi)  # 3.14159
print(c2.pi)  # 3.14159
6.5.2 实例属性

实例属性,属于类实例化的属性,也就是对象属性,每个实例属性,都是对应实例对象的属性,在类的实例化过程中,通过构造方法 __init__中初始化的属性。通过类实例化对象.属性名访问。

class Circle:
    pi = 3.14  # 类属性

    def __init__(self, radius):
        self.radius = radius  # 实例属性

c1 = Circle(5)
c2 = Circle(3)

print(c1.radius)  # 5
print(c2.radius)  # 3

c1.radius = 6
print(c1.radius)  # 6
print(c2.radius)  # 3

6.6 方法

6.6.1 实例方法

实例方法是最常见的方法类型,它需要一个实例对象作为第一个参数(通常命名为 self)。实例方法可以访问和修改实例变量以及类变量。

class Cat:
    def __init__(self, name):
        self.name = name

    def say(self):
        print(self.name)


c = Cat("加菲猫")
c.say()  # 输出: 加菲猫

6.6.2 类方法

类方法的第一个参数是类本身(通常命名为 cls),并且可以通过该参数访问和修改类变量。类方法主要用于操作整个类的状态,而不是某个特定实例的状态。要定义类方法,你需要使用 @classmethod 装饰器;类方法可以直接通过类名来调用,也可以通过实例来调用。

class Cat:
    name = "加菲猫"

    @classmethod
    def get_name(cls):
        print(cls.name)

    @classmethod
    def set_name(cls, name):
        cls.name = name


c = Cat()
c.get_name()  # 输出: 加菲猫
Cat.get_name()  # 输出: 加菲猫

Cat.set_name("卡丁猫")
Cat.get_name()  # 输出: 卡丁猫

6.6.3 类静态方法

静态方法既不需要实例也不需要类作为参数,它与类或实例没有直接的关系。静态方法通常用于执行与类或实例无关的操作。要定义静态方法,则需要使用 @staticmethod 装饰器;静态方法同样可以直接通过类名来调用,也可以通过实例来调用。

class Cat:
    @staticmethod
    def say():
        print("静态方法")


c = Cat()
c.say()  # 输出: 静态方法
Cat.say()  # 输出: 静态方法

第7章 模块与包

在 Python 中,模块和包是用来组织代码的重要工具。管理代码结构,避免命名冲突,并使代码更容易管理和复用。

7.1 模块

模块是一个包含 Python 代码的文件。通常,一个模块就是一个 .py 文件。模块内容可以是变量、函数和类。

新建模块

假设新建一个 utils.py文件,文件内容如下

# utils.py

# π
pi = 3.14


def round_perimeter(r):
    """
    计算圆的周长
    :param r: 圆的半径
    :return: 圆的周长
    """
    return 2 * pi * r


class Round(object):
    """
    计算圆的面积
    """

    def __init__(self, r):
        self.r = r

    def round_area(self):
        return pi * (self.r ** 2)

在每个模块最下面加测试代码,只会在测试情况下运行,被导入时不会被执行

# utils.py

# 在代码的最下方
def main():
    # ...
    pass

# 根据 __name__ 判断是否执行下方代码
if __name__ == "__main__":
    main()

使用模块

导入整个模块

# main.py
import utils

result = utils.round_perimeter(1)
print(result)  # 输出 6.28

导入特定变量、函数或类

# main.py
from utils import round_perimeter

result = round_perimeter(1)
print(result)  # 输出 6.28

导入所有内容

# main.py
from utils import *

result = round_perimeter(1)
print(result)  # 输出 6.28
print(pi)  # 输出 3.14

使用别名

# main.py
import utils as u

result = u.round_perimeter(1)
print(result)  # 输出 6.28

7.2 包

由多个相关模块组成的集合,用于组织和管理代码。包本身也是一个模块,但通常包含其他模块。

新建包

新建一个目录,目录里面必须包含初始化文件__init__.py,Python才知道这是一个包,文件内容可以为空。

假设新建一个round_package的包

包结构示例:

round_package/
│
├── __init__.py
├── round_perimeter.py
└── round_area.py

__init__.py文件可以包含一些代码来初始化包,也可以在__init.py文件定义默认导入的内容

# __init__.py 文件把两个模块导入,到时模块调用就不需要加模块名了
from round_perimeter import *
from round_area import * 

使用包

# main.py
from round_package import round_perimeter as u, round_area

result = u.round_perimeter(1)
print(result)  # 输出 6.28

7.3 包管理工具

pip 是 Python 的包管理工具,用于安装、卸载和管理第三方模块。

安装 pip(如果尚未安装)

# 对于大多数系统
python -m ensurepip --upgrade

# 或者
python -m pip install --upgrade pip

查看已安装的模块

pip list

安装模块

要安装一个模块,可以使用 pip install 命令,后面跟上模块的名称。例如,要安装 numpy 模块,可以使用:

pip install numpy

升级模块

如果想要升级已安装的模块到最新版本,可以使用 pip install --upgrade 命令:

pip install --upgrade numpy

卸载模块

pip uninstall numpy

查找模块

如果你不确定某个模块是否存在或想要查找模块的版本信息,可以使用 pip search 命令:

pip search numpy

显示模块信息

要显示模块的详细信息,可以使用 pip show 命令:

pip show numpy

安装指定版本的模块

如果你想安装特定版本的模块,可以使用 -==== 后跟版本号的方式:

pip install numpy==1.20.0

第8章 异常处理

8.1 异常的概念

程序运行时,Python 解释器遇到到一个错误,会停止程序的执行,并且提示错误信息,这就是异常。程序停止执行并提示错误信息,这个动作称为:抛出(raise)异常

8.2 捕获异常

将可能会引发异常的代码放在 try 块内,而将处理异常的代码放在 except 块内。

语法:

try:
    尝试执行的代码
except:
    出现错误的处理

示例:

try:
    # 尝试执行的代码
    result = 10 / 0
except ZeroDivisionError:
    # 处理异常的代码
    print("除数不能为零")

遇到不同类型的异常,如果需要针对不同类型异常做出不同处理,则要进行分类型捕获

try:
    # 尝试执行的代码
    pass
except 错误类型1:
    # 针对错误类型1,对应的代码处理
    pass
except (错误类型2, 错误类型3):
    # 针对错误类型2 和 3,对应的代码处理
    pass
except Exception as result:
    print("未知错误 %s" % result)

异常捕获完整语法

try:
    # 尝试执行的代码
    pass
except 错误类型1:
    # 针对错误类型1,对应的代码处理
    pass
except 错误类型2:
    # 针对错误类型2,对应的代码处理
    pass
except (错误类型3, 错误类型4):
    # 针对错误类型3 和 4,对应的代码处理
    pass
except Exception as result:
    # 打印错误信息
    print(result)
else:
    # 没有异常才会执行的代码
    pass
finally:
    # 无论是否有异常,都会执行的代码
    print("无论是否有异常,都会执行的代码")

8.3 异常的传递

当函数或方法执行的时候,出现异常,会将异常传递给函数或方法的调用方,这就是异常的传递。如果异常传递到主程序,仍然没有进行异常处理,则程序将终止。

在实际开发中,常见做法是在主程序函数中添加异常捕获,主程序函数调用其它函数,只要出现异常,都会传递到主程序函数的异常捕获中,这样就不需要再其它函数的代码上增加大量的异常捕获。

def demo1():
    return int(input("请输入一个整数:"))


def demo2():
    return demo1()

try:
    print(demo2())
except ValueError:
    print("请输入正确的整数")
except Exception as result:
    print(f"未知错误:{result}")

8.4 抛出(raise)异常

在开发中,除了代码执行出错时,Python 解释器抛出异常外,还可以根据业务需求主动抛出异常。首先实例化一个Exception异常类的对象或继承异常类的对象;其次用关键字raise抛出这个对象

def input_password():

    # 1. 提示用户输入密码
    pwd = input("请输入密码:")

    # 2. 判断密码长度,如果长度 >= 8,返回用户输入的密码
    if len(pwd) >= 8:
        return pwd

    # 3. 密码长度不够,需要抛出异常
    # 1> 创建异常对象 - 使用异常的错误信息字符串作为参数
    ex = Exception("密码长度不够")

    # 2> 抛出异常对象
    raise ex


try:
    user_pwd = input_password()
    print(user_pwd)
except Exception as result:
    print(f"发现错误:{result}")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员buddha2080

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值