Hello World - Python
type: channel
link: https://blog.moshanghua.net/index.php/tag/Python/
items: Django CRUD操作
items: Django 模型
items: Django DTL 模板
items: Django 基础
items: 用 Python 操作 Excel 文档（基础）
items: 管理 Python 环境
items: Python基础 – 使用别人代码的模块机制
items: Python基础 – 类与对象
items: Python基础 – 递归与匿名函数
items: Python基础 – 函数的参数

Django CRUD操作
type: item
date: 2024-08-01T02:34:16+00:00
description: 在 ORM 框架中，所有模型相关的操作，比如添加/删除等，其实都是映射到数据库中一条数据的操作，因此模型操作也就是数据库表中数据的操作。首先需要创建一个模型。添加模型到数据库中。from django.db import models # Create your models here. class User(models.Model): username = models.CharField(max_length=20) password = models.CharField(max_length=100) # 表一对一,用户表和用户信息表, 常用和不常用 class UserExtension(models.Model): birthday = models.DateTimeField() university = models.CharField(max_length=200) user = models.OneToOneField("User", on_delete=models.CASCADE) class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() pub_time = models.DateTimeField(auto_now_add=True, null=True) author = models.ForeignKey( "User", on_delete=models.SET_DEFAULT, default=1, related_name="articles" ) tags = models.ManyToManyField("Tag", related_name="articles") class Tag(models.Model): name = models.CharField(max_length=100) class Comment(models.Model): content = models.TextField() origin_comment = models.ForeignKey("self", on_delete=models.CASCADE, null=True)添加一个模型实例到数据库中添加模型到数据库中，首先需要创建一个模型，创建模型的方式很简单，就跟创建普通的 Python 对象是一摸一样的。在创建完模型之后，需要调用模型的 save 方法，这样 Django 会自动的将这个模型转换成sql 语句，然后存储到数据库中。from django.shortcuts import HttpResponse def add_user(request): user = User(username="xiaoming", password="111111") # 调用save()方法：是将模型对象的数据保存到数据库表中，即在数据库表中插入一条新的记录。 user.save() return HttpResponse(f"用户 {user.username} 添加成功!")执行访问以上视图函数 add_user 就会往User这个表里面添加一条数据二次添加或者更新数据，比如创建用户时没创建UserExtension 表里的数据from django.shortcuts import HttpResponse from django.utils import timezone from .models import User, UserExtension def add_user_extension(request): # 获取已经存在的用户 try: user = User.objects.get(username="xiaoming") except User.DoesNotExist: return HttpResponse("用户 xiaoming 不存在。") # 准备要添加的扩展信息数据 birthday = "2024-08-01" university = "Example University" # 创建或更新 UserExtension 数据 user_extension, created = UserExtension.objects.get_or_create( user=user, defaults={'birthday': birthday, 'university': university} ) if not created: # UserExtension 已经存在，更新数据 user_extension.birthday =…

Django 模型
type: item
date: 2024-07-31T12:37:09+00:00
description: Django数据库MySQL驱动程序安装使用 Django 来操作 MySQL ，实际上底层还是通过 Python 来操作的。因此想要用 Django 来操作 MySQL ，首先还是需要安装一个驱动程序。在 Python3 中，驱动程序有多种选择。比如有 pymysql 以及 mysqlclient 等。这里我们就使用 mysqlclient 来操作。mysqlclient 安装非常简单pip install mysqlclient配置连接数据库在操作数据库之前，首先要连接数据库，这里以配置 MySQL 为例。Django 连接数据库，不需要单独的创建一个连接对象。只需要在 settings.py 文件中找到DATABASES字段做好数据库相关的配置就可以了。DATABASES = { "default": { # 数据库引擎（是mysql还是oracle等） "ENGINE": "django.db.backends.mysql", # 数据库的名字 "NAME": "database_django", # 连接mysql数据库的用户名 "USER": "root", # 连接mysql数据库的密码 "PASSWORD": "root", # mysql数据库的主机地址 "HOST": "127.0.0.1", # mysql数据库的端口号 "PORT": "3306", } }其中 engine 的选择还有以下：'django.db.backends.postgresql''django.db.backends.mysql''django.db.backends.sqlite3''django.db.backends.oracle'在Django中操作数据库在 Django 中操作数据库有两种方式。第一种方式就是使用原生 sql 语句操作，第二种就是使用 ORM 模型来操作。本笔记记录使用ORM 模型来操作，这里稍微记录一下原生 sql 语句操作在 Django 中使用原生 sql 语句操作其实就是使用 python db api 的接口来操作。如果你的 mysql 驱动使用的是 pymysql ，那么你就是使用 pymysql 来操作的，只不过 Django 将数据库连接的这一部分封装好了，我们只要在 settings.py 中配置好了数据库连接信息后直接使用 Django 封装好的接口就可以操作了。# 使用django封装好的connection对象，会自动读取settings.py中数据库的配置信息 from django.db import connection # 获取游标对象 cursor = connection.cursor() # 拿到游标对象后执行sql语句 cursor.execute("select * from book") # 获取所有的数据 rows = cursor.fetchall() # 遍历查询到的数据 for row in rows: print(row)以上的 execute 以及 fetchall 方法都是 Python DB API 规范中定义好的。ORM模型介绍ORM ，全称 Object Relational Mapping ，中文叫做对象关系映射，通过 ORM 我们可以通过类的方式去操作数据库，而不用再写原生的SQL语句。通过把表映射成类，把行作实例，把字段作为属性， ORM 在执行对象操作的时候最终还是会把对应的操作转换为数据库原生语句。创建ORM模型ORM 模型一般都是放在 app 的 models.py 文件中。每个 app 都可以拥有自己的模型。并且如果这个模型想要映射到数据库中，那么这个 app 必须要放在 settings.py 的 INSTALLED_APP 中进行安装。以下是写一个简单的书籍 ORM 模型。# 从Django的 django.db 模块中导入了 models 模块 # models 模块包含了用于定义各种数据库字段类型和模型的类 from django.db import models # 定义了一个名为 Book 的类，并继承自 models.Model # 继承 models.Model 表示这个类是一个Django模型，将映射到数据库中的一个表 class Book(models.Model): # 包含四个字段：name、author、pub_time 和 price name = models.CharField(max_length=20,null=False) author = models.CharField(max_length=20,null=False) pub_time = models.DateTimeField(…

Django DTL 模板
type: item
date: 2024-07-27T12:32:22+00:00
description: 目前市面上有非常多的模板系统，其中最知名最好用的就是DTL和Jinja2。 DTL 是 Django Template Language 三个单词的缩写，也就是Django自带的模板语言。当然也可以配置Django支持Jinja2等其他模板引擎，但是作为Django内置的模板语言，和Django可以达到无缝衔接而不会产生一些不兼容的情况。DTL与普通的HTML文件的区别DTL模板是一种带有特殊语法的HTML文件，这个HTML文件可以被Django编译，可以传递参数进去，实现数据动态化。在编译完成后，生成一个普通的HTML文件，然后发送给客户端。渲染模板渲染模板有多种方式。列举两种常用的方式。render_to_string ：找到模板，然后将模板编译后渲染成Python的字符串格式。最后再通过HttpResponse 类包装成一个 HttpResponse 对象返回回去。示例代码如下：from django.template.loader import render_to_string from django.http import HttpResponse def book_detail(request,book_id): html = render_to_string("detail.html") return HttpResponse(html)django还提供了一个更加简便的方式，直接将模板渲染成字符串和包装成 HttpResponse 对象一步到位完成。示例代码如下：from django.shortcuts import render def book_list(request): return render(request,'list.html')模板查找路径配置：在项目的 settings.py 文件中。有一个 TEMPLATES 配置，这个配置包含了模板引擎的配置，模板查找路径的配置，模板上下文的配置等。模板路径可以在两个地方配置。DIRS ：这是一个列表，在这个列表中可以存放所有的模板路径，以后在视图中使用 render 或者render_to_string 渲染模板的时候，会在这个列表的路径中查找模板。APP_DIRS ：默认为 True ，这个设置为 True 后，会在 INSTALLED_APPS 的安装了的 APP 下的templates 文件夹中查找模板。TEMPLATES = [ { .... # 定义存放模板的目录，这里使用 templates 目录 "DIRS": [BASE_DIR / "templates"], "APP_DIRS": True, "OPTIONS": { ... }, ] 查找顺序：比如代码 render('list.html') 。先会在 DIRS 这个列表中依次查找路径下有没有这个模板，如果有，就返回。如果 DIRS 列表中所有的路径都没有找到，那么会先检查当前这个视图所处的 app 是否已经安装，如果已经安装了，那么就先在当前这个 app 下的 templates 文件夹中查找模板，如果没有找到，那么会在其他已经安装了的 app 中查找。如果所有路径下都没有找到，那么会抛出一个 TemplateDoesNotExist 的异常。DTL模板语法变量：模板中可以包含变量， Django 在渲染模板的时候，可以传递变量对应的值过去进行替换。变量的命名规范和 Python 非常类似，只能是阿拉伯数字和英文字符以及下划线的组合，不能出现标点符号等特殊字符。变量需要通过视图函数渲染，视图函数在使用 render 或者 render_to_string 的时候可以传递一个context 的参数，这个参数是一个字典类型。以后在模板中的变量就从这个字典中读取值的。示例代码如下：# views.py代码 def profile(request): return render(request,'profile.html',context={'username':'陌上花'}) # profile.html模板代码 {{ username }} 除了变量，还可以是字典，列表以及对象。模板中的变量同样也支持 点(.) 的形式。# views.py代码 def info(request): # 1. 普通的变量 username = "悦来小陌" # 2. 字典类型 book = {"firm": "悦来集团", "name": "henry"} # 3. 列表 books = [ {"name": "全职高手", "author": "蝴蝶蓝"}, {"name": "斗破苍穹", "author": "天蚕土豆"}, ] # 4. 对象 class Person: def __init…

Django 基础
type: item
date: 2024-07-27T09:08:47+00:00
description: Django5 入门Django相关的网址Github源代码：https://github.com/django/djangoDjango官网：https://www.djangoproject.com/安装Django通过 pip install django 安装 django ，本文以 Django 5.0.3 版本进行记录。pip install django #如需要指定版本用这个命令 pip install django==5.0.3 初始化 Django 项目创建项目使用命令： django-admin startproject [项目名称] 即可创建。初始化一个新的 Django 项目，例如：django-admin startproject startdjango 创建应用（app）：一个项目类似于是一个架子，但是真正起作用的还是 app 。在终端进入到项目所在的路径，然后执行 python manage.py startapp [app名称] 创建一个app。运行Django项目进入项目，通过命令行的方式： python manage.py runserver这样可以在本地访问项目网站，默认端口号是 8000 ，在浏览器中通过 http://127.0.0.1:8000/ 来访问cd startdjango python manage.py runserver如果想要修改端口号，那么在运行的时候可以指定端口号，python manage.py runserver 9000这样就可以通过9000端口来访问python manage.py runserver 9000项目结构介绍 manage.py：以后和项目交互基本上都是基于这个文件。一般都是在终端输入python manage.py [子命令]。可以输入python manage.py help看下能做什么事情。除非你知道你自己在做什么，一般情况下不应该编辑这个文件。 settings.py：本项目的设置项，以后所有和项目相关的配置都是放在这个里面。 urls.py：这个文件是用来配置URL路由的。比如访问http://127.0.0.1/news/是访问新闻列表页，这些东西就需要在这个文件中完成。 wsgi.py：项目与WSGI工协议兼容的web服务器入口，部署的时候需要用到的，一般情况下也是不需要修改的。 project和app的关系app是django项目的组成部分。一个app代表项目中的一个模块，所有URL请求的响应都是由app来处理。比如豆瓣，里面有图书，电影，音乐，同城等许许多多的模块，如果站在django的角度来看，图书，电影这些模块就是app，图书，电影这些app共同组成豆瓣这个项目。因此这里要有一个概念，django项目由许多 app组成，一个app可以被用到其他项目，django也能拥有不同的app。通过命令：python manage.py startapp bookURL分发器一、视图：视图一般都写在 app 的 views.py 中。并且视图的第一个参数永远都是 request （一个HttpRequest）对象。这个对象存储了请求过来的所有信息，包括携带的参数以及一些头部信息等。在视图中，一般是完成逻辑相关的操作。def book_list(request): return HttpResponse("书籍列表！")视图可以是函数，也可以是类。二、URL映射：视图写完后，要与URL进行映射，即用户在浏览器中输入什么 url 的时候可以请求到这个视图函数。在用户输入了某个 url ，请求到我们的网站的时候， django 会从项目的 urls.py 文件中寻找对应的视图。在 urls.py 文件中有一个 urlpatterns 变量，以后 django 就会从这个变量中读取所有的匹配规则。匹配规则需要使用 django.urls.path 函数进行包裹，这个函数会根据传入的参数返回URLPattern 或者是 URLResolver 的对象。示例代码如下：from django.contrib import admin from django.urls import path from book import views urlpatterns = [ path('admin/', admin.site.urls), path('book/',views.book_list) ]URL中添加参数：有时候， url 中包含了一些参数需要动态调整。比如博客某篇文章的详情页的url，是https://moshanghua.net/details/3276 后面的 3276 就是这篇文章的 id ，那么文章详情页面的url就可以写成 ht…

用 Python 操作 Excel 文档（基础）
type: item
date: 2024-06-30T14:48:26+00:00
description: Excel表格的基本结构一个Excel表格文件，又叫做一个工作簿（Workbook）。一个工作簿中包含一个或多个工作表（Worksheet）。在工作薄页面的左下方可以进行工作表的切换和增删。一个工作表由单元格（Cell）组成。Excel的数据存储在单元格中。我们可以通过列号（Column）和行号（Row）对单元格进行定位。行号默认从数字1开始，并依次递增。列号默认从字母A开始，依次递增。超过字母Z后，以AA，AB的方式继续计数。至此，就是Excel表格的基本结构，总结如图所示。openpyxl 模块要使用Python对Excel表格进行读取，我们需要安装一个用于读取数据的工具 openpyxl 。openpyxl 是一个用于读、写Excel文件的开源模块。Excel表格读取读取工作簿读取指定路径的工作簿需要使用函数：openpyxl.load_workbook()openpyxl.load_workbook()函数读取成功后，会返回一个工作簿对象，本例中将这个对象赋值给了变量wb。# 导入openpyxl模块 import openpyxl #读取工作目录里名为"2019年1月销售订单.xlsx"的工作簿并赋值给变量wb wb = openpyxl.load_workbook("2019年1月销售订单.xlsx") 读取指定工作表如果事先不知道工作簿内有哪些工作表，可以通过访问工作簿的 .sheetnames 属性来获取一个包含所有工作表名称的列表。具体操作为在变量wb之后添加代码 .sheetnames 。import openpyxl wb = openpyxl.load_workbook("2019年1月销售订单.xlsx") # 使用print输出工作簿中所有的工作表名称 print(wb.sheetnames) # ['销售商品', '销售订单数据'] # 通过工作簿对象wb获取名为“销售商品”的工作表对象， orderSheet = wb["销售商品"] 读取指定单元格要获取工作表中指定的单元格对象，我们可以通过在中括号 [ ] 内填入列号和行号的方式去获取。单元格对象除了包含具体的值，还包含相关的函数和属性。要访问单元格里的值，可以在单元格对象后加一个 .valueimport openpyxl wb = openpyxl.load_workbook("sample.xlsx") print(wb.sheetnames) # ['sheet1', 'sheet2'] orderSheet = wb["销售商品"] # 使用print输出 orderSheet 的C5单元格对象 print (orderSheet["C5"]) # < Cell '销售商品'.C5 > # 使用 orderSheet["C5"].value 输出orderSheet的C5单元格的值 print(orderSheet["C5"].value) 若单元格中包含公式，现有方式读取出的值是公式本身。若需要读取公式计算后的值，要在读取工作簿的代码部分，传入一个参数： data_only=True ，便可以得出公式计算后的值了。# 导入openpyxl模块 import openpyxl # 原打开方式，直接读取公式本身 wb = openpyxl.load_workbook("2019年1月销售订单.xlsx") orderSheet = wb["销售订单数据"] # 输出公式本身 print(orderSheet["I3"].value) # 添加data_only=True打开工作簿，获取公式计算后的值 wb2 = openpyxl.load_workbook("2019年1月销售订单.xlsx", data_only=True) orderSheet2 = wb2["销售订单数据"] # 输出公式计算后的值 print(orderSheet2["I3"].value)工作表行数据的遍历要对整个工作表的每一行数据进行浏览查询，可以使用for循环对工作表对象的行属性（rows）进行遍历。具体代码为 for rowData in orderSheet.rows这样程序就会以从上到下的顺序，逐个获取到“销售订单数据”工作表内的每一行数据，读取出的每一行数据是由单元格对象组成的元组。import openpyxl wb = openpyxl.load_workbook("2019年1月销售订单.xlsx", data_only=True) orderSheet = wb["销售订单数据"] # 遍历工作表的所有行数据 for rowData in orderSheet.rows: # 输出行数据 print(rowData) # (<Cell '…

管理 Python 环境
type: item
date: 2024-06-22T14:07:00+00:00
description: pyenv 来管理 Python 版本pyenv 是一个强大 Python 包管理工具，可以灵活地切换各种 Python 版本，使用 pyenv 来管理我们的 Python 版本，优雅高效且不会破坏掉系统自带的 Python 环境：macOS 安装 pyenv➜ brew install pyenv接着为 pyenv 配置 shell 环境，提高工作效率，可自动联想 Tab 补全我们本地安装的 Python 版本：echo 'eval "$(pyenv init -)"' >> ~/.zshrcpyenv 安装 Python# 查看已经安装的Python版本 ➜ pyenv versions # 查看当前的 Python 版本 ➜ pyenv version # 查看可安装的版本 ➜ pyenv install -l # 安装与卸载 pypy3.8-7.3.11 ➜ pyenv install pypy3.8-7.3.11 ➜ pyenv uninstall pypy3.8-7.3.11版本切换确实很方便，所安装的版本都在 ~/.pyenv/versions 目录下：# global 全局设置 一般不建议改变全局设置 ➜ pyenv global <python版本> # shell 会话设置 只影响当前的shell会话 ➜ pyenv shell <python版本> # 取消 shell 会话的设置 ➜ pyenv shell --unset # local 本地设置 只影响所在文件夹 ➜ pyenv local <python版本>pyenv 的 global、local、shell 的优先级关系是：shell > local > globalPython 的 pip 管理工具pipenv 是一个强大的工具，用于简化 Python 项目中的依赖管理和虚拟环境管理。以下是一些常见的 pipenv 用法示例：更多关于 pipenv 的信息，可以查看它的官方文档： pipenv 官方文档 安装 pipenv首先，你需要确保已经安装了 pipenv。你可以通过以下命令安装它：pip install pipenv创建和管理虚拟环境创建一个新项目并初始化 **pipenv** 环境：mkdir my_project cd my_project pipenv install安装一个新的包pipenv 会自动创建一个虚拟环境（如果还没有创建），并将包安装到该虚拟环境中。pipenv install requests安装一个开发依赖包：开发依赖包只在开发环境中需要，比如测试工具。pipenv install --dev pytest卸载一个包：pipenv uninstall requests激活虚拟环境：激活虚拟环境后，你可以在其中运行 Python 命令和脚本。pipenv shell要退出虚拟环境，使用 exit 命令。运行脚本而不激活虚拟环境：如果你不想手动激活虚拟环境，可以使用以下命令直接在虚拟环境中运行脚本。pipenv run python your_script.py管理依赖文件生成 Pipfile.lock： Pipfile.lock 文件记录了所有包的精确版本，保证项目的一致性。pipenv lock安装 Pipfile 中的所有依赖： 如果你克隆了一个包含 Pipfile 的项目，可以使用以下命令安装所有依赖。pipenv install检查包的安全性： pipenv 提供了一个方便的命令来检查已安装的包是否有已知的安全漏洞。pipenv check其他有用的命令查看已安装包列表：pipenv graph更新包：pipenv update requests或更新所有包：pipenv update清理未使用的包：pipenv clean查看虚拟环境路径：pipenv --venv查看 Python 解释器路径：pipenv --py这些命令和用法应该可以帮助你更有效地管理 Python 项目的依赖和虚拟环境。如果你需要更多信息和详细的用法，可以查看 pipenv 的官方文档。例如：# 安装 pipenv pip install pipenv mkdir my_project cd my_project # 初始化 pipenv 环境 pipenv install # 安装模块 openpyxl pipenv install openpyxl # 激活虚拟环境，运行python，使用 exit 命令退出环境 pipenv shell # 直接在虚拟环境中运行脚本 pipenv run python your_script.py

Python基础 – 使用别人代码的模块机制
type: item
date: 2022-08-13T22:06:21+00:00
description: Python的模块为日常编程中许多问题提供了标准的解决方案，同时也能让我们更加简洁优雅地管理代码。模块定义： 每个模块是由1个或多个Python文件构成。是相关的类、函数和变量所组成的一个集合。它可以被其它代码引入并直接使用。通常，一个模块中的各个功能是相互关联的。模块中的函数就像是积木，用一块一块的积木搭建成一个完整的图形，搭好的图形就是模块。 了解完模块的基本概念后，先来看看最常接触的第一大类模块：内置模块。内置模块是在安装Python时自带的模块。Python提供了大量丰富且高质量的内置模块来帮助完成一些系统化工作。比如，生成一个随机的数字可以使用random模块，要处理日期和时间则可以通过datetime模块等。为了使用这些模块，首先需要通过关键词import来导入模块。导入模块（I）import random randomNum = random.random() print(randomNum)代码的作用 这三行代码输出了一个随机数。第一行导入了random模块，该模块用于生成随机数； 第二行将生成的随机数赋值给了变量randomNum； 第三行输出了randomNum这个变量的数值。import 关键字import，中文意思是“导入”，表明我们要在这里导入模块。 模块的名称 一个名为random的模块，该模块用于生成一个随机数。 模块内的函数 导入random模块后，就可以通过 random.xxx() 来使用该模块中的所有函数。这里，我们调用了random模块里的random()函数，该函数用于生成一个0到1的随机浮点数。 模块内的函数 random模块中还有其它的函数，可以根据自己的需要来调用。比如，想生成一个在1到7之间的随机整数，可以使用random模块里的randint()函数，代码为：random.randint(1,7)。 代码小结 要导入模块时，就可以使用这样的格式： 使用import导入模块后，除了可以获取到模块内的函数，还可以获取到该模块中的类。通过调用类里面的方法，来实现某一功能。比如，要获取今天的日期，就需要用到datetime模块里的date类，以及该类中的today()方法。import datetime todayDate = datetime.date.today() print(todayDate)导入模块 使用关键字import，中文意思是“导入”，表明我们要在这里导入一个名称为datetime的模块。 模块中的一个类 一个类，表明我们在调用datetime模块里的date类。date类是一个日期类，里面提供了一些关于日期的方法与属性。 date类里面的某一个方法 一个方法，表明我们要调用的today()从属于date类。该方法用于获取当前的本地日期。 代码小结 导入模块后，想获取到该模块中的类里面的某一个方法时，就可以使用这样的格式： 小练习使用import导入random模块。使用该模块下的random()函数，生成一个0到1之间的随机浮点数，并使用print()将结果输出。import random print(random.random())获取今天日期的年份，并判断跟实际今年的年份（2022）是否相等。相等输出True，不相等输出False。import datetime today = datetime.date.today() year = today.year print(year == 2022)不难看出，一个模块是由很多类和函数组成的。有时候只想导入（import）模块里面的一部分内容，可能是一个类或是一个函数。 比如，我们只希望导入datetime模块中的date类。这时候，就可以用到 from...import... 。导入模块（II）from datetime import date todayDate = date.today() print(todayDate)两个关键字 第一个关键字from允许我们从模块中导入一个指定的部分。这两个关键字，表明从datetime模块里导入date类。 模块的名称 一个名为datetime的模块，表示要从该模块中导入某个类。 一个类 一个类，表明我们要调用的date类属于datetime模块。 date类里面的某一个方法 一个方法，表明我们要调用的today()从属于date类。可以看到，使用from...import...这种形式时，调用datetime模块中的类或函数时不需要datetime.前缀。 代码小结 当我们只想导入模块里面的一部分内容时，就可以使用这样的格式： 第三方模块学习了导入模块的两种方式，但是导入的都是内置模块。这些模块是Python自带的，具有较高的通用性。除此之外，我们还会接触到许多的第三…

Python基础 – 类与对象
type: item
date: 2022-08-13T20:13:28+00:00
description: 在生活中，我们通过特征与功能来描述一个具体对象，转换到代码中就变成了数据与函数。 回顾已经学过的内容，我们学习了用来存储数据的变量与用来存储代码的函数。 现在让我们把变量与函数打包，来学习在程序中创建类与对象。类代表着一类事物，比如人类，鸟类，汽车，电脑。当我们提起这些事物的时候，我们并不特指某一个具体的东西，比如人类是泛指抽象的全人类而对象指的是类的实例，比如人类的对象是某个具体的人，如张三，李四，tony和kevin。类与对象类代表一些拥有相同特性与功能的事物，如鸟类，人类，猫类等。类中的某一个具体实例称为这个类的实例对象，简称为对象。若请你介绍一下自己的手机，你会如何去做？ 你可以通过颜色、型号、容量大小，屏幕尺寸等数据来描述它的特征； 也可以用拍照、安装应用、打电话等操作来描述它的功能。 我们可以把拥有上述特性的设备都归类于手机，即手机就是一个类。手机的特征称为这个类的属性，手机的功能称为这个类的方法。属性与方法定义： 属性用来描述这个类的一些特征，如品牌，颜色，型号是手机的属性。方法用来表现这个类的一些功能，如拍照，打电话等是手机的方法。在Python中通过class关键字来创建一个类。 为了方便理解，接下来在程序中定义一个手机类。 并为手机设定两个方法：打电话，发短信。 类的定义class Phone(): def makeCall(self, who): return f"正在拨打电话给{who}" def sendMsg(self, who, txt): return f"正在发送短信给{who}, 内容为{txt}"代码的作用 用class定义一个类，并命名为Phone。第2～6行，为该类添加了打电话和发短信两个功能。即定义了两个方法makeCall与sendMsg。第2，3行，makeCall方法接收联系人的名字为参数，并将文字格式化输出。第5，6行，sendMsg方法接收联系人的名字与短信内容为参数，并将文字格式化输出。关键字 class，在程序中定义类的关键字。 类名 一串文字，为类定义的名称。 为了区分类与函数，类的名称首字母建议大写。 括号 一对括号，定义类的标准写法。 : 一个冒号，表明接下来缩进的代码是属于这个类的。 四个空格 一个缩进，表示该代码块属于Phone这个类。 方法名 类中的两个特殊函数，称为方法。 方法又被称为成员函数，用来表现这个类的一些功能。成员函数的第一个参数为self。 特殊的参数 self参数，由程序自动传入的参数，指调用该方法的对象。第一个参数为self，是定义实例方法的固定写法。 代码小结 当我们要定义一个类时就需要这几个部分 类是抽象的，我们要使用类，就需要实例化一个对象。对象是以类为模板创建的。这个过程类似于以人类的共同特性为模板，创造一个特定的人。 可以这样说，你就是人类的一个实例对象。 接下来学习一下如何通过类来实例一个具体的对象。 用Phone类来实例化两个对象表示我的手机与你的手机。 实例化对象class Phone(): def makeCall(self, who): return f"正在拨打电话给{who}" def sendMsg(self, who, txt): return f"正在发送短信给{who}, 内容为{txt}" myPhone = Phone() yourPhone = Phone() ret = myPhone.makeCall("Tony") print(ret) ret2 = yourPhone.sendMsg("Jeremy", "中午吃啥？") print(ret2)代码的作用 将刚才定义好的Phone类拿过来，并实例化两个对象myPhone与yourPhone。第9，10行，创建Phone的对象myPhone与yourPhone。第12行，调用myPhone的方法makeCall，把结果存储到ret中。第14行，调用yourPhone的方法sendMsg，把结果存储到ret2。对象名 一个变量名，为对象设定的名称。 类名 定义好的类名。 括号 括号，表示调用Phone类实例化一个对象。 对象 对象名称，用对象名调用指定的方法。 句点 一个句点【.】。用句点连接对象名与对象的方法，称为句点表示法。例如第11行，表示myPhone使用了他的方法(功能)makeCall（打电话）。 方法名 方法名，对象要调用的方法名称。 实参 调用方法时传递的实参。调用对象的方法时，不需要为self参数传递实参。这里，第11行的“Tony”实参传递给makeCall的“who”形参。第13行的“Jeremy”实参传递给sendMsg的“who”形参，“中午吃啥”传递给sendMsg的“txt”形参。 代码小结 当我们要实例化对象时就需要这…

Python基础 – 递归与匿名函数
type: item
date: 2022-08-12T03:42:52+00:00
description: 在 Python 中，我们可以使用【def 函数名(参数):】的方式定义函数。如果我们把 def 定义的函数看作“有名字函数”，那么还有一类函数，其不需要显示定义函数名。这就是匿名函数。匿名函数匿名函数是一种不需要为函数命名的函数定义方式，以 lambda 关键字开头。 匿名函数之所以叫匿名函数，是因为它没有函数名称。 本例中，我们是把一个匿名函数赋值给了变量 square，该变量就可以调用函数。 匿名函数的结构square = lambda x:x*x result = square(9) print(result) multiply = lambda x,y:x*y newResult = multiply(9,10) print(newResult)代码的作用 这两段代码创建两个匿名函数，并且使用变量调用，传入参数，输出了结果。lambda 一个关键字 lambda，用来创建匿名函数。 空格 一个空格，固定格式，关键字 lambda 和具体计算式之间的空格。 参数 这个位置表示该匿名函数的参数，为形参。 如果传入多个参数，需要使用“逗号”隔开。 冒号: 一个冒号：，是“匿名函数”的固定格式，冒号后面是具体如何计算冒号前面的输入数值。 表达式 冒号后面是函数的返回值，注意这里不需使用 return 关键字。 变量 将匿名函数赋给一个变量，再由该变量来调用函数。 调用函数 匿名函数同样需要被调用才能执行，调用仍然使用 ( ) 传参的方式实现。 变量 变量，这个变量会“接受”匿名函数返回出来的值。 代码小结 当要定义匿名函数时，可以使用这样的格式 小练习幂 定义一个“匿名函数”，它的功能是计算一个输入值的3次幂，将匿名函数赋值给变量power，然后输入一个数值 5，并输出计算结果。power = lambda number:number*number*number print(power(5))立方体体积 定义一个“匿名函数”，它的功能是计算立方体的体积，其公式为：长宽高，将匿名函数赋值给变量 area。然后传入参数10, 8, 6，并输出计算结果。area = lambda length,width,height:length*width*height print(area(10, 8, 6))匿名函数使用起来比较方便，但是它也有局限性。 lambda 的主体是一个表达式，而不是一个代码块，不适合处理复杂的逻辑情况。 我们在创建函数时，如果需要处理较为复杂的逻辑，建议使用 def 创建函数，如本例所示，计算列表各元素的累加。 在之前的学习中，都是先定义函数以后，在代码的其他地方调用这个函数。 其实，在函数的内部还可以调用自己，这种调用自己函数就是递归函数。 递归一段程序调用自身的过程我们叫做递归，多见于函数调用函数自身。当两面镜子相互之间近似平行时，镜中嵌套的图像是以无限递归的形式出现的。也可以理解为自我复制的过程 语言例子 如果我们用语言的形式表示递归的话，这个通俗的故事最能体现：从前有座山，山里有座庙，庙里有个老和尚，正在给小和尚讲故事呢！故事是什么呢？“从前有座山，山里有座庙，庙里有个老和尚，正在给小和尚讲故事呢！故事是什么呢？‘从前有座山，山里有座庙，庙里有个老和尚，正在给小和尚讲故事呢！故事是什么呢？…… 接下来，就在案例中，学习递归的使用方法和其中的程序运行逻辑。 递归递归概念比较抽象，我们来一起梳理下。假设创建一个递归函数，用于计算数字累加，传入数字 5 ，计算 5 以内的数字累加。 5+4+3+2+1+0 由于 5 大于 0，程序不会执行函数中 if 判断的代码块，而是返回 5 + sum(4)。 这里的 sum(4) 又是一次 sum() 函数的调用，程序就会返回 4 + sum(3)。 程序就一直调用自己，直到 sum(0)，因为 if 语句的存在，它不需要等待 sum(0) 的计算了，而是直接给出结果 0。 然后程序一路返回，回到最初的 sum(5)，并给出最终的答案：5+4+3+2+1+0 = 15 递归函数会终止么？在递归函数中，if 判断就是终止条件，在本例中当 n 小于等于 0，就返回 0 ，递归就终止了。 如果不加这个终止条件会无休止的递归下去，最终造成程序报错。 类似的，我们要算一个数的阶乘，一个正整数的阶乘是所有小于及等于该数的正整数的积，例如 5! = 5×4×3×2×1我们可以用图中的代码，当 n > 0 的时候，函数会调用它本身，直到 n <= 0。 小练习200以内求和 写一个递归函数可以实现 200 以内的整数和。将函数名命名为 sum，传入参数为 n。# 定义名为sum()函数，传入参数n def sum(n): # 如果n小于等于0 if n <= 0: # 返回0 retu…

Python基础 – 函数的参数
type: item
date: 2022-08-11T04:32:55+00:00
description: 必选参数函数的一种参数类型，在调用这个函数的时候必须传入数据的参数。 传递实参时的顺序在传递必选参数时，形参会按照定义的顺序依次接收数据。调用函数时第一个参数传递给name，第二个参数传递给pet。 缺少实参在调用函数时，缺少或超出对必选参数的传递会导致程序错误。也就是说，在函数中定义了多少个必选参数就要传递多少个实参。 关键字传递当我们忘记了传递顺序时，可以利用“形参名=实参名”的方式传递实参。这样以关键字传递实参的形式，简称为关键字实参。 小练习定义一个函数getArea，设定参数width与height分别接收矩形的宽高，计算矩形的面积并返回。调用该函数，用关键字的形式传递参数宽为5、高为3，并按照“矩形的面积为xx”的格式输出结果。def getArea(width, height): return width*height ret = getArea(width=5, height=3) print(f"矩形的面积为{ret}")若定义一个计算圆形面积的函数，设定参数为半径（radius）与圆周率（pi）。多数情况下，圆周率都会近似为3.14。若pi不是必选参数，设其默认为3.14。只在需要修改圆周率时传递数据，函数调用起来会方便很多。 必选参数定义起来虽然简单，在调用函数时经常会因为缺少实参造成程序错误。接下来学习给形参设置默认值。默认值参数def getArea(radius, pi=3.14): ret = radius * radius * pi return ret ret1 = getArea(2) print(ret1) ret2 = getArea(2, 3.14159) print(ret2)代码的作用定义一个函数getArea，根据传递的半径与圆周率，计算圆的面积并输出。在第1行，定义形参radius与pi，并为pi设定默认值为3.14。在第5行，调用函数getArea，并传递数据2。在第7行，调用函数getArea，并传递数据2与3.14159。关键字一个关键字，def是函数定义的关键字，是define的缩写。括号 括号与冒号，这是函数定义的固定格式。逗号 一个逗号，用来分割多个参数。 必选参数 一串字母radius，必选参数。必选参数要定义在默认值参数之前。 默认参数 一串字母pi，默认值参数。默认参数可以有任意个，但必须定义在必选参数之后（若必选参数存在）。 等号 一个等号，赋值符号。默认值 一组数据，为参数pi设置默认值。若在调用函数时，没有为参数pi传递实参，参数pi默认为3.14。传递一个实参 调用函数，只为必选参数传递整数2。因为pi没有接收到参数，所以pi将使用默认值3.14。传递两个实参 调用函数，传递参数2与3.14159。此时pi接收到的实参数据3.14159会覆盖默认值3.14。 代码小结 当我们定义一个默认值参数时就需要这几个部分 目前学习了两种类型的参数，必选参数与默认值参数。这两种参数形式涵盖了80%以上的函数使用。 在定义不同的参数时，需要注意避免一些常见的错误。1.定义参数的顺序在定义函数时，定义形参的顺序是：1，必选参数；2，默认参数。 当有必选参数和默认参数的时候，必选参数必须写在默认参数的前面，否则程序会出错。 2.参数名避免使用无意义的字母在传递实参给函数时，若忘记定义顺序可以使用“形参名=实参”的方式。 但如果定义的形参名是诸如a，abc这样无意义的名字，会减少代码可读性，容易混淆。 所以设定参数名时，尽量使用有意义的名称。 最后，对这两种参数的差异性做一个总结。