Web framework-Gin(二)
目录
一、Gin
1、Ajax
2、文件上传
2.1、form表单中文件上传(单个文件)
2.2、form表单中文件上传(多个文件)
2.3、ajax上传单个文件
2.4、ajax上传多个文件
3、模板语法
4、数据绑定
5、路由组
6、中间件
一、Gin
1、Ajax
AJAX 即“Asynchronous Javascript And XML”(异步 JavaScript和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
AJAX的最大的特点: 异步访问,局部刷新。
案例:Ajax之验证用户名是否被占用
main.go
func main() {r := gin.Default()r.LoadHTMLGlob("part02/templates/**/*")//指定js文件:r.Static("/s", "part02/static")r.GET("/test1", myfunc.Test1)r.POST("/getUserInfo", myfunc.Test2)r.POST("/ajaxpost", myfunc.Test3)r.Run()
}
myfunc.go
func Test1(context *gin.Context) {context.HTML(200, "demo01/hello01.html", nil)
}func Test3(context *gin.Context) {//获取post-ajax请求的数据,获取对应的参数:uname := context.PostForm("uname")fmt.Println(uname)fmt.Println(uname == "丽丽")if uname == "丽丽" {context.JSON(200, gin.H{"msg": "用户名重复了!",})} else {context.JSON(200, gin.H{"msg": "",})}
}
hello01.html 注意:引入jQuery.min.js
{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="/s/css/mycss.css"><script src="/s/js/jQuery.min.js"></script>
</head>
<body>用户form表单<br><form action="/getUserInfo" method="post">用户名:<input type="text" name="username" id="uname"><span id="errmsg"></span><br>密码:<input type="password" name="pwd"><input type="submit" value="提交"></form><script>//获取用户名的文本框var unametext = document.getElementById("uname");//给文本框绑定一个事件:失去焦点的时候会触发后面的函数的事件unametext.onblur = function () {//获取文本框的内容:var uname = unametext.value;//alert(uname)可以弹出数据,验证代码的正确性//局部刷新:通过ajax技术来实现数据的校验 ---》 后台 :异步访问,局部刷新//调用ajax方法需要传入json格式的数据: $.ajax({属性名:属性值,属性名:属性值,方法名:方法})$.ajax({url : "/ajaxpost",//请求路由type : "POST",//请求类型 GET、POSTdata : {//向后端发送的数据,以json格式向后传递"uname" : uname},success : function (info) {//后台响应成功会调用函数,info-后台响应的数据封装到info中,info名字可以随便起document.getElementById("errmsg").innerText = info["msg"]},fail : function () {后台响应失败会调用函数}})}</script>
</body>
</html>
{{end}}
测试:

2、文件上传
2.1、form表单中文件上传(单个文件)
main.go
func main() {r := gin.Default()r.LoadHTMLGlob("part03/templates/**/*")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test2)r.Run()
}
myfunc.go
func Test1(context *gin.Context) {context.HTML(200, "demo01/hello01.html", nil)
}func Test2(context *gin.Context) {//获取前端传入的文件:file, _ := context.FormFile("myfile")fmt.Println(file.Filename)//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)//响应一个字符串:context.String(200, "文件上传成功")
}
hello01.html
{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="/s/css/mycss.css">
</head>
<body>用户form表单<br><form action="/savefile" method="post" enctype="multipart/form-data"><input type="file" name="myfile"><input type="submit" value="提交"></form>
</body>
</html>
{{end}}
测试:


2.2、form表单中文件上传(多个文件)
main.go
func main() {r := gin.Default()r.LoadHTMLGlob("part03/templates/**/*")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test3)r.Run()
}
myfunc.go
func Test3(context *gin.Context) {//先获取form表单form, _ := context.MultipartForm()//在form表单中获取name相同的文件:files := form.File["myfile"] //File是个Map,通过key获取value部分//files就是name相同的多个文件:挨个处理---遍历处理:for _, file := range files {//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)}//响应一个字符串:context.String(200, "文件上传成功")
}
hello01.html
{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="/s/css/mycss.css">
</head>
<body>用户form表单<br><form action="/savefile" method="post" enctype="multipart/form-data"><input type="file" name="myfile"><input type="file" name="myfile"><input type="file" name="myfile"><input type="submit" value="提交"></form>
</body>
</html>
{{end}}
测试:


2.3、ajax上传单个文件
注意利用ajax上传文件的话,在ajax中需要加两个参数:
(1)contentType:false
默认为true,当设置为true的时候,jquery ajax 提交的时候不会序列化 data,而是直接使用data
(2)processData:false,
目的是防止上传文件中出现分界符导致服务器无法正确识别文件起始位置。
main.go
func main() {r := gin.Default()r.LoadHTMLGlob("part04/templates/**/*")r.Static("/s", "part04/static")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test4)r.Run()
}
myfunc.go
func Test4(context *gin.Context) {//获取前端传入的文件:file, _ := context.FormFile("file")fmt.Println(file.Filename)//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)//响应一个字符串:context.String(200, "文件上传成功")
}
hello01.html
{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="/s/js/jQuery.min.js"></script>
</head>
<body>用户form表单<br><form action="/savefile" method="post"><input type="file" class="myfile" multiple="multiple"><input type="button" value="提交按钮" id="btn"></form><script>//获取按钮var btn = document.getElementById("btn");//给按钮加入一个单击事件:btn.onclick = function () {//创建存放form表单的数据:var form_data = new FormData();//在form_data添加要传入到后台的元素:form_data.append("file",$(".myfile")[0].files[0])//利用ajax向后台传递数据:$.ajax({url : "/savefile",type : "POST",data : form_data,contentType:false,processData:false,success : function () {}})}</script>
</body>
</html>
{{end}}
2.4、ajax上传多个文件
main.go
func main() {r := gin.Default()r.LoadHTMLGlob("part04/templates/**/*")r.Static("/s", "part04/static")r.GET("/userindex", myfunc.Test1)r.POST("/savefile", myfunc.Test5)r.Run()
}
myfunc.go
func Test5(context *gin.Context) {//先获取form表单form, _ := context.MultipartForm()//在form表单中获取name相同的文件:files := form.File["myfile"] //File是个Map,通过key获取value部分//files就是name相同的多个文件:挨个处理---遍历处理:for _, file := range files {//加入一个时间戳:time_int := time.Now().Unix()time_str := strconv.FormatInt(time_int, 10) //10:十进制//保存在我的本地:context.SaveUploadedFile(file, "e://"+time_str+file.Filename)}//响应一个字符串:context.String(200, "文件上传成功")
}
hello01.html
{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="/s/js/jQuery.min.js"></script>
</head>
<body>用户form表单<br><form action="/savefile" method="post"><input type="file" class="myfile"><input type="file" class="myfile"><input type="file" class="myfile"><input type="button" value="提交按钮" id="btn"></form><script>//获取按钮var btn = document.getElementById("btn");//给按钮加入一个单击事件:btn.onclick = function () {//创建存放form表单的数据:var form_data = new FormData();//获取多个文件:var myfiles = $(".myfile");//对多个文件进行遍历,每一个添加到form_data中去:for (var i = 0;i < myfiles.length;i++){form_data.append("myfile",myfiles[i].files[0]);}//利用ajax向后台传递数据:$.ajax({url : "/savefile",type : "POST",data : form_data,contentType:false,processData:false,success : function () {}})}</script>
</body>
</html>
{{end}}
响应重定向:是请求服务器后,服务器通知浏览器,让浏览器去自主请求其他资源的一种方式。
3、模板语法
【1】模板
在写动态页面的网站的时候,我们常常将不变的部分提出成为模板,可变部分通过后端程序的渲染来生成动态网页,golang也支持模板渲染。
【2】模板内内嵌的语法支持,全部需要加 {{}} 来标记。
【3】在模板文件内, . 代表了当前位置的上下文:
(1)在非循环体内,. 就代表了后端传过来的上下文
(2)在循环体中,. 就代表了循环的上下文
【4】在模板文件内, $ 代表了模板根级的上下文
【5】在模板文件内, $. 代表了模板根级的上下文
【6】字符串:{{ “abc,Hello World ” }}
【7】原始字符串:{{ `abc` }} {{ `a` }} 不会转义
【8】字节类型:{{ ' a' }} ---> 97 会转义
【9】打印:
打印字符串: {{ print "Hello World" }}
nil类型:{{ print nil }}
{{define "demo01/hello.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>打印字符串: {{ print "Hello World" }}nil类型:{{ print nil }} 变量的定义:{{$name := "XIAOMING"}}变量的使用:{{$name}}
</body>
</html>
{{end}}
【10】if:
方式1:
{{if .condition}}
{{end}}
方式2:
{{if .condition1}}
{{else}}
{{end}}
方式3:
{{if .condition1}}
{{else if .contition2}}
{{end}}内置的模板函数
not 非
and 与
or 或
eq 等于
ne 不等于
lt 小于 (less than)
le 小于等于
gt 大于
ge 大于等于
【11】range循环
{{range .arr}}{{.}}{{$.age}}{{end}}<br>{{range $i,$v := .arr}}{{$i}}{{$v}}{{end}}
【12】with 关键字
{{ with pipeline }} T1 {{ end }}
{{ with pipeline }} T1 {{ else }} T0 {{ end }}
其中 pipeline 为判断条件,如满足就将 . 设为 pipeline 的值并执行 T1,不修改外面的 . 。
否则执行 T0。
{{define "demo01/hello.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><br>获取结构体中内容:{{.stu.Age}}{{.stu.Name}}<br>启动with关键字:{{with .stu}}{{.Age}}{{.Name}}{{else}}暂无数据{{end}}
</body>
</html>
{{end}}
【13】template:作用:引入另一个模板文件
{{template "模板名" pipeline}}
PS:管道(传递数据的)
PS:引入的模板文件中也要用{ {define "路径"} } { {end} }包含
PS:如果想在引入的模板中也需要获取动态数据,必须使用 . 访问当前位置的上下文
hello.html
{{define "demo01/hello.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><br>内嵌另外模板:{{/* 如果想要传递内容到内嵌模板中,可以通过.上下文进行传递,和内嵌页面共享上下文数据*/}}{{template "templates/demo01/hello2.html" .}}
</body>
</html>
{{end}}
hello2.html
{{define "templates/demo01/hello2.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>这是一个内嵌页面。。。{{with .stu}}{{.Age}}{{.Name}}{{else}}暂无数据{{end}}
</body>
</html>
{{end}}
模板函数
【1】print 打印字符串
【2】printf 按照格式化的字符串输出
格式:参照:Go中:fmt.Sprintf
【3】len 返回对应类型的长度(map, slice, array, string, chan)
【4】管道传递符: |
函数中使用管道传递过来的数值
【5】括号提高优先级别:()
【6】and 只要有一个为空,则整体为空;如果都不为空,则返回最后一个
【7】or 只要有一个不为空,则返回第一个不为空的;如果都是空,则返回空
【8】not 用于判断返回布尔值,如果有值则返回false,没有值则返回true
【9】index 读取指定类型对应下标的值(map, slice, array, string)
【10】eq:等于equal,返回布尔值
【11】ne:不等于 not equal,返回布尔值
【12】lt:小于 less than,返回布尔值
【13】le:小于等于less equal,返回布尔值
【14】gt:大于 greater than,返回布尔值
【15】ge:大于等于 greater equal,返回布尔值
【16】日期格式化 Format
实现了时间的格式化,返回字符串,设置时间格式比较特殊,需要固定方式,不能轻易改变
【17】自定义模板函数:
【17】自定义模板函数:
myfunc.go
// 定义一个函数:
func Add(num1 int, num2 int) int {return num1 + num2
}
main.go注册函数
import ("github.com/gin-gonic/gin""html/template""test_gin/part05/myfunc"
)func main() {r := gin.Default()//注册函数:FuncMap是html/FuncMapr.SetFuncMap(template.FuncMap{//键值对的作用:key指定前端调用的名字,value指定的是后端对应的函数"add": myfunc.Add,})r.LoadHTMLGlob("part05/templates/**/*")r.Static("/s", "part05/static")r.GET("/test1", myfunc.Test1)r.Run()
}
hello01.html使用函数
{{define "demo01/hello01.html"}}
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<br>调用add函数:{{add 11 82}}
</body>
</html>
{{end}}
测试:

4、数据绑定
数据绑定:能够基于请求自动提取JSON、form表单和QueryString类型的数据,并把值绑定到后端指定的结构体对象中去
5、路由组
路由组:将不同的路由按照版本、模块进行不同的分组,利于维护,方便管理。
6、中间件
Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数(中间件函数),这个钩子函数就叫中间件。
中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等等。
Web framework-Gin
Go framework-Beego
难留少年时,总有少年来!
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!
相关文章:
Web framework-Gin(二)
目录 一、Gin 1、Ajax 2、文件上传 2.1、form表单中文件上传(单个文件) 2.2、form表单中文件上传(多个文件) 2.3、ajax上传单个文件 2.4、ajax上传多个文件 3、模板语法 4、数据绑定 5、路由组 6、中间件 一、Gin 1、Ajax AJAX 即“Asynchronous Javascript And XM…...
【聚类】K-Means聚类
cluster:簇 原理: 这边暂时没有时间具体介绍kmeans聚类的原理。简单来说,就是首先初始化k个簇心;然后计算所有点到簇心的欧式距离,对一个点来说,距离最短就属于那个簇;然后更新不同簇的簇心&a…...
超图聚类论文阅读2:Last-step算法
超图聚类论文阅读2:Last-step算法 《使用超图模块化的社区检测算法》 《Community Detection Algorithm Using Hypergraph Modularity》 COMPLEX NETWORKS 2021, SCI 3区 具体实现源码见HyperNetX库 工作:提出了一种用于超图的社区检测算法。该算法的主要…...
React 防抖与节流用法
在React中,防抖和节流是优化性能和提升用户体验的常用技术。下面是它们的用法: 防抖(Debounce):防抖是指在某个事件触发后,等待一段时间后执行回调函数。如果在等待时间内再次触发该事件,将重新…...
发布 VectorTraits v1.0,它是 C# 下增强SIMD向量运算的类库
发布 VectorTraits v1.0, 它是C#下增强SIMD向量运算的类库 VectorTraits: SIMD Vector type traits methods (SIMD向量类型的特征方法). NuGet: https://www.nuget.org/packages/VectorTraits/1.0.0 源代码: https://github.com/zyl910/VectorTraits 用途 总所周知&#x…...
HCIA自学笔记01-冲突域
共享式网络(用同一根同轴电缆通信)中可能会出现信号冲突现象。 如图是一个10BASE5以太网,每个主机都是用同一根同轴电缆来与其它主机进行通信,因此,这里的同轴电缆又被称为共享介质,相应的网络被称为共享介…...
3D封装技术发展
长期以来,芯片制程微缩技术一直驱动着摩尔定律的延续。从1987年的1um制程到2015年的14nm制程,芯片制程迭代速度一直遵循摩尔定律的规律,即芯片上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍。但2015年以后,芯片制…...
探讨下live555用的编程设计模式
这个应该放到这里 7.live555mediaserver-第1阶段小结(完整对象图和思维导图) https://blog.csdn.net/yhb1206/article/details/127330771 但是想想,还是拿出来吧。 从这第1阶段就能发现,它实质用到了reactor网络编程模式。...
LeetCode 1123. Lowest Common Ancestor of Deepest Leaves【树,DFS,BFS,哈希表】1607
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
centroen 23版本换界面了
旧版本 新版本 没有与操作系统一起打包的ISO文件了,要么先安装系统,再安装Centreon,要么用pve导入OVF文件...
Postman 调用 Microsoft Graph API (InsCode AI 创作助手)
官方配置参考网址: https://learn.microsoft.com/zh-cn/graph/use-postman 获取 Azure AD 应用程序凭据: 在 Azure AD 中注册你的应用程序,并获取客户端ID和客户端密钥。这些凭据将允许你的应用程序与 Microsoft Graph 进行身份验证和访问权限…...
MySql 游标 触发器
游标 1.什么是游标 MySQL游标是一种数据库对象,它用于在数据库查询过程中迭代访问结果集中的每一行。游标可以被看作是一个指向查询结果集的指针,通过移动游标,可以按行读取和处理结果集的数据。在MySQL中,游标可以用于在存储过程…...
浅谈数据治理中的智能数据目录
在数字化转型的战略实施中,很多企业都在搭建自己的业务、数据及人工智能的中台。在同这些企业合作和交流中,越来越体会到数据目录是中台建设的核心和基础。为了更好地提供数据服务,发挥数据价值,用户需要先理解数据和信任数据。 企…...
算法通关村第十七关:青铜挑战-贪心其实很简单
青铜挑战-贪心其实很简单 1. 难以解释的贪心算法 贪心学习法则:直接做题,不考虑贪不贪心 贪心(贪婪)算法 是指在问题尽心求解时,在每一步选择中都采取最好或者最优(最有利)的选择,从而希望能够导致结果最…...
[Vue3 博物馆管理系统] 使用Vue3、Element-plus的Layout 布局构建组图文章
系列文章目录 第一章 定制上中下(顶部菜单、底部区域、中间主区域显示)三层结构首页 第二章 使用Vue3、Element-plus菜单组件构建菜单 第三章 使用Vue3、Element-plus走马灯组件构建轮播图 第四章 使用Vue3、Element-plus tabs组件构建选项卡功能 第五章…...
【LeetCode算法系列题解】第36~40题
CONTENTS LeetCode 36. 有效的数独(中等)LeetCode 37. 解数独(困难)LeetCode 38. 外观数列(中等)LeetCode 39. 组合总和(中等)LeetCode 40. 组合总和 II(中等)…...
java+ssm+mysql电梯管理系统
项目介绍: 使用javassmmysql开发的电梯管理系统,系统包含管理员,监管员、安全员、维保员角色,功能如下: 管理员:系统用户管理(监管员、安全员、维保员);系统公告&#…...
最近读书了吗?林曦老师与你分享来自暄桐课堂的读书方法
近来,大家有在开心读书吗?对于读书,有一个很生动的说法:“无事常读书,一日是四日。若活七十年,便二百八十。”读书帮助我们超越个体生命经验的限制,此时此地的我们,也可借由书本&…...
【AI理论学习】语言模型:从Word Embedding到ELMo
语言模型:从Word Embedding到ELMo ELMo原理Bi-LM总结参考资料 本文主要介绍一种建立在LSTM基础上的ELMo预训练模型。2013年的Word2Vec及2014年的GloVe的工作中,每个词对应一个vector,对于多义词无能为力。ELMo的工作对于此,提出了…...
多功能透明屏,在智能家居领域中,有哪些功能特点?显示、连接
多功能透明屏是一种新型的显示技术,它能够在透明的表面上显示图像和视频,并且具有多种功能。 这种屏幕可以应用于各种领域,如商业广告、智能家居、教育等,为用户提供更加便捷和多样化的体验。 首先,多功能透明屏可以…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
