1.背景介绍 1. 背景介绍 电商数据分析是一项非常重要的技能,它可以帮助企业了解消费者行为、优化商品推荐、提高销售额等。随着数据规模的增加,传统的数据处理方法已经无法满足需求。因此,需要一种高效、可扩展的大数据处理框架来处理这些复杂的数据。
Apache Spark是一个开源的大数据处理框架,它可以处理大量数据并提供高性能的数据分析能力。Spark的核心组件是Spark Streaming、Spark SQL、MLlib和GraphX等。在本文中,我们将主要关注Spark Streaming和Spark SQL两个组件,并通过一个电商数据分析的实例来展示Spark的强大功能。
2. 核心概念与联系 在进入具体的实例之前,我们需要了解一下Spark的核心概念和联系。
2.1 Spark Streaming Spark Streaming是Spark中用于处理流式数据的组件。它可以将流式数据转换为RDD(Resilient Distributed Dataset),并利用Spark的强大功能进行实时分析。Spark Streaming支持多种数据源,如Kafka、Flume、Twitter等,并可以将分析结果输出到多种目的地,如HDFS、Kafka、Elasticsearch等。
2.2 Spark SQL Spark SQL是Spark中用于处理结构化数据的组件。它可以将结构化数据转换为DataFrame,并利用Spark的强大功能进行数据分析。Spark SQL支持多种数据源,如HDFS、Hive、Parquet等,并可以将分析结果输出到多种目的地,如HDFS、Kafka、Elasticsearch等。
2.3 联系 Spark Streaming和Spark SQL之间的联系是:它们都是Spark的核心组件,并可以共同完成大数据处理和分析任务。在实际应用中,我们可以将Spark Streaming用于处理流式数据,并将分析结果存储到HDFS中。然后,我们可以使用Spark SQL对存储在HDFS中的结构化数据进行进一步的分析。
3. 核心算法原理和具体操作步骤以及数学模型公式详细讲解 在本节中,我们将详细讲解Spark Streaming和Spark SQL的核心算法原理、具体操作步骤以及数学模型公式。
3.1 Spark Streaming Spark Streaming的核心算法原理是基于RDD的微批处理。它将流式数据划分为一系列的微批次,并将每个微批次转换为RDD。然后,Spark Streaming可以利用Spark的强大功能对RDD进行操作,如转换、聚合、连接等。最后,Spark Streaming将结果输出到目的地。
具体操作步骤如下:
创建一个Spark Streaming的Context对象。设置数据源和目的地。定义一个函数,用于对数据进行处理。创建一个DStream(Discretized Stream)对象,用于表示流式数据。注册一个函数,用于对DStream进行操作。启动Spark Streaming的计算任务。关闭Spark Streaming的计算任务。 数学模型公式详细讲解:
Spark Streaming的核心算法原理是基于RDD的微批处理。在这种模型中,数据被划分为一系列的微批次,每个微批次包含一定数量的数据。然后,Spark Streaming将每个微批次转换为RDD,并对RDD进行操作。最后,Spark Streaming将结果输出到目的地。
3.2 Spark SQL Spark SQL的核心算法原理是基于DataFrame的查询优化。它将结构化数据转换为DataFrame,并利用Spark的强大功能对DataFrame进行查询和分析。Spark SQL支持多种查询语言,如SQL、Python、Scala等。
具体操作步骤如下:
创建一个Spark SQL的Context对象。设置数据源和目的地。定义一个查询语句。执行查询语句。获取查询结果。 数学模型公式详细讲解:
Spark SQL的核心算法原理是基于DataFrame的查询优化。在这种模型中,数据被转换为DataFrame,并对DataFrame进行查询和分析。Spark SQL支持多种查询语言,如SQL、Python、Scala等。
Android ORM 框架之 greenDAO 官网地址GitHub地址greenDAO 描述greenDAO 特点greenDAO 核心类DaoMasterDaoSessionDAO实体 使用 greenDAO将 greenDAO 插件添加到项目中创建实体实体常用注解 初始化 DaoSession操作数据(CRUD) 官网地址 GitHub地址 greenDAO 描述 greenDAO 是一个轻量且快速的 Android ORM,可将对象映射到 SQLite 数据库,
greenDAO 针对 Android 进行了高度优化,可提供出色的性能并消耗最少的内存。
ORM: 对象关系映射,是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。是一个可在编程语言里使用的——“虚拟对象数据库”。
greenDAO 特点 体积小:小于100KB,以保持较低的构建时间并避免65k方法限制简单:简洁直接易于使用的API,V3带注释高性能:可能是 Android 最快的 ORM,由智能代码生成驱动强大的联接:跨实体查询,甚至对复杂关系进行链式联接灵活的属性类型:使用自定义类或枚举来表示实体中的数据数据库加密:greenDAO支持SQLCipher来保证用户数据的安全安全且富有表现力的查询 API:QueryBuilder 使用属性常量来避免拼写错误稳定:greenDAO 自 2011 年以来一直存在并被无数著名应用程序使用(GitHub 12k+ stars) greenDAO 核心类 DaoMaster 官方释义:使用 greenDAO 的入口点。DaoMaster 持有数据库对象(SQLiteDatabase)并管理特定模式的 DAO 类(而不是对象)。它有静态方法来创建或删除表。它的内部类 OpenHelper 和 DevOpenHelper 是 SQLiteOpenHelper 实现,用于在 SQLite 数据库中创建架构。我的理解:创建数据库的框架。DaoMaster 做了createAllTables dropAllTables的操作;其内部类 OpenHelper 初始化时调用了 DaoMaster 的 createAllTables 方法、内部类 DevOpenHelper 在数据库升级时调用了 DaoMaster 的 dropAllTables 方法; DaoSession 官方释义:管理特定模式的所有可用 DAO 对象,您可以使用其中一种 getter 方法获取这些对象。DaoSession 还提供了一些通用的持久化方法,如实体的插入、加载、更新、刷新和删除。最后,DaoSession 对象还跟踪身份范围。我的理解:获取各个实体对应的 DAO 对象、操作具体的 DAO 对象(初始化、注册、清除缓存数据(GreenDao默认开启了缓存)); DAO 官方释义:数据访问对象(DAO)持续存在并查询实体。对于每个实体,greenDAO 都会生成一个 DAO。它比 DaoSession 有更多的持久化方法,例如:count、loadAll 和 insertInTx。我的理解:对应实际生成的实体类。Dao 类中包含了 实体的属性以及 queryBuilde 的引用列名、createTable 时的SQL语句、dropTable 时的SQL语句、get 实体属性值到语句、将光标当前位置值 set 到实体属性中,有更多的方法来操作数据库元素; 实体 官方释义:持久化对象。通常,实体是使用标准 Java 属性(如 POJO 或 JavaBean)表示数据库行的对象。我的理解:就是使用了 @Entity 注解的类对象; 使用 greenDAO 将 greenDAO 插件添加到项目中 将以下 gradle 配置添加到 Android 项目的根 build.
动态规划3.0 动态规划 - - - 简单多状态 dp 问题1. 按摩师(打家劫舍Ⅰ的变形)2. 打家劫舍Ⅱ3. 删除并获得点数4. 粉刷房子5. 买卖股票的最佳时机含冷冻期6. 买卖股票的最佳时机含手续费7. 买卖股票的最佳时机Ⅲ8. 买卖股票的最佳时机Ⅳ 动态规划 - - - 简单多状态 dp 问题 1. 按摩师(打家劫舍Ⅰ的变形) 题目链接 -> Leetcode -面试题 17.16.按摩师
Leetcode -面试题 17.16.按摩师
题目:一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。
在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
注意:本题相对原题稍作改动
示例 1:
输入:[1, 2, 3, 1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。
示例 2:
输入:[2, 7, 9, 3, 1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。
前端vue2中axios封装请求数据,教会你封装教会你请求数据 简单易懂,轻松学会axios封装请求数据 看一眼就会 手把手教会 1、在完成下面的步骤之前,先脚手架创建vue项目,然后再vue项目当中,首先先创建一个文件夹utils,里面放request.js的文件 (1)下载 npm i axios先下载好axios请求依赖 (2)下面的这个文件,包括封装请求,以及拦截器,还有设置了请求头(里面的代码需要根据自己个人需求修改) import axios from "axios"; // 封装axios构造函数请求 // 1.先是自定义一个方法名 // 2.然后获取头部token值 // 3.延长器设不设置都可以 const instance = axios.create({ baseURL: 'http://localhost:8081/wx', headers: { // X-Litemall-Token这个名称就固定这个 'X-Litemall-Token' : localStorage.getItem("X-Litemall-Token") } }) // 请求拦截器 // 1.请求拦截器,在发请求之前,请求拦截器可以检测到发起请求之前需要做什么事情,把需要做的事情,放在请求拦截器之前 axios.interceptors.request.use(config => { // 1.这里我设置了,在请求之前,先开始进度条的动画 // 2.返回请求数据 if(localStorage.setItem['X-Litemall-Token'] !== null ) { console.headers.common['X-Litemall-Token'] = localStorage.getItem('X-Litemall-Token') } return config }) // 响应拦截器 // 1.相应上面的请求拦截器的需求 // 2.把上面的请求拦截器的需求全部做到 axios.interceptors.response.use(res => { return res.
目录
一、touchstart:当手指触摸屏幕时触发。
二、touchmove:当手指在屏幕上滑动时触发。
三、touchend:当手指离开屏幕时触发。
四、touchcancel:当触摸事件被取消时触发,例如突然有来电等中断触摸的情况。
五、touchenter:当手指触摸到元素边界时触发。
六、touchleave:当手指离开元素边界时触发。
JavaScript触摸事件是通过浏览器提供的Touch API来实现的。当用户在触摸屏设备上进行交互时,浏览器会捕捉到触摸事件,并将其传递给相应的JavaScript事件处理器。
需要注意的是,触摸事件在不同的设备和浏览器上可能有差异,因此在使用触摸事件时应该进行兼容性测试,并根据需要进行适当的兼容性处理。此外,触摸事件通常与其他事件(如点击事件、滚动事件等)结合使用,以实现更复杂的交互效果。
一、touchstart:当手指触摸屏幕时触发。 touchstart事件在用户触摸屏幕时触发,可以用于实现各种触摸交互效果。以下是一个简单的例子
<!DOCTYPE html> <html> <head> <title>触摸事件示例</title> <style> #touchDiv { width: 200px; height: 200px; background-color: green; color: white; text-align: center; line-height: 200px; cursor: pointer; } </style> </head> <body> <div id="touchDiv">点击触摸</div> <script> document.addEventListener('DOMContentLoaded', function() { const touchDiv = document.getElementById('touchDiv'); touchDiv.addEventListener('touchstart', function(event) { // 当用户触摸元素时,更改其背景颜色和文本内容 touchDiv.style.backgroundColor = 'red'; touchDiv.textContent = '已触摸'; }); }); </script> </body> </html> 在这个示例中,我们有一个HTML文档,其中包含一个id为touchDiv的<div>元素。CSS样式定义了元素的外观。JavaScript代码直接嵌入在HTML文件中,在DOMContentLoaded事件中添加了一个touchstart事件监听器。当用户触摸touchDiv元素时,触发事件处理函数,将元素的背景颜色更改为红色,并更新文本内容为"已触摸"。
将HTML代码保存为HTML文件(例如index.html),然后在Web浏览器中打开该文件。您应该看到一个具有绿色背景的"点击触摸"元素。当您触摸它时,元素的外观将根据事件处理函数中指定的更改而改变。
二、touchmove:当手指在屏幕上滑动时触发。 当触摸设备上的手指在屏幕上移动时,会触发touchmove事件。这个事件常用于实现触摸滑动、拖拽等交互效果。以下是一个简单的例子:
<!DOCTYPE html> <html> <head> <title>触摸移动事件示例</title> <style> #touchDiv { width: 200px; height: 200px; background-color: green; color: white; text-align: center; line-height: 200px; cursor: pointer; } </style> </head> <body> <div id="
【1】 安装homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 根据提示选择不同的源即可安装
【2】此时使用nvm -v提示如下 输入下面命令查看提示
brew info nvm 需要2步:
1)创建工作空间
mkdir ~/.nvm 2)使用vim更改文件
vi ~/.zshrc 3)按下 “ i ”进入insert模式 4)在空白处粘贴刚刚提示的内容,我的环境有conda从<<< conda initialize >>>下面开始粘贴
5)按下ESC退出insert模式,输入 :wq 后回车退出VIM 记得有个冒号
6) 刷新
source ~/.zshrc 【3】可以使用nvm 了 安装 Node.js:
nvm install <version> 安装指定版本的 Node.js。例如,要安装 Node.js 14,可以运行:
nvm install 14 切换 Node.js 版本:
nvm use <version> 切换到指定版本的 Node.js。例如:
nvm use 14 设置默认 Node.js 版本:
nvm alias default <version> 设置默认使用的 Node.
引言 当我初次接触数据分析三剑客(numpy、pandas、matplotlib)时,感觉每个库的功能都很多很杂,所以在差不多理清了各模块功能后便相继推出了各自教程(文末附链接);后来,当接触了机器学习库sklearn之后,才发现三剑客也不外如是,相比sklearn简直是小巫见大巫。
sklearn库功能强大API众多,本文仅对其中的各子模块进行梳理和介绍,以期通过本文能对sklearn迅速建立宏观框架。
01 sklearn简介 sklearn,全称scikit-learn,是python中的机器学习库,建立在numpy、scipy、matplotlib等数据科学包的基础之上,涵盖了机器学习中的样例数据、数据预处理、模型验证、特征选择、分类、回归、聚类、降维等几乎所有环节,功能十分强大。与深度学习库存在pytorch、TensorFlow等多种框架可选不同,sklearn是python中传统机器学习的首选库,不存在其他竞争者。
本文将分别围绕下图中各大子模块进行分别介绍,不会面面俱到、但求提纲挈领。
02 样例数据集 sklearn为初学者提供了一些经典数据集,通过这些数据集可快速搭建机器学习任务、对比模型性能。数据集主要围绕分类和回归两类经典任务,对于不同需求,常用数据集简介如下:
load_breast_cancer:乳腺癌数据集,特征为连续数值变量,标签为0或1的二分类任务
load_iris:经典鸢尾花数据集,特征为连续数值变量,标签为0/1/2的三分类任务,且各类样本数量均衡,均为50个
load_wine:红酒数据集,与鸢尾花数据集特点类似,也是用于连续特征的3分类任务,不同之处在于各类样本数量轻微不均衡
load_digits:小型手写数字数据集(之所以称为小型,是因为还有大型的手写数字数据集mnist),包含0-9共10种标签,各类样本均衡,与前面3个数据集最大不同在于特征也是离散数值0—16之间,例如在进行多项式朴素贝叶斯模型、ID3树模型时,可用该数据集
load_boston:波士顿房价数据集,连续特征拟合房价,适用于回归任务
值得指出,sklearn除了load系列经典数据集外,还支持自定义数据集make系列和下载数据集fetch系列(load系列为安装sklearn库时自带,而fetch则需额外下载),这为更多的学习任务场景提供了便利。
03 数据预处理 sklearn中的各模型均有规范的数据输入输出格式,一般以np.array和pd.dataframe为标准格式,所以一些字符串的离散标签是不能直接用于模型训练的;同时为了加快模型训练速度和保证训练精度,往往还需对数据进行预处理,例如在以距离作为度量进行训练时则必须考虑去量纲化的问题。为此,sklearn提供了一些常用的数据预处理功能,常用的包括:
MinMaxScaler:归一化去量纲处理,适用于数据有明显的上下限,不会存在严重的异常值,例如考试得分0-100之间的数据可首选归一化处理
StandardScaler:标准化去量纲处理,适用于可能存在极大或极小的异常值,此时用MinMaxScaler时,可能因单个异常点而将其他数值变换的过于集中,而用标准正态分布去量纲则可有效避免这一问题
Binarizer:二值化处理,适用于将连续变量离散化
OneHotEncoder:独热编码,一种经典的编码方式,适用于离散标签间不存在明确的大小相对关系时。例如对于民族特征进行编码时,若将其编码为0-55的数值,则对于以距离作为度量的模型则意味着民族之间存在"大小"和"远近"关系,而用独热编码则将每个民族转换为一个由1个"1"和55个"0"组成的向量。弊端就是当分类标签过多时,容易带来维度灾难,而特征又过于稀疏
Ordinary:数值编码,适用于某些标签编码为数值后不影响模型理解和训练时。例如,当民族为待分类标签时,则可将其简单编码为0-55之间的数字
04 特征选择 机器学习中有句经典的台词是:数据和特征决定学习上限,模型和算法只是逼近这个上限,可见特征工程在机器学习中的重要性。一般而言,传统机器学习中的特征工程主要包括两方面需求:
特征维度过多时,为加快模型训练速度,进行特征选择即过滤掉不重要的特征;
特征较少或模型训练性能不好时,可通过对问题的理解尝试构建特征提升维度。
这里简单介绍几种特征选择的方式:
from_model:顾名思义,从模型选择特征,这是因为很多模型在训练后都提供了特征的重要性结果feature_importance,据此可作为特征选择的依据
VarianceThreshold:根据方差阈值做特征选择,实际上当某一特征的方差越大时意味着该特征越能带来更好的分类区分度,否则由于特征取值比较集中,很难对应不同的分类效果
SelectKBest:指定K个特征选择结果,具体也需依赖选择的标准
05 模型选择 模型选择是机器学习中的重要环节,涉及到的操作包括数据集切分、参数调整和验证等。对应常用函数包括:
train_test_split:常用操作之一,切分数据集和测试集,可设置切分比例
cross_val_score:交叉验证,默认K=5折,相当于把数据集平均切分为5份,并逐一选择其中一份作为测试集、其余作为训练集进行训练及评分,最后返回K个评分
GridSearchCV:调参常用方法,通过字典类型设置一组候选参数,并制定度量标准,最后返回评分最高的参数
06 度量指标 不同的度量指标可以学到不同的最优模型。对于不同类型任务,sklearn提供了多种度量指标,包括:
分类任务:准确率,所有样本中分类正确样本所占比例;精准率和召回率,一对相互矛盾的指标,适用于分类样本数量不均衡时,此时为了保证既定目标,可只选其中一个指标;调和平均数F1,相当于兼顾了精准率和召回率两项指标
回归任务:常用的包括MSE、MAE,但R2_score实质上是更为公允和直观的评价指标,其意义是R2_Score = MSE / VAR,即预测分类和实际分类的均方差与实际分类方差的比值
聚类任务:聚类任务属于无监督学习,所以根据是否有先验标签信息,聚类结果的度量指标包括轮廓系数(无需先验标签,用组内距离与组外最近距离的比值度量)、调整兰德指数(基于真实分簇标签和聚类标签计算)
07 降维 降维也属于无监督学习的一种,当特征维度过多时可通过矩阵的QR分解实现在尽可能保留原有信息的情况下降低维度,一般用于图像数据预处理,且降维后的特征与原特征没有直接联系,使得模型训练不再具有可解释性。
08 聚类 聚类是一种典型的无监督学习任务,但也是实际应用中较为常见的需求。在不提供样本真实标签的情况下,基于某些特征对样本进行物以类聚。根据聚类的原理,主要包括三种:
基于距离聚类,典型的就是K均值聚类,通过不断迭代和重新寻找最小距离,对所有样本划分为K个簇,有一款小游戏《拥挤城市》应该就是基于K均值聚类实现
基于密度聚类,与距离聚类不同,基于密度聚类的思想是源于通过距离判断样本是否连通(需指定连通距离的阈值),从而完成样本划分。由于划分结果仅取决于连通距离的阈值,所以不可指定聚类的簇数。典型算法模型是DBSCAN
基于层次聚类,具体又可细分为自顶向下和自底向上,以自底向上层次聚类为例:首先将所有样本划分为一类,此时聚类簇数K=样本个数N,遍历寻找K个簇间最相近的两个簇并完成合并,此时还有K-1个簇,如此循环直至划分为指定的聚类簇数。当然,这里评价最相近的两个簇的标准又可细分为最小距离、最大距离和平均距离。
09 基本学习模型 分类和回归任务是机器学习中的经典场景,同属于有监督学习。经典的学习算法主要包括5种:
线性模型,回归任务中对应线性回归,分类任务则对应即逻辑回归,或者叫对数几率回归,实质是通过线性回归拟合对数几率的方式来实现二分类
K近邻,最简单易懂的机器学习模型,无需训练(惰性模型),仅仅是通过判断自己所处位置周边的样本判断类比或者拟合结果
支持向量机,一个经典的机器学习模型,最初也是源于线性分类,通过最大化间隔实现最可靠的分类边界。业界相传:支持向量机有三宝、间隔对偶核函数。其中"间隔"由硬间隔升级为软间隔解决了带异常值的线性不可分场景,"对偶"是在优化过程中求解拉格朗日问题的一个小技巧,而核函数才是支持向量机的核心,通过核实的核函数可以实现由线性可分向线性不可分的升级、同时避免了维度灾难
朴素贝叶斯,源于概率论中贝叶斯全概率公式,模型训练的过程就是拟合各特征分布概率的过程,而预测的过程则是标出具有最大概率的类比,是一个纯粹的依据概率完成分类任务的模型。而像逻辑回归、K近邻、支持向量机以及决策树,虽然也都可以预测出各类别概率,但并不是纯粹意义上的概率
决策树,这是一个直观而又强大的机器学习模型,训练过程主要包括特征选择-切分-剪枝,典型的3个决策树是ID3、C4.5和CART,其中CART树既可用于分类也可用于回归。更重要的是,决策树不仅模型自身颇具研究价值,还是众多集成学习模型的基学习器。
在以上5个经典的基本学习模型中,除了朴素贝叶斯仅用于分类任务外,其他4个模型都是既可分类也可回归的模型。
10 集成学习模型 当基本学习模型性能难以满足需求时,集成学习便应运而生。集成学习,顾名思义,就是将多个基学习器的结果集成起来汇聚出最终结果。而根据汇聚的过程,集成学习主要包括3种流派:
你有没有想过,就在你的电脑上,用几行代码就能搭建一个服务器?没错,不需要复杂的Apache、Nginx,Python的http.server模块就能让你快速起飞。今天,暴躁哥就带你快速入门!
1.为啥用 http.server? 简单!快!烦那些花里胡哨的东西?http.server是你的最佳选择。不用装一堆乱七八糟的东西,Python自带的,开箱即用!
2.基本使用 看这里,一行命令:
python -m http.server 完了,你的电脑现在就是个服务器了,端口是8000。打开浏览器,输127.0.01:8000,看看是不是有东西?
如果你需要换一个端口, 比如8001。
你可以这样:
python -m http.server 8001 3.自定义服务器 “这样太简单了,我要自定义!” 没问题!来自定义一个:
比如我们加上一个"/hello"路由。
from http.server import HTTPServer, SimpleHTTPRequestHandler class MyHandler(SimpleHTTPRequestHandler): def do_GET(self): if self.path == '/hello': self.send_response(200) self.end_headers() self.wfile.write(b"Hello, world!") else: super().do_GET() # 其他请求就用默认的处理方式 server_address = ('', 8008) httpd = HTTPServer(server_address, MyHandler) httpd.serve_forever() 再复杂点儿,需要加上简单的POST请求。
import cgi from http.server import HTTPServer, SimpleHTTPRequestHandler class MyHandler(SimpleHTTPRequestHandler): def do_GET(self): if self.path == '/hello': self.send_response(200) self.end_headers() self.
运行环境 (后面附有API9版本,可修改后在HarmonyOS4设备上运行)
DAYU200:4.0.10.16
SDK:4.0.10.15
IDE:4.0.600
在DAYU200:4.0.10.16上运行 一、创建应用 1.点击File->new File->Create Progect
2.选择模版
【OpenHarmony】Empty Ability
3.填写项目名,WenXinTalk,应用包名com.WenXinTalk,应用存储位置XXX(不要有中文,特殊字符,空格)
Compile SDK10,Model :Stage
Device Type 默认就可以。
node,建议16.20.1
完成以上配置以后点击Finish
4.选择在新窗口打开,等待依赖加载完毕。如图所示。
如果大家加载依赖报错的话,检查自己的网络。
二、运行HelloWord 1.给开发板供电,并连接开发板到电脑,如图所示
2.签名
签名的步骤:
点击File->Project struct
点击Apply或者ok就可以,。
现在点击按钮运行项目。
控制台打印信息
01/12 16:13:40: Launching com.myapplication $ hdc uninstall com.myapplication $ hdc shell mkdir data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279 $ hdc file send "E:\study\HarmonyOS\project\WenXinTalk\entry\build\default\outputs\default\entry-default-signed.hap" "data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279" $ hdc shell bm install -p data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279 $ hdc shell rm -rf data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279 $ hdc shell aa start -a EntryAbility -b com.
前言 安装Python和PySide6 :首先,确保已经安装了Python和PySide6 。你可以从Python官方网站(https://www.python.org)下载并安装Python,然后使用pip命令安装PySide6 。
设计GUI界面:使用Qt Designer工具来设计GUI界面。Qt Designer是一个可视化的界面设计工具,可以帮助你创建和布局GUI界面。你可以在PyQt5的安装目录中找到Qt Designer。
将GUI界面转换为Python代码:在Qt Designer中设计好界面后,可以将界面保存为.ui文件。然后,使用PyQt5提供的工具将.ui文件转换为Python代码。可以使用pyuic5命令行工具或者在Python代码中使用uic模块进行转换。
编写业务逻辑:在生成的Python代码中,你可以添加业务逻辑。这包括处理用户输入、响应按钮点击事件、更新界面等操作。你可以使用PyQt5提供的各种类和方法来实现这些功能。
运行应用程序:完成代码编写后,你可以运行应用程序并测试它的功能。可以使用Python解释器运行你的代码,或者将代码打包成可执行文件。
调试和优化:在运行应用程序时,可能会遇到一些错误或者需要进行性能优化。你可以使用调试工具来定位和修复错误,并使用PyQt5提供的一些优化技巧来提高应用程序的性能。
一、安装PySide6 (删除) 安装命令:
pip install --upgrade pip 或 python.exe -m pip install --upgrade pip pip install PySide6-i https://mirror.baidu.com/pypi/simple # 更新PySide6库 pip install --upgrade PySide6 # 删除PySide6库 pip uninstall PySide6 二、Pycharm配置Pyside6 打开Pycharm点击File -> Settings -> Tools -> External Tools,点击+。需要添加 Pyside6-Designer 、 Pyside6-UIC 和 Pyside6-rcc三个选项
$FileName$ -o $FileNameWithoutExtension$.py $FileDir$ 把设计的图案 转换生成 ui.py 文件来使用
$FileName$ -o $FileNameWithoutExtension$_rc.py $FileDir$ 三、设计界面 在PyCharm的终端命令行输入以下命令,启动设计
1. lora介绍(Low Rank Adaption) 何为LoRA?LoRA并不是扩散模型专有的技术,而是从隔壁语言模型(LLM)迁移过来的,旨在解决避免将整个模型参数拷贝下来才能对模型进行调校的问题。因为大型语言模型的参数量过于恐怖,比如最近新出的GPT-4参数量约为100 万亿。
LoRA采用的方式是向原有的模型中插入新的数据处理层,这样就避免了去修改原有的模型参数,从而避免将整个模型进行拷贝的情况,同时其也优化了插入层的参数量,最终实现了一种很轻量化的模型调校方法。
和上文提到的Hypernetwork相同,LoRA在稳定扩散模型里也将注意打在了crossattention(注意力交叉)机制上,LoRA将会将自己的权重添加到注意力交叉层的权重中,以此来实现微调。
添加是以向量(矩阵)的形式,如果这样做,LoRA势必需要存储同样大小的参数,那么LoRA又有了个好点子,直接以向量(矩阵)相乘的形式存储,最终文件大小就会小很多了。 https://www.bilibili.com/read/cv22533819?spm_id_from=333.999.0.0
2. 环境准备 为了使用LoRa,需要stable-diffusion-webui的环境:
stable-diffusion-webui
想要自己训练lora,可以使用以下工具
lora-scripts(LoRA training scripts for kohya-ss/sd-scripts)
3. 模型训练 各种大模型以及社区训练好的模型可以在这里下载civitai(需要魔法),使用方法可见第五章。
1. 数据准备(最重要) 数据准备是训练过程中的重要步骤,因为好的数据集会大大提高模型的性能,质量比数量更重。
需要关注的主要点有:
数据质量(抠图):确保你的图像是准确的、清晰的,没有噪声和其他不必要的干扰因素。因此,需要进行目标识别与抠图。我找了几个实用的方式,手动操作的话可以用这个网站,免费全尺寸抠图人像抠图(单张操作)。数量多的话可以用remove.bg网站的api来进行抠图,有每月50张的免费额度。附录有写好的python脚本,填上api和图像目录就行。
【更新】 通过多个本地分割案例测试,该方法Semantic Guided Human Matting也能够很好的进行抠图,可以点击链接进入相应的git仓库按步骤进行本地部署。图像尺寸:在训练模型之前,需要将所有的图像调整到同一尺寸。图像尺寸的选择取决于你的模型和数据,基于sd-1.5一般为512*512. 修改图像尺寸可以使用该网站的功能。修改尺寸工具数据标签:每个样本都应该有准确的标签。可以使用多种方法生成标签Tag。我们可以手动填写每个标签,但建议大家先批量自动生成,然后再进行手动修改,这样的效果可以更好。
如果你需要某一部分是可控的,那么就将这一部分放在标签内;如果某一部分是该LoRA的特征,那么最好不要去添加。
举例:如果我们需要后续可以修改头发的颜色,那就在标签内填写现在有头发特征,如黑发|长发,这样后续才方便我们使用SD生成时进行修改。如果关于该图的所有Tag内都没有关于头发的描述,那么AI将会理解关于头发的部分,是这个LoRA的一部分,是内置在LoRA模型内无法进行单独修改的。数据的多样性:你的数据应该涵盖所有可能的情况。例如,数据集应该包括各种不同的角度和环境条件下的图像。数据数量:至少大于5张,越多越好,一般10-20张够用。 参考资料:图像素材准备与打标
2. 模型选择 在开始训练前,你需要选择一个适合你任务的模型。模型的选择通常取决于你的任务类型以及你的计算资源,看是训练 真人模型还是动漫模型,需要选择合适的大模型底膜。例如真人模型要选 majic_mix.safetensor.
3. 训练过程 在开始训练前,你需要设置一些超参数。这些参数在lora-scripts的train.sh中定义:
# Train data path | 设置训练用模型、图片 pretrained_model="./sd-models/model.ckpt" # base model path | 底模路径 is_v2_model=0 # SD2.0 model | SD2.0模型 2.0模型下 clip_skip 默认无效 parameterization=0 # parameterization | 参数化 本参数需要和 V2 参数同步使用 实验性功能 train_data_dir="
꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:xiaoxie的JAVA系列专栏——CSDN博客●'ᴗ'σσணღ*
我的目标:"团团等我💪( ◡̀_◡́ ҂)" ( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝+关注(互三必回)!
一.关于二叉树的遍历的总结 1.使用递归来遍历二叉树 使用递归的方法来遍历二叉树我相信大家应该都没有什么大问题,在这里就不过多的赘述了,直接上代码
1.前序遍历(按照根 -> 左 -> 右) public void preOrder(TreeNode root) { if(root == null) { return; } System.out.print(root.val + " "); preOrder(root.left); preOrder(root.right); } 2.中序遍历(按照左 -> 根 -> 右) public void inOrder(TreeNode root) { if(root == null){ return; } inOrder(root.left); System.out.print(root.val + "
1 人工智能、机器学习、深度学习的关系 如图1所示
图 1 :人工智能、机器学习、深度学习之间的关系
可以看到,三者之间相互包含:人工智能涵盖范围最广,它包含了机器学习;而机器学习是人工智能的重要研究内容,它又包含了深度学习。
人工智能(Artificial Intelligence:AI)、机器学习(Machine Learning:ML)和深度学习(Deep Learning:DL)在计算机科学领域中形成了一种层次关系。在最广泛的层面上,人工智能构成了开发计算机系统的首要目标,它可以执行需要类人智能的任务。在人工智能领域中,机器学习作为一个专门的子集出现,专注于使机器在没有显式编程的情况下从数据中学习。ML包括各种学习范式,包括有监督、无监督和强化学习。另一方面,深度学习是ML中的进一步专业化,利用具有多层的深度神经网络来自动学习数据的层次表示。虽然人工智能封装了智能系统的宏伟愿景,但ML为机器提供了从数据中学习模式的基础工具,而DL通过使用复杂的神经结构来改进这一过程。深度学习,特别是其深度神经网络,擅长从大型数据集中捕捉复杂的特征,从而在图像和语音识别等任务上取得突破。从本质上讲,人工智能是一个总体概念,ML作为一个子集提供了学习能力,而DL,ML的一种特殊形式,利用深度神经网络来实现先进的学习和表示,共同推动了智能系统和技术的进化。这种层次关系突出了从人工智能的广泛愿望到ML和DL中分别复杂复杂的学习机制和神经结构的进展。
2 人工智能、大数据、数据分析、数据挖掘的关系 大数据是指大量的结构化和非结构化数据,它构成了人工智能应用的基础资源。人工智能算法,包括机器学习和深度学习,可以在大型数据集上进行训练模型和提高预测精度。
数据分析包括对数据的检查和解释,以得出结论,确定趋势和支持决策。在人工智能的背景下,数据分析在将数据集输入学习算法之前的预处理和细化中发挥着至关重要的作用。它有助于特征选择,识别异常值,并确保数据质量,有助于人工智能模型的有效性。
数据挖掘是数据分析的一个子集,它专注于从大型数据集中发现隐藏的模式和知识。它使用了各种技术,包括统计分析和机器学习算法,以发现有价值的见解。数据挖掘在提取相关信息方面尤其有用,这些信息可用于增强人工智能模型和提高其决策能力。
随着人工智能系统利用大数据的能力,利用大数据的丰富度来有效地训练模型,这些领域之间的关系变得很明显。反过来,人工智能通过自动提取复杂模式和基于学习到的行为进行预测来增强数据分析和数据挖掘过程。人工智能可以在大型数据集中发现复杂的关系,这可能是传统数据分析方法要识别的挑战。如图2 所示:
图2 人工智能、大数据、数据分析、数据挖掘的关系
3 深度学习 深度学习(DL)是机器学习(ML)的一个复杂的子集,它利用具有多层的神经网络来自动学习数据的层次表示。DL的本质在于它能够从大型而复杂的数据集中自动提取复杂的特征和模式,使机器能够以一种类似于人类认知的方式来理解和解释信息。深度学习的核心是深度神经网络,其特征是具有输入层、多个隐藏层和输出层的复杂架构。这些层通过加权连接相互连接,使模型能够逐步捕获层次结构的特征,从而允许在数据中表示抽象的概念和细微差别。训练过程包括向网络提供大量的标记数据,通过反向传播迭代地调整权值,并改进模型泛化模式的能力。DL擅长于图像和语音识别、自然语言处理和复杂决策等任务,在传统机器学习方法可能不足的领域表现出显著的表现。深度学习的变革性影响遍及各个行业,推动了医疗保健诊断领域的进步,自动驾驶汽车、推荐系统等等。虽然深度学习的计算需求可能是巨大的,但最近的技术进步和强大的硬件的可用性促进了它的广泛采用。深度学习的成功明显体现在其在特定领域超越人类水平的能力上,这标志着人工智能能力的范式转变。作为一个不断发展的领域,深度学习继续推动机器所能实现的边界,正在进行的研究集中于提高模型的可解释性,解决伦理考虑,并将其适用性扩展到新的领域。总之,深度学习代表了机器学习的一种革命性方法,使系统能够自主地从数据中学习复杂的表示,其影响在不同领域产生共鸣,塑造了人工智能的未来格局。
3.1 神经网络 人工智能的目的是让机器具备人的思维和意识。在实现的过程中,目前有主流三大学派、分别为行为主义、符号主义和连接主义。其中行为主义是基于控制论,目的是构建一个感知-动作控制系统。(控制论,如平衡、行走、避障等自适应控制系统)。符号主义是基于算数逻辑表达式,求解问题时先把问题描述为表达式,再求解表达式(可用公式描述、实现理性思维,如专家系统)。连接主义:基于仿生学,模仿神经元连接关系。(仿脑神经元连接,实现感性思维,如神经网络)。如图3
图 3 :仿人脑神经元构建的神经网络
3.2 神经网络设计过程 随着我们的成长,大量的数据通过视觉、听觉涌入大脑,使我们的神经网络连接,也就是神经元连接线上的权重发生变化,有些线权重增强了,有些线上的权重减弱了。如图4
图 4 :神经网络设计过程
3.3 将人脑学习过程转换神经网络学习过程 3.31 数据准备 以手写数字识别mnist数据集为例:
MNIST数据集共有7000张图像,其中其中训练集60000张,测试集10000张,所有图像都是28*28的灰度图像,每张图像包含一个手写数字。
标注类别:共10个类别,每个类别代表0-9之间的数字。
图 5 :mnist数据集
数据集由图像和标签构成,mnist数据集的图像为28*28的灰色图像。标签则对应着每个图像所属的数字类别。
3.3.2 跨越语义的鸿沟 MNIST数据是由70000个2828的灰度图组成。我们人眼看到的是一张张图片。而计算机看到的是一组组矩阵。如图6
图6 :mnist数据集、计算机看到的矩阵形式2828的矩阵
同样的如果是3通道的彩色图像,则计算机看到的是3个矩阵。多通道则是n个矩阵。
3.3.3 彩色图像需要考虑的维度 如下图,随着学习的深入和进阶。我们需要考虑图像可能遇到的多个维度。计算机在处理时会遇到哪些困难。如图7所示: 可能包括但不限于视角、光照、遮挡、尺度、形变、背景杂波、运动模糊等。了解这些,在模型训练时,适当做些数据增强,效果会很好。同时针对不同图像的特点,有针对的性的做图像处理,也可以改善模型性能。
图 7 :图像需要考虑的多个维度
前面两篇推文我们分别介绍了使用Python和R进行IDW(反距离加权法) 插值的计算及结果的可视化过程,详细内容可见如下:
Python - IDW插值计算及可视化绘制
R-gstat-ggplot2 IDW计算及空间插值可视化绘制(需修改链接)
本期推文,我们将介绍如何使用Python进行克里金(Kriging)插值计算及插值结果的可视化绘制。主要涉及的知识点如下:
克里金(Kriging)插值简介
Python-pykrige库克里金插值应用
克里金(Kriging)插值结果可视化绘制
克里金(Kriging)插值简介 克里金法(Kriging) 是依据协方差函数对随机过程/随机场进行空间建模和预测(插值)的回归算法。在特定的随机过程,例如固有平稳过程中,克里金法能够给出最优线性无偏估计(Best Linear Unbiased Prediction, BLUP),因此在地统计学中也被称为空间最优无偏估计器(spatial BLUP)(以上定义来自于网络)。还是IDW插值介绍一样,我们省去繁琐的公式推导过程,示意图如下:
(Kriging插值示意图)
而使用Python进行Kriging插值计算无需自定义复杂的函数,这里我们直接调用pykrige包进行Kriging插值计算,二我们所要作的就是将计算出pykrige包插件计算所需要的参数数据即可。
插值网格制作 无论十自定义还是调用包,我们都需要制作出我们插值区域的网格(grid),方法也十分简单,首先根据地图文件(js)获取其经纬度范围,这里我们使用geopandas读取geojson 地图文件,并获取total_bounds属性,具体代码如下:
js_box = js.geometry.total_bounds grid_lon = np.linspace(js_box[0],js_box[2],400) grid_lat = np.linspace(js_box[1],js_box[3],400) 这里我们还是设置400*400的网格,注意np.linspace()方法和上期中 R的seq() 的使用不同。除此之外,我们还需要获取已知站点的经纬度信息(lons、lats)和对应值(data),这里给出点数据预览,如下:
获取数据代码如下:
lons = nj_data["经度"].values lats = nj_data["纬度"].values data = nj_data["PM2.5"].values pykrige包计算插值结果 在进过上面的数据处理过程后,我们已经构建出符合pykrige包进行插值计算所需的全部参数数据,接下来,我们直接调用即可,具体操作代码如下:
from pykrige.ok import OrdinaryKriging OK = OrdinaryKriging(lons, lats, data, variogram_model='gaussian',nlags=6) z1, ss1 = OK.execute('grid', grid_lon, grid_lat) 注意:
我们使用OrdinaryKriging方法进行插值计算,此外,还有UniversalKriging、RegressionKriging插值方法
variogram_model='gaussian',我们设置高斯(gaussian)模型,其结果和一般的线性(linear)结果可能会有不同。
pykrige提供 linear, power, gaussian, spherical, exponential, hole-effect几种variogram_model可供选择,默认的为linear模型。
Python pip更换清华源镜像 命令安装配置安装其它镜像 在安装Python库时使用清华源镜像是为了改善库的下载速度和稳定性地址:https://pypi.tuna.tsinghua.edu.cn/simple 命令安装 安装命令:
pip install 包名 -i https://pypi.tuna.tsinghua.edu.cn/simple 以wordcloud库为例,在终端输入后回车:
pip install wordcloud -i https://pypi.tuna.tsinghua.edu.cn/simple 配置安装 依次点击PyCharm的File,Settings:
再依次点击Project,Python Interpreter,+:
点击Manage Repositories:
点击+,输入清华源镜像地址:https://pypi.tuna.tsinghua.edu.cn/simple,点击OK:
再点击OK:
以wordcloud为例,输入想要安装的库名,点击Install Package,还能在右边选择版本:
安装成功:
其它镜像 豆瓣:http://pypi.douban.com/simple/
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科学技术大学:http://pypi.mirrors.ustc.edu.cn/simple/
目录
1、基本请求
2、代理设置
3、设置请求参数
4、设置请求头
5、文件的写入与读取
6、遍历请求 txt 内的所有 url
7、其他补充
1、基本请求 测试代码:
import requests re = requests.get("http://www.baidu.com") print(re.status_code) print(re.text) 个人理解:
使用 requests 库我们肯定需要先导入它,使用 import 导入;
re 为我们自定义的一个参数,用来接收请求返回的信息,在 python 中点表示调用的意思,我们这里就调用了 requests 库中的 get() 方法,括号内为请求的URL,使用单引号或者双引号包裹;
最后使用 print 函数输出响应结果,也是通过点进行调用;
status_code 为响应状态码,text 返回的是网页源码(str类型)。
运行结果:
常用的调用方法:
re. text # 返回的是unicode 型的数据,一般是在网页的header中定义的编码形式
re.content # 返回的是bytes,二级制型的数据
如果想要提取文本就用 text ,如果想要提取图片、文件,就用 content
re.url # 获取请求的 url
re.status_code # 获取响应的状态码
re.headers # 获取响应头
re.request.headers # 获取请求头
re.cookies # 获取 cookie
文章目录 1.递归函数2.递归流程图3.递归总结4.递归注意事项5.内存栈区堆区(了解内容)6.递归案例1.使用递归实现任意数n的阶乘普通实现递归实现 2. 使用尾递归来实现任意数的阶乘(1) 优化代码1(2)优化代码2 [把尾递归需要的参数值隐藏起来,避免篡改.](3)优化代码3(扩展) 3.使用递归来完成斐波那契数列 1.递归函数 工作中,我们可能经常会遇到递归函数的使用,今天我们就来深入讲讲什么是递归。
递归函数 : 在函数内部,可以调用其他函数。如果一个函数在内部自己调用自己,这个函数就是递归函数。必须由出口
递 : 去
归 : 回
一去一回叫做递归
def digui(n): print(n,"<==1==>") if n > 0: digui(n-1) print(n,"<==2==>") digui(5) #此递归函数开辟了6层空间。去的过程
n = 5 print(5,"<==1==>") if 5 > 0: digui(5-1) => digui(4) 代码阻塞在第12行,下面的代码不再执行 n = 4 print(4,"<==1==>") if 4 > 0: digui(4-1) => digui(3) 代码阻塞在第12行 n = 3 print(3,"<==1==>") if 3 > 0: digui(3-1) => digui(2) 代码阻塞在第12行 n = 2 print(2,"
最近把工作终端一步步迁移到Mac上来了,搭了个 Latex的环境,跟windows上一样好用。
首先,如果是 intel 芯片的 macOS,那么可以使用组合1,
如果是 M1、M2 或 M3 芯片或者 intel 芯片的 Mac book,则应该使用组合2,
texMaker目前在Mx芯片上工作不行;
1,Mactex + Texmaker
2,Mactex + (VScode + Latex workshop[James Yu])
效果分别如下图,点击
选择了 Mactex 做编译,用 Texmaker 做编辑;
1. 下载与安装 1.1 Mactex 下载安装 MacOS 安装和示例 LaTex 的编译器 与 编辑器
编译器使用免费的 Mactex:
https://tug.org/mactex/mactex-download.html
单击页面中的粗体 MacTeX.pkg. 即可开始下载;
下载 完毕后双击,进入安装页面,全部采用默认配置,一路点击,最后安装几分钟后结束。
如果是M1 M2 等M系列的Mac 电脑,那么不需要安装Texmaker,可以直接使用 已经安装进来的 Texshop,稍显简陋,但也能用:
分三步:
1, 打开软件
2, 输入latex代码
\documentclass[12pt]{article} \title{Dawn} \begin{document} \maketitle \[ Hello\,\, L^{A}T_{E}X\,2_{\epsilon} \] \begin{equation} f\, =\,a^{x}\,+\,b \end{equation} $\backslash$ I read that Knuth divides the\newline people working with \TeX{} into\newline \TeX{}nicians and \TeX perts.
这是ubuntu20.04安装步骤,其他版本建议查阅官网安装!!! 1.切换到自己想要安装的目录安装依赖包 cd /tmp
2.拉取和解压安装包 wget https://zunyun01.store.deepinos.org.cn/spark-store-dependencies-kylin.zip unzip spark-store-dependencies-kylin.zip # 解压得到目录 spark-store-dependencies-kylin/ # 以及 spark-store-dependencies-kylin/解压我.tar cd spark-store-dependencies-kylin/ tar xvf 解压我.tar # 得到 all-depends/ # 以及 all-depends/Debian10-or-ubuntu-20.04/ 3.安装依赖 cd all-depends/Debian10-or-ubuntu-20.04/ sudo apt update sudo apt install -yf ./*.deb 4.下载软件包 软件包在官网上就可以,直接搜索spark-store安装下载解压
推荐使用apt来安装(apt会自动安装软件包所需要的依赖包,dpkg不会)
apt-get install -y 安装包.deb
概要 Python是一门灵活而强大的编程语言,提供了各种机制来控制模块的导入和访问。其中,__all__魔法函数是一种用于限制模块导入的机制,可以明确指定哪些变量、函数或类可以被导入。本文将深入探讨__all__的作用、用法以及示例,以帮助大家更好地理解和使用这一功能。
什么是__all__? __all__是一个特殊的Python模块级别变量,它是一个包含字符串的列表。当在一个模块中定义了__all__变量时,它将告诉Python解释器哪些名称应该被视为模块的公共接口,即哪些名称可以通过from module import *语句导入到其他模块中。
使用__all__可以提供以下几个好处:
明确指定模块的公共接口,提高代码的可读性。
避免不必要的名称泄露,防止模块的私有成员被导入。
控制模块的外部可见性,确保只有经过认可的接口可以被外部使用。
__all__的用法 要使用__all__,需要在模块中定义一个名为__all__的变量,并将需要导出的名称添加到列表中。
以下是一个简单的示例:
# mymodule.py # 导出的名称列表 __all__ = ['function1', 'function2'] def function1(): return "This is function 1." def function2(): return "This is function 2." def _private_function(): return "This is a private function." 在上面的示例中,__all__变量明确指定了function1和function2可以被导入,而_private_function是模块的私有函数,不会被导入。
示例1:限制导入的变量和函数 看一个完整的示例,演示如何使用__all__来限制导入的变量和函数。创建一个名为math_operations.py的模块,其中包含一些数学操作函数,并使用__all__指定哪些函数可以被导入。
# math_operations.py __all__ = ['add', 'subtract'] def add(a, b): return a + b def subtract(a, b): return a - b def multiply(a, b): return a * b def divide(a, b): return a / b 在另一个模块中尝试导入这些函数,并查看__all__的限制效果。