【万字详解】如何在微信小程序的 Taro 框架中设置静态图片 assets/image 的 Base64 转换上限值
设置方法
mini
中提供了 imageUrlLoaderOption
和 postcss.url
。
其中:
config.limit
和 imageUrlLoaderOption.limit
服务于 Taro 的 MiniWebpackModule.js , 值的写法要 ()KB * 1024
。
config.maxSize
服务于 postcss-url 的 inline.js , 值的写法要 ()KB
。
关于为什么 limit
和 maxSize
的写法不同?
因为在源码层:
limit
在使用时是判断 limit
和 2 * 1024
的值: maxSize: options.limit || 2 * 1024
;
maxSize
在使用时是判断 maxSize
和 0
,再乘以 1024
: const maxSize = (options.maxSize || 0) * 1024;
;
所以在配置时要注意区分。
const config = {// ...mini: {// ...imageUrlLoaderOption: {limit: num * 1024,},postcss: {// ...url: {enable: true / false,config: {limit: num * 1024,maxSize: num,},},// ...},},// ...
};// ...
Base64 转换上限值分以下 12 种情况去配置:
url | config | imageUrlLoaderOption | 转成 Base64 的图片上限 |
url.enable 为 true | config.limit 和 config.maxSize 都存在 | 没有 imageUrlLoaderOption.limit | config.limit 和 maxSize的最大值 |
有 imageUrlLoaderOption.limit | config.limit、imageUrlLoaderOption.limit 、 maxSize的最大值 | ||
config.maxSize 不存在, config.limit 存在 | 没有 imageUrlLoaderOption.limit | 全部图片都被转成 Base64 | |
有 imageUrlLoaderOption.limit | 全部图片都被转成 Base64 | ||
config.limit 不存在, config.maxSize 存在 | 没有 imageUrlLoaderOption.limit | 当 maxSize > 10 ,以 maxSize 为主;否则小于 10KB 的图片被转成 Base64 | |
有 imageUrlLoaderOption.limit | imageUrlLoaderOption.limit 和 maxSize的最大值 | ||
config.limit 和 config.maxSize 都不存在 | 没有 imageUrlLoaderOption.limit | 全部图片都被转成 Base64 | |
有 imageUrlLoaderOption.limit | 全部图片都被转成 Base64 | ||
url.enable 为 false | - | 没有 imageUrlLoaderOption.limit | 2KB |
有 imageUrlLoaderOption.limit | imageUrlLoaderOption.limit | ||
不存在 url | - | 没有 imageUrlLoaderOption.limit | 全部图片都被转成 Base64 |
有 imageUrlLoaderOption.limit | 全部图片都被转成 Base64 |
最实用的配置:
不使用 postcss 插件,通过 Taro 提供的 imageUrlLoaderOption
来设置转换上限值
// ...
const config = {// ...mini: {// ...imageUrlLoaderOption: {limit: -1,},postcss: {// ...url: {enable: false,},// ...},},// ...
};
// ...
关于 limit
config.limit
和 imageUrlLoaderOption.limit
的替换关系如图所示
源码解析
Taro 部分
class MiniWebpackModule
是 Taro 框架中用于处理和封装 Webpack 构建模块的类。它负责配置、加载和编译与各类文件格式相关的模块,通常在 Taro 生成项目构建配置时发挥作用。它的目标是将开发者的源代码转换成适用于小程序、 H5 、 React Native 等平台的最终代码。
getModules
getModules
方法的核心作用是配置和返回不同类型模块的处理规则,包括对 Sass 、 Scss 、 Less 、 Stylus 等样式文件的处理,并将其与 CSS 、 PostCSS 等工具结合起来,最终生成适合各种小程序平台的构建规则。
parsePostCSSOptions()
解析 PostCSS 的配置选项,返回 postcssOption
、postcssUrlOption
和 cssModuleOption
等。
通过 getDefaultPostcssConfig
方法获取 PostCSS 的默认配置,返回给 this.__postcssOption
进行保存。
调用 getImageRule
方法对 image
进行配置,并将配置存入 rule
对象中。
getModules() {const { appPath, config, sourceRoot, fileType } = this.combination;const { buildAdapter, sassLoaderOption, lessLoaderOption, stylusLoaderOption, designWidth, deviceRatio } = config;const { postcssOption, postcssUrlOption, cssModuleOption } = this.parsePostCSSOptions();this.__postcssOption = (0, postcss_mini_1.getDefaultPostcssConfig)({designWidth,deviceRatio,postcssOption,alias: config.alias,});const rule = {image: this.getImageRule(postcssUrlOption)};return { rule };
}
parsePostCSSOptions
defaultUrlOption
确实默认启用 postcss-url,并设置 limit
为 10KB(10240 字节)。代码中 postcssOption.url
会通过 recursiveMerge
方法与 defaultUrlOption
合并,如果配置中提供了 postcss-url 的自定义配置,将会覆盖默认值。
postcssUrlOption
不会赋值,即 config/index.ts 中配置的 config
不会被使用或存储。
parsePostCSSOptions() {const { postcss: postcssOption = {} } = this.combination.config;const defaultUrlOption = {enable: true,config: {limit: 10 * 1024 // limit 10k base on document}};const urlOptions = (0, helper_1.recursiveMerge)({}, defaultUrlOption, postcssOption.url);let postcssUrlOption = {};if (urlOptions.enable) {postcssUrlOption = urlOptions.config;}return {postcssOption,postcssUrlOption};
}
getDefaultPostcssConfig
接收 postcssOption
,从中提取 url
配置,并通过 recursiveMerge
将其与 defaultUrlOption
合并为 urlOption
。如果 postcssOption.url
存在,就会用自定义配置来替代或合并默认配置。
const getDefaultPostcssConfig = function ({ postcssOption = {} }) {const { url } = postcssOption,options = __rest(postcssOption, ["url"]);const urlOption = (0, helper_1.recursiveMerge)({}, defaultUrlOption, url);return [["postcss-url", urlOption, require("postcss-url")],...Object.entries(options),];
};
getImageRule
当调用 getImageRule
时,postcssOptions
和 imageUrlLoaderOption
合并生成新的 options
,并传递给 WebpackModule.getImageRule()
,limit
的优先级以 imageUrlLoaderOption.limit
为主导。
getImageRule(postcssOptions) {const sourceRoot = this.combination.sourceRoot;const { imageUrlLoaderOption } = this.combination.config;const options = Object.assign({}, postcssOptions, imageUrlLoaderOption);return WebpackModule_1.WebpackModule.getImageRule(sourceRoot, options);
}
WebpackModule_1.WebpackModule.getImageRule
如果 postcss.url.config.limit
没有设置,系统应有逻辑保证 limit
的默认值为 2KB。
static getImageRule(sourceRoot, options) {return {test: helper_1.REG_IMAGE,type: 'asset',parser: {dataUrlCondition: {maxSize: options.limit || 2 * 1024 // 2kb}},generator: {emit: options.emitFile || options.emit,outputPath: options.outputPath,publicPath: options.publicPath,filename({ filename }) {if ((0, shared_1.isFunction)(options.name))return options.name(filename);return options.name || filename.replace(sourceRoot + '/', '');}}};
}
postcss-url 部分
plugin
options
是个对象,属性有 url
、 limit
、 maxSize
。 url
默认值是 inline
。
当 enable
设为 false
, options
为 {}
;设为 true
, options
为打印配置中所设的,可能有 url
、 limit
、 maxSize
。
styles.walkDecls((decl) =>{});
遍历 CSS 文件中的每个声明(decl)。对每个声明,调用 declProcessor
函数,并将结果(是个 Promise
) push
到 promises
数组中。返回的 Promise
通过 then
打印的结果,是一个数组,值为'url("OSS || Base64 || assets")'
。
const plugin = (options) => {options = options || {};return {postcssPlugin: "postcss-url",Once(styles, { result }) {const promises = [];const opts = result.opts;const from = opts.from ? path.dirname(opts.from) : ".";const to = opts.to ? path.dirname(opts.to) : from;styles.walkDecls((decl) =>promises.push(declProcessor(from, to, options, result, decl)));return Promise.all(promises);},};
};
declProcessor
获取 patten
,值存在 undefined
、/(url\(\s*['"]?)([^"')]+)(["']?\s*\))/g
还有其他。
如果 patten
是 undefined
,直接返回 Promise.resolve()
。这是为了在 pattern
不存在时直接短路,避免不必要的计算。
正常函数内部执行了
Promise.resolve()
后,后面的代码是可以继续执行的。
如果 patten
不是 undefined
,新建一个 promises
数组,用来存储所有异步操作的 Promise
。 decl.value.replace(pattern, (matched, before, url, after) => { ... })
使用 replace
函数遍历和处理 decl.value
中的每个匹配项。 replace
函数的第二个函数是个回调函数,最终的返回值是 matched
。
在回调函数中执行 replaceUrl
函数,返回一个为 Promise
的 newUrlPromise
,然后调用 then
方法获取 newUrlPromise
的值。
如果 newUrlPromise
的值是 undefined
,直接返回 matched
。这种情况会发生在没有转换成 Base64 编码的本地图片路径上。
declProcessor
最终返回的是 Promise.all(promises)
(是个 Promise
)。
const declProcessor = (from, to, options, result, decl) => {const dir = { from, to, file: getDirDeclFile(decl) };const pattern = getPattern(decl);if (!pattern) return Promise.resolve();const promises = [];decl.value = decl.value.replace(pattern, (matched, before, url, after) => {const newUrlPromise = replaceUrl(url, dir, options, result, decl);promises.push(newUrlPromise.then((newUrl) => {if (!newUrl) return matched;if (WITH_QUOTES.test(newUrl) && WITH_QUOTES.test(after)) {before = before.slice(0, -1);after = after.slice(1);}decl.value = decl.value.replace(matched, `${before}${newUrl}${after}`);}));return matched;});return Promise.all(promises);
};
replaceUrl
asset
是一个对象,里面有 url
、 originUrl
、 pathname
、 absolutePath
、 relativePath
、 search
、 hash
。
当传入的是 OSS 路径或者 data:font/woff;base64
时, matchedOptions
是 undefined
,直接返回 Promise.resolve()
。
当传入的是 asset/images 下的图片时, matchedOptions
是 options
的值。会判断 matchedOptions
是不是个数组。如果是数组,则对数组里面的值一一执行 process
函数;不是数组,直接执行 process
函数。
process
函数里的 getUrlProcessor
函数会根据 url
的值判断走哪种类型的编译方法。
process
函数里的 wrapUrlProcessor
函数实现了对 urlProcessor
的“增强”,使其在处理 URL 的过程中可以记录警告信息和依赖关系。
replaceUrl
最终返回一个 Promise
,在 resultPromise.then(...)
的链式调用中, return newUrl
; 实际上是将 newUrl
封装在一个新的 Promise
中作为最终返回值,并且 Promise
的解析值是 newUrl
,可以是经过编码的 URL
、文件路径或 undefined
。
const replaceUrl = (url, dir, options, result, decl) => {const asset = prepareAsset(url, dir, decl);const matchedOptions = matchOptions(asset, options);if (!matchedOptions) return Promise.resolve();const process = (option) => {const wrappedUrlProcessor = wrapUrlProcessor(getUrlProcessor(option.url),result,decl);return wrappedUrlProcessor(asset, dir, option);};let resultPromise = Promise.resolve();if (Array.isArray(matchedOptions)) {for (let i = 0; i < matchedOptions.length; i++) {resultPromise = resultPromise.then(() => process(matchedOptions[i])).then((newUrl) => {asset.url = newUrl;return newUrl;});}} else {resultPromise = process(matchedOptions);}return resultPromise.then((newUrl) => {asset.url = newUrl;return newUrl;});
};
getUrlProcessor
根据 url
的值判断走哪种 post-url 类型
function getUrlProcessor(optionUrl) {const mode = getUrlProcessorType(optionUrl);if (PROCESS_TYPES.indexOf(mode) === -1) {throw new Error(`Unknown mode for postcss-url: ${mode}`);}return require(`../type/${mode}`);
}
wrapUrlProcessor
wrapUrlProcessor
实现了对 urlProcessor
的“增强”,使其在处理 URL 的过程中可以记录警告信息和依赖关系。
const wrapUrlProcessor = (urlProcessor, result, decl) => {const warn = (message) => decl.warn(result, message);const addDependency = (file) =>result.messages.push({type: "dependency",file,parent: getPathDeclFile(decl),});return (asset, dir, option) =>urlProcessor(asset, dir, option, decl, warn, result, addDependency);
};
inline.js
根据 options
中的 maxSize
获取 maxSize
,所以配置表中传入的maxSize
不需要乘 1024
。
如果 maxSize
不是 0
,获取图片的 size
。如果图片的 size
大于 maxSize
,调用 processFallback
,按回退处理方式(如文件路径链接)返回;如果图片的 size
小于 maxSize
,调用 inlineProcess
编译成 Base64 。
module.exports = function (asset,dir,options,decl,warn,result,addDependency
) {return getFile(asset, options, dir, warn).then((file) => {if (!file) return;if (!file.mimeType) {warn(`Unable to find asset mime-type for ${file.path}`);return;}const maxSize = (options.maxSize || 0) * 1024;if (maxSize) {const size = Buffer.byteLength(file.contents);if (size >= maxSize) {return processFallback.apply(this, arguments);}}return inlineProcess(file, asset, warn, addDependency, options);});
};
processFallback
根据 options.fallback
的值进行调用,当前 options.fallback
是 undefined
,直接返回 Promise.resolve();
。
function processFallback(originUrl, dir, options) {if (typeof options.fallback === "function") {return options.fallback.apply(null, arguments);}switch (options.fallback) {case "copy":return processCopy.apply(null, arguments);case "rebase":return processRebase.apply(null, arguments);default:return Promise.resolve();}
}
inlineProcess
该方法实现了将文件进行 Base64 转换,如果是 SVG 文件,则使用 encodeURIComponent
,否则使用 base64
编码。
const inlineProcess = (file, asset, warn, addDependency, options) => {const isSvg = file.mimeType === "image/svg+xml";const defaultEncodeType = isSvg ? "encodeURIComponent" : "base64";const encodeType = options.encodeType || defaultEncodeType;// Warn for svg with hashes/fragmentsif (isSvg && asset.hash && !options.ignoreFragmentWarning) {// eslint-disable-next-line max-lenwarn(`Image type is svg and link contains #. Postcss-url cant handle svg fragments. SVG file fully inlined. ${file.path}`);}addDependency(file.path);const optimizeSvgEncode = isSvg && options.optimizeSvgEncode;const encodedStr = encodeFile(file, encodeType, optimizeSvgEncode);const resultValue =options.includeUriFragment && asset.hash? encodedStr + asset.hash: encodedStr;// wrap url by quotes if percent-encoded svgreturn isSvg && encodeType !== "base64" ? `"${resultValue}"` : resultValue;
};
相关文章:

【万字详解】如何在微信小程序的 Taro 框架中设置静态图片 assets/image 的 Base64 转换上限值
设置方法 mini 中提供了 imageUrlLoaderOption 和 postcss.url 。 其中: config.limit 和 imageUrlLoaderOption.limit 服务于 Taro 的 MiniWebpackModule.js , 值的写法要 ()KB * 1024。 config.maxSize 服务于 postcss-url 的…...

复合选择器,CSS特性,背景属性,显示模式(HTML)
目录 复合选择器,CSS特性,背景属性,显示模式知识点: 练习一: 练习二: 复合选择器,CSS特性,背景属性,显示模式知识点: 复合选择器:后代选择器 :父选择器 子选择器(中间用空格隔开) eg:对div中的span进行设置,会对后代中的所有span都进行设置 选中所有后代(后代选择器.html)…...

加密货币行业与2024年美国大选
加密货币行业经历了近十年的飞速发展,尤其是在比特币、以太坊等主要加密资产的兴起之后,越来越多的美国人开始将其视为一种财富积累或交易的工具。然而,尽管这一新兴行业的市场规模在持续扩大,但加密货币仍面临着重重监管难题&…...

Hive SQL中判断内容包含情况的全面指南
Hive SQL中判断内容包含情况的实用指南 在 Hive SQL 的数据处理与分析世界里,判断字段是否包含特定内容是一项非常重要的操作。今天,我将为大家详细介绍 Hive SQL 中实现这一功能的多种方法,并附上相应的表创建和数据插入语句。 一、准备工作 - 表创建与数据插入 首先,我…...

匿名管道 Linux
目录 管道 pipe创建一个管道 让子进程写入,父进程读取 如何把消息发送/写入给父进程 父进程该怎么读取呢 管道本质 结论:管道的特征: 测试管道大小 写端退了,测试结果 测试子进程一直写,父进程读一会就退出 …...

苍穹外卖WebSocket无法建立连接 (修改前端代码)
我在部署nginx 反向代理服务器时,把80端口改成了90端口(不与80端口的Tomcat冲突)。 但黑马的资料里定义了前端连接nginx的端口号默认为80,造成连接不上的问题,此时只需要修改前端的端口号,使其知道如何连接到修改后的后端端口。 …...

音频内容理解
音频内容理解是音频处理和理解领域的一个重要方向,它涉及到从环境声音中提取语义信息,并能够对这些声音进行解释和描述。以下是音频内容理解的几个关键应用: 1. 音频问答(Audio Question Answering, AQA) 在这个任务…...

MQTT实用示例集:Air201版
今天贴出的是Air201版关于MQTT实用示例集,希望大家喜欢。 本示例教你通过使用脚本代码,对Air201模组进行MQTT链接操作。 操作例程包括: MQTT单链接 MQTT多链接 MQTT SSL不带证书链接 MQTT SSL带证书链接 大家可根据自身需求,…...

Day23 opencv图像预处理
图像预处理 在计算机视觉和图像处理领域,图像预处理是一个重要的步骤,它能够提高后续处理(如特征提取、目标检测等)的准确性和效率。OpenCV 提供了许多图像预处理的函数和方法,常见的操作包括图像空间转换、图像大小调…...

优化模型训练过程中的显存使用率、GPU使用率
参考:https://blog.51cto.com/u_16099172/7398948 问题:用小数据集训练显存使用率、GPU使用率正常,但是用大数据集训练GPU使用率一直是0. 小数据: 大数据: 1、我理解GPU内存占用率显存使用率,由模型的大小…...

RocketMQ学习笔记
RocketMQ笔记 文章目录 一、引言⼆、RocketMQ介绍RocketMQ的由来 三、RocketMQ的基本概念1 技术架构2 部署架构 四、快速开始1.下载RocketMQ2.安装RocketMQ3.启动NameServer4.启动Broker5.使⽤发送和接收消息验证MQ6.关闭服务器 五、搭建RocketMQ集群1.RocketMQ集群模式2.搭建主…...

Linux第三讲:环境基础开发工具使用
Linux第三讲:环境基础开发工具使用 1.Linux软件包管理器yum1.1什么是软件包管理器1.2操作系统生态问题1.3什么是yum源 2.vim详解2.1什么是vim2.2vim的多模式讲解2.2.1命令模式的诸多指令2.2.1.1gg和nshiftg2.2.1.2shift$和shift^2.2.1.3上、下、左、右2.2.1.4w和b2.…...

日本TikTok直播的未来:专线网络助力创作者突破极限
近年来,随着短视频平台的崛起,尤其是TikTok(国际版抖音)成为全球范围内广受欢迎的社交娱乐平台,直播功能的加入无疑为内容创作者提供了更广阔的展示舞台。在日本,TikTok直播不仅使得年轻人能够实时与粉丝互…...

如何在家庭网络中设置静态IP地址:一份实用指南
在家庭网络环境中,IP地址扮演着至关重要的角色。大多数家庭用户依赖路由器的DHCP(动态主机配置协议)来自动分配IP地址,但在某些情况下,手动设置静态IP地址能为家庭网络带来更多的便利性与稳定性,尤其是在涉…...

qt QFile详解
1、概述 QFile类是Qt框架中用于读取和写入文本和二进制文件资源的I/O工具类。它继承自QFileDevice类,后者又继承自QIODevice类。QFile类提供了一个接口,允许开发者以二进制模式或文本模式对文件进行读写操作。默认情况下,QFile假定文件内容为…...

ESP8266 自定义固件烧录-Tcpsocket固件
一、固件介绍 固件为自定义开发的一个适配物联网项目的开源固件,支持网页配网、支持网页tcpsocket服务器配置、支持串口波特率设置。 方便、快捷、稳定! 二、烧录说明 固件及工具打包下载地址: https://download.csdn.net/download/flyai…...

内网项目,maven本地仓库离线打包,解决Cannot access central in offline mode?
背景: 内网项目打包,解决Cannot access central in offline mode? 1、修改maven配置文件: localRepository改为本地仓库位置 <localRepository>D:\WorkSpace\WorkSoft\maven-repository\iwhalecloud-repository\business</loca…...

stack和queue --->容器适配器
不支持迭代器,迭代器无法满足他们的性质 边出边判断 实现 #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<stack> #include<queue> using namespace std; int main() {stack<int> st;st.push(1);st.push(2);st.push(3);…...

ffmpeg视频解码
一、视频解码流程 使用ffmpeg解码视频帧主要可分为两大步骤:初始化解码器和解码视频帧,以下代码以mjpeg为例 1. 初始化解码器 初始化解码器主要有以下步骤: (1)查找解码器 // 查找MJPEG解码器pCodec avcodec_fin…...

前端入门一之CSS知识详解
前言 CSS是前端三件套之一,在MarkDown中也完美兼容这些语法;这篇文章是本人大一学习前端的笔记;欢迎点赞 收藏 关注,本人将会持续更新。 文章目录 Emmet语法:CSS基本语法:css语法结构只有3种:…...

【JS学习】10. web API-BOM
文章目录 Web APIs - 第5天笔记js组成window对象定时器-延迟函数location对象navigator对象histroy对象本地存储(今日重点)localStorage(重点)sessionStorage(了解)localStorage 存储复杂数据类型 综合案例…...

C#实现递归获取所有父级的列表
条件: 父级的id是子级的父id形成递归条件 实现功能: 获取自己到最顶级父级的列表(假如最顶级父级的父ID0) 代码: 解释:CF_CODE是自己的ID,CF_PARENT_ID是父id /// <summary>/// 递归获…...

【深度学习】梯度累加和直接用大的batchsize有什么区别
梯度累加与使用较大的batchsize有类似的效果,但是也有区别 1.内存和计算资源要求 梯度累加: 通过在多个小的mini-batch上分别计算梯度并累积,梯度累积不需要一次加载所有数据,因此显著减少了内存需求。这对于显存有限的设别尤为重…...

【Linux】网络相关的命令
目录 ① ip addr show ② ip route show ③ iptables -nvL ④ ping -I enx00e04c6666c0 192.168.1.100 ⑤ ip route get 192.168.1.100 ⑥ sudo ip addr add dev enx00e04c6666c0 192.168.1.101/24 ⑦ ifconfig ⑧ netstat ⑨ traceroute ⑩ nslookup ① ip addr sho…...

leetcode哈希表(五)-四数相加II
题目 454.四数相加II 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足: 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 示例 1: 输入&…...

Java学习路线:Maven(一)认识Maven
目录 认识Maven 新建Maven文件 导入依赖 认识Maven Maven是一个Java的项目管理工具,通过Maven,我们可以实现: 项目自动构建,包括代码的编译、测试、打包、安装等依赖管理,快速完成依赖的导入 在学习Maven之前&…...

【深度学习】— 多输入多输出通道、多通道输入的卷积、多输出通道、1×1 卷积层、汇聚层、多通道汇聚层
【深度学习】— 多输入多输出通道、多通道输入的卷积、多输出通道、11 卷积层、汇聚层、多通道汇聚层 多输入多输出通道多通道输入的卷积示例:多通道的二维互相关运算 多输出通道实现多通道输出的互相关运算 11 卷积层11 卷积的作用 使用全连接层实现 11 卷积小结 …...

java mapper 的 xml讲解
<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.bnc.s12.mapper.GoodaCateDT…...

全面解析:区块链技术及其应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 全面解析:区块链技术及其应用 文章目录 全面解析:区块链技术及其应用什么是区块链区块链的工作原理1. 分…...

python基础学习笔记
本文类比c语言讲解python 一.变量和类型 前缀小知识: 注意:1.python写每一行代码时,结尾不需要 ; 这点是和c语言有很大区别的 2.代码的缩进(就是每行代码前面的空格)是非常重要的后文会提到 1.定义变量 注意: 和C/C …...