一个项目的简单结构划分

首先创建一个新项目

可以正常运行与访问

创建配置文件并添加配置。

将这里拆分到不同的文件中,让启动文件更加简洁。

创建一个apps包,导入配置模块,导入Flask,定义创建app函数,返回app对象。实例化的Flask对象做配置,定义模板位置和静态文件位置。添加app config配置,使用来自对象的方法,将配置模块导入到配置中

然后再来写我们的运行程序。导入创建 app函数,创建app,让app点run运行

我们将路由和视图函数写到views里面,这样启动文件就简洁了。我们将配置文件写到一个模块里面,这样创建好Flask对象之后,不用app.config往后堆很多配置,简洁很多。使用app点config点来自对象,将模块作为参数传入进去。

一个项目:比如分用户 商品 订单
一个项目分很多部分。我们不可能把所有的路由放到一个文件。
比如用户,就可以有
用户中心 /center
用户注册 /register
用户登录 /login
用户更新 /upgrade
一个用户部分就有很多路由。那么我们可以项目的一个部分就用一个蓝图,把路由划分成不同的部分。其实蓝图也是路由的另一种方式。

我们在apps下创建视图模块,里面写一个蓝图。蓝图里写了两个视图函数,

user_for('')调用register,如果有endpoint,返回的是endpoint的值,如果没有,返回的是函数的名,这是反向解析。就是给我个名我去找到路径,而不是给个路径我去找到函数名。正常的是给个路由,我给你找到函数名,现在反过来了,你给我函数名我给你找到路由,这就是url_for反向解析,

写完蓝图后导入并注册到app中

注册完了之后就命令行运行app程序并访问

一访问就报错了

因为原来我们是在app上写路由,现在我们用了蓝图了,多了一层,经过蓝图然后写的路由。所以url_for想要反向解析引用函数名,就需要在前面加上蓝图,指定是哪个蓝图下的函数名,然后我们再访问

这样就访问到了默认路由根了。

后端打印出 我们根据字符串反向解析出路径。包括在前端进行反向解析的时候,也要这么写,加上蓝图名称

一个项目

我们这里沿用上面的结构做些修改。

我们将路由和视图函数写到views里面,这样启动文件就简洁了。我们将配置文件写到一个模块里面,这样创建好Flask对象之后,不用app.config往后堆很多配置,简洁很多。使用app点config点来自对象,将模块作为参数传入进去。

项目:比如分用户 商品 订单
一个项目分很多部分。我们不可能把所有的路由放到一个文件。
比如用户,就可以有
用户中心 /center
用户注册 /register
用户登录 /login
用户更新 /upgrade
一个用户部分就有很多路由。那么我们可以项目的一个部分就用一个蓝图,把路由划分成不同的部分。其实蓝图也是路由的另一种方式。

我们可以在apps下创建多个目录,用户目录放用户相关的,商品目录放商品相关,放的可以是蓝图等,比如view模块里面定义蓝图。

现在目录结构如下:

我们根据项目的不同的部分划分。这里创建了三个包,我们现在要写跟用户相关的,所以我们写蓝图在user下面的view模块写蓝图。app,配置还有init文件已经按上面那个写好了。现在只需要把蓝图重新写一下。

程序:

from flask import Flask
import settings
from apps.user.view import user_bp def create_app():
app=Flask(__name__,template_folder='../templates',static_folder='../static')
app.config.from_object(settings)
app.register_blueprint(user_bp)
print(app.url_map)
return app

init文件

from flask import Blueprint

user_bp=Blueprint('user',__name__)

@user_bp.route("/")
def user_center():
return '用户中心'
@user_bp.route('/register',methods=['GET','POST'])
def register():
return '用户注册'
@user_bp.route('/login',methods=['GET','POST'])
def login():
return '用户登录'
@user_bp.route('/logout',methods=['GET','POST'])
def logout():
return '用户注册'

用户下写的蓝图:

现在我们写了四个路由了。这四个路由绑定在蓝图上的,也就是绑定在user蓝图上的。蓝图需要注册到app中,让蓝图和app产生联系。

在apps下的init里面,导入蓝图,在app对象里面注册我们创建的蓝图,我们可以用url_map查看app里的路由,可以看到我们写的四个路由,已经生效了。

我们访问一下看效果:

我们需要定义类,用于与数据库交互用的。在用户目录下创建model模块。写入到这个模块中

现在我们需要写模板了,模板目录创建子目录user,跟用户相关的模板就放到这个目录中。比如我们先创建三个文件,登录,注册和展示用的页面。因为这些页面都有公共的部分。所以我们需要将公共的部分分出来。我们在templates下创建base页面。

母版的写法:
base母版页面的标题也是可能改的,设置成block,默认是用户中心
我们还需要预留我们的css和js。所以母版中再设置css和js块。然后我们创建三个div,分为header center footer.然后定义三者的样式

刚刚的有点问题,右击模板目录,将目录标记为模板目录,使用jinja2语言。这样下面的block就识别出来了

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} 用户中心{% endblock %}</title>
<style>
#head {
height: 50px;
background-color: bisque;
} #head ul {
list-style: none;
height: 50px;
} #head ul li {
float: left;
width: 100px;
text-align: center;
font-size: 18px;
height: 50px;
line-height: 50px;
} #middle {
height: 900px;
background-color: azure;
} #foot {
height: 50px;
line-height: 50px;
background-color: darkseagreen;
}
</style>
{% block mycss %}{% endblock %}
</head>
<body>
<div id="head">
<ul>
<li><a href="">首页</a></li>
<li><a href="">秒杀</a></li>
<li><a href="">超市</a></li>
<li><a href="">图书</a></li>
<li><a href="">会员</a></li>
</ul>
</div>
<div id="middle">
{% block middle %} {% endblock %}
</div>
<div id="foot"> </div> {% block myjs %}{% endblock %}
</body>
</html>

母版文件

母版展示效果如下

我们要写注册页面。我们需要继承母版。修改标题,

{% extends 'base.html' %}
{% block title %}
用户注册
{% endblock %} {% block middle %}
<form action="/register" method="post">
<p><input type="text" name="username" placeholder="用户名"></p>
<p><input type="password" name="password" placeholder="密码"></p>
<p><input type="password" name="repassword" placeholder="确认密码"></p>
<p><input type="number" name="phone" placeholder="手机号码"></p>
<p><input type="submit" value="用户注册"></p>
</form>
{% endblock %}

我们写好前端页面之后。写后端,让注册视图返回这个模板文件看看效果。因为模板目录能找到,文件在子目录中,所以用相对路径就可以找到文件。

效果如下:

我们在创建flask对象的时候,设置了模板文件位置,静态文件位置了。所以flask能找到模板目录。如果在创建flask对象的时候没有设置传参那么就只能把模板目录放到apps下,和init文件同级目录,因为,创建flask对象的时候,内部有默认设置找到创建对象同级目录下的templates目录作为模板目录。同理,我们也要设置一下静态文件目录、。因为我们要将apps和模板目录独立开来,不放到apps下。

接下来我们写post提交数据。点击注册,然后跳转到用户中页面

目前我们的model这个类,可以封装用户的用户名,密码。打印对象会显示用户名。用户数据封装在init方法下面。

用户数据暂时先保存到一个列表中。有一个就追加一个到列表中。将用户类导入进来,创建用户对象,将用户数据封装进对象中。注册后是将用户对象追加到用户对象列表里面了。

然后看一下用户注册的逻辑。

  • 如果是get请求,那么不走post下面的程序,直接走到最后的一个return,返回一个注册页面可以让浏览器展示出来。
  • 如果我们在from的框框里输入数据,点击用户注册,那么就是发送post请求,走post下面的程序。
  • 这时,第一步就是获取post提交的数据。获取form数据,是request点form里去get数据。form返回的是个啥字典的形式数据集,虽然展示不是字典的样子,但是用get可以获取到指定键的值。
  • 对密码和确认密码做判断,两次密码相等才能继续往下走,然后循环用户对象列表,查询前端提交的用户名字是否存在用户对象列表中中。如果存在就返回注册页面和一个错误信息,错误信息显示是用户名已存在。并将信息渲染在模板中。否则,就是用户不存在,继续往下走,用户不存在就可以创建用户对象了。将前端form数据封装到用户对象里,然后将用户对象追加到用户对象列表存储起来。这就相当于保存到数据库了。
  • 保存数据之后就跳转到用户展示页面。这里是用户中心,也就是"/"

查看效果

给我们的注册页面添加上错误显示

<p style="color: red">{{ msg }}</p>

目前缺少很多校验

成功跳转到用户中心页面

接下来写用户中心的页面,用户中心页面是展示用的,那么我们也就返回一个展示模板,因为需要展示用户的,那就将users对象列表传进去。传的方法是变量等于用户对象列表。

用户中心展示页面,我们得知道需要展示哪些新喜,标题,当前用户人数等。然后每个人的信息。这里就做个表格,将后端传进来的用户对象列表做循环。然后点取值

如下,我们进入注册页面,注册后跳转到用户信息页面。这样就将信息都展示出来了。用户信息需要修改和删除按钮、。loop.index应该是循环的索引

我们应当还需要添加。一般数据展示页面,需要增改删按钮,查已经实现了、。

现在我们需要删除

删除一条数据,一个用户。我们需要准确的知道是删除那条数据。点击删除按钮或者是链接,就发送请求,让它请求/del删除路径。这样让它找到删除用户操作的删除视图函数。这个功能的实现需要js来配合实现。前端上是添加一个js点击事件,

下面看下如何添加js点击事件。

在删除a标签上添加点击事件函数传一个字符串用户的名字。这里是根据用户名去删除。下面就添加js代码块。定义js语句。定义js函数,函数是点击事件中调用的函数。function 函数名小括号接收点击事件传给函数的参数,然后花括号定义点击事件发生后的行为。这里暂时是打印在控制台。js函数的调用时,给href链接加上Javascript冒号分号,然后后面接事件类型,事件是点击事件=双引号,双引号里面可以放函数的调用。调用的括号里面可以放给函数的传参。传参这里是传的字符串。传的是一个用户名字这个变量。这样,点击谁,就传参是谁,下面的函数可以定位到对那条数据做删除操作。

点击之后成功打印,说明没有问题。后面再改成删除的行动

删除的逻辑应该是如下:

现在当我们点击删除a链接时,不是打印输出在控制台了。是要发送一个请求。我们这里注释掉a标签的请求,使用调用js函数的方式来做请求。做的是个get请求。也就是删除按钮是个点击事件。当点击这个标签时,调用del函数并传参用户名字给函数。js代码块中定义的del函数接收到传参,知道是哪个用户要被删除,函数要做的动作是想/del路径发送get请求,并拼接上用户名,因为这里是根据用户名来删除,将用户名作为get请求的参数传递给后端视图函数。后端视图函数接收到传参后就可以对该数据做操作了。js中location.href等于一个地址,可以使得函数执行时,对该地址发送一个get请求。拼接键值对用问号,键自己指定,值是js函数传参接收过来的用户名。键值对等号拼接

删除逻辑如下:前端想del发送一个请求,并将用户传到后端了,视图函数中获取get请求中的数据,然后对用户做判断。循环我的用户列表.如果用户对象列表的每个用户名字和前端传递过了的名字相等,那么就将用户从用户对象列表中删除,然后重定向到用户中心页面。如果循环结束之后发现没有匹配到用户,也就没走到重定向这一步,我们可以else否则给它返回一个删除失败。

这下我们点击删除

发现删除成功

注册模板中我们写action地址,我们要访问的是蓝图user下的/register这个路由,但是这个路由也是可能会被修改的。如果被修改了,前端action地址就访问不到了,所以前端不能写死了,我们应该用动态的反向解析的方法去获取到路由地址,从而正确访问到该路由。{{ url_for('user.register') }} 就是通过字符串,能反向解析出路由地址,然后访问路由从而实现向这条路由发起请求。正常来说我们是通过路径找到函数,而我们这里就是通过函数名或endpoint去找到路径,这就是反向解析

接下来我们要做修改的程序

前端设计:

  • 用户点击修改,进入修改页面。也就是在用户展示页面可以个修改a标签加个点击事件,调用修改函数。修改函数的动作就是给修改路径/update发送一个请求,并将用户名字传递给后端,这里是发送一个get请求 ,get请求修改页面,然后展示修改页面。
  • 修改页面要继承母版,修改标题,修改中间的div信息。修改的表单action,是去请求更新的路径,我们后端写一个路由和视图函数,作为修改使用。
  • form的action,最好写成反向解析,用变量引用的方式,url_for ,传参蓝图点endpoint或者函数名,让它找到访问路径,并发起请求
  • 我们这里的有三个字段,那修改也要有三个字段。这里是通过用户名来识别用户的,没有设置用户id,所以修改提交操作后我们不知用户改的是谁,这种情况下我们可以在修改页面添加一个隐藏标签,备注上它的名字。然后写上用户,密码手机号三个标签,更新按钮。因为是修改,当我们在用户展示页点击修改后,向修改页面发送get请求,让后端将修改页面和修改用户的数据都传递过来。然后我们可以在模板的input框中设置默认值,value.
  • 当点击修改的时候,这里是通过js从用户展示页向修改页面/update发送一个get请求,后端/update的get请求我们可以返回修改页面的模板,因为是修改,所以修改的框中欧应该携带修改用户的原本数据才对。我们刚刚从用户展示页发送请求的时候,将点击的用户的名字通过参数的方式传给点击事件函数,函数接收参数,发送get请求拼接携带上用户的名字。后端get请求逻辑代码中,从get请求里获取到用户名字,通过用户名字遍历用户对象列表,如果有名字相等的用户对象,就将该用户传到修改页面模板中,也就是返回用户模板和用户对象。而模板中有定义使用用户对象去渲染出修改前的原数据信息的。

下面看下展示效果

接下来就是写/update路由也就是修改页面的post请求了。

修改逻辑

  • 修改页面当修改完数据需要向修改页面的路由/update发送一个post请求,我们这里的路径是用url_for反向解析,使用蓝图点endpoint去解析出请求路径,然后向路径发起post请求。
  • 前端向/update发起post请求后,后端视图函数走post请求的程序。post请求中有用户提交的数据,在请求点form中,get通过前端name获取对应填写的值。然后遍历用户对象列表,如果用户对象列表中有用户的名字等于隐藏标签的真实名字,也就是未修改前的名字,那么就让用户对象的名字等于新提交的名字,也就是重新赋值,然后让用户对象的其它属性也等于用户新提交的数据,然后给前端展示返回一个更新成功。我们也可以返回一个重定向,重定向到用户展示页面

重定向到用户展示页面效果

目前的程序day042 05:

class User:
def __init__(self, username, password, phone=None):
self.username = username
self.password = password
self.phone = phone def __str__(self):
return self.username

model

from flask import Blueprint,request, render_template, redirect
from apps.user.model import User
user_bp=Blueprint('user',__name__) # 列表保存的是一个一个的用户对象
users = [] @user_bp.route("/")
def user_center():
return render_template('user/show.html',users=users)
@user_bp.route('/del')
def del_user():
# 获取你传递的username
username = request.args.get('username')
# 根据username找到列表中的user对象
for user in users:
if user.username == username:
# 删除user
users.remove(user)
return redirect('/')
else:
return '删除失败'
@user_bp.route('/update', methods=['POST', 'GET'], endpoint='update')
def update_user():
if request.method == 'POST':
realname = request.form.get('realname')
username = request.form.get('username')
password = request.form.get('password')
phone = request.form.get('phone')
for user in users:
if user.username == realname:
user.username = username
user.phone = phone
return redirect('/') else:
# get请求了
username = request.args.get('username')
for user in users:
if user.username == username:
return render_template('user/update.html', user=user) @user_bp.route('/register',methods=['GET','POST'])
def register():
if request.method=='POST':
# 获取post提交的数据
print(request.form)
print(request.form.get('username'))
username = request.form.get('username')
password = request.form.get('password')
phone = request.form.get('phone')
repassword = request.form.get('repassword')
if password == repassword:
# 用户名唯一
for user in users:
if user.username == username:
return render_template('user/register.html', msg='用户名已存在')
# 创建user对象
user = User(username, password, phone)
# 添加到用户列表
users.append(user)
return redirect('/')
return render_template('user/register.html')
@user_bp.route('/login',methods=['GET','POST'])
def login():
return '用户登录'
@user_bp.route('/logout',methods=['GET','POST'])
def logout():
return '用户注册'

view

from flask import Flask
import settings
from apps.user.view import user_bp def create_app():
app=Flask(__name__,template_folder='../templates',static_folder='../static')
app.config.from_object(settings)
app.register_blueprint(user_bp)
return app

init

{% extends 'base.html' %}
{% block title %}
用户注册
{% endblock %} {% block middle %}
<p style="color: red">{{ msg }}</p>
<form action="{{ url_for('user.register') }}" method="post">
<p><input type="text" name="username" placeholder="用户名"></p>
<p><input type="password" name="password" placeholder="密码"></p>
<p><input type="password" name="repassword" placeholder="确认密码"></p>
<p><input type="number" name="phone" placeholder="手机号码"></p>
<p><input type="submit" value="用户注册"></p>
</form>
{% endblock %}

register

{% extends 'base.html' %}
{% block middle %}
<h1>用户信息</h1>
<span>当前用户人数是:{{ users |length }} 人</span>
<table border="1" cellspacing="0" width="60%">
{% for user in users %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.phone }}</td>
<td><a href="javascript:;" onclick="update('{{ user.username }}')" >修改</a>
<a href="javascript:;" onclick="del('{{ user.username }}')">删除</a></td>
</tr>
{% endfor %} </table>
{% endblock %} {% block myjs %}
<script>
function del(username) {
{#console.log(username)#}
{#// location 地址栏对象#}
location.href = '/del?username=' + username
}
//修改的函数
function update(username) {
location.href = '/update?username=' + username
}
</script>
{% endblock %}

用户展示页

{% extends 'base.html' %}
{% block title %}
用户信息修改
{% endblock %}
{% block middle %}
<h1>用户信息更新</h1>
<form action="{{ url_for('user.update') }}" method="post">
<p><input type="hidden" name="realname" value="{{ user.username }}"></p>
<p><input type="text" name="username" placeholder="用户名" value="{{ user.username }}"></p>
<p><input type="password" name="password" placeholder="密码" value="{{ user.password }}" disabled></p>
<p><input type="number" name="phone" placeholder="手机号码" value="{{ user.phone }}"></p>
<p><input type="submit" value="用户更新"></p>
</form>
{% endblock %}

update

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} 用户中心{% endblock %}</title>
<style>
#head {
height: 50px;
background-color: bisque;
} #head ul {
list-style: none;
height: 50px;
} #head ul li {
float: left;
width: 100px;
text-align: center;
font-size: 18px;
height: 50px;
line-height: 50px;
} #middle {
height: 900px;
background-color: azure;
} #foot {
height: 50px;
line-height: 50px;
background-color: darkseagreen;
}
</style>
{% block mycss %}{% endblock %}
</head>
<body>
<div id="head">
<ul>
<li><a href="">首页</a></li>
<li><a href="">秒杀</a></li>
<li><a href="">超市</a></li>
<li><a href="">图书</a></li>
<li><a href="">会员</a></li>
</ul>
</div>
<div id="middle">
{% block middle %} {% endblock %}
</div>
<div id="foot"> </div> {% block myjs %}{% endblock %}
</body>
</html>

base

from apps import create_app

app=create_app()

if __name__ == '__main__':
app.run()

app

ENV="development"
DEBUG=True

setting

flask注册功能的更多相关文章

  1. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(五)——实现注册功能

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  2. Flask实战第44天:完成前台注册功能

    注册功能后端逻辑 用户注册要把注册的表单提交上来,因此,我要先对表单进行验证,编辑front.forms from apps.forms import BaseForm from wtforms im ...

  3. flask 开发用户登录注册功能

    flask 开发用户登录注册功能 flask开发过程议案需要四个模块:html页面模板.form表单.db数据库操作.app视图函数 1.主程序 # app.py # Auther: hhh5460 ...

  4. flask之注册功能

    一:注册功能 1:前端准备表单 # 前端代码 <!DOCTYPE html> <html lang="en"> <head> <meta ...

  5. day101:MoFang:模型构造器ModelSchema&注册功能之手机号唯一验证/保存用户注册信息/发送短信验证码

    目录 1.模型构造器:ModelSchema 1.SQLAlchemySchema 2.SQLAlchemyAutoSchema 2.注册功能基本实现 1.关于手机号码的唯一性验证 2.保存用户注册信 ...

  6. python实现软件的注册功能(机器码+注册码机制)

    http://www.cnblogs.com/cquptzzq/p/5940583.html 一.前言: 目的:完成已有python图像处理工具的注册功能 功能:用户运行程序后,通过文件自动检测认证状 ...

  7. Winform 注册机通用软件注册功能之建立有效的软件保护机制

    本文转载:http://www.cnblogs.com/umplatform/archive/2013/01/23/2873001.html 众所周知,一些共享软件往往提供给使用者的是一个功能不受限制 ...

  8. springMVC+Java验证码完善注册功能

    这篇文章简单的写了一个java验证码,为之前写过的springMVC注册功能加上验证码,验证码的作用就不多说了,防止机器人程序恶意注册什么的.. 其中User.java,加上了password和cod ...

  9. gitlab 取消注册功能

    gitlab 默认安装完成以后是允许用户注册,公司内部使用所以准备禁用了注册功能,只允许管理员从后台开通权限: 1.进入"Admin Area" 2.在左边菜单栏最低下点击&quo ...

  10. 7、ABPZero系列教程之拼多多卖家工具 修改注册功能

    本篇开始进入重头戏,之前的几篇文章都是为了现在的功能作准备.前面教程已经讲到修改User表结构,接下来就需要修改注册逻辑代码. 注册页面 修改Register.cshtml,备注如下代码: 文件路径: ...

随机推荐

  1. npm 直接安装 GitHub/GitLab 仓库代码及 npm link 本地调试

    一.npm 直接安装 GitHub/GitLab 仓库代码 语法 npm install <git remote url> 示例 命令: npm i git@github.com:maze ...

  2. OpenAtom OpenHarmony三方库创建发布及安全隐私检测

    OpenAtom OpenHarmony三方库(以下简称"三方库"或"包"),是经过验证可在OpenHarmony系统上可重复使用的软件组件,可帮助开发者快速开 ...

  3. 【直播回顾】OpenHarmony知识赋能第八期:手把手教你实现涂鸦小游戏

     OpenHarmony第八期知识赋能直播已经在9月29日圆满落幕!从9月15日起,资深OS框架开发工程师巴延兴老师于每周四进行分享,通过实现涂鸦小游戏来帮助大家全面了解ArkUI框架的应用,拓宽知识 ...

  4. 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(2)

    1.问题描述: 开发服务端推送,客户端能收到离线推送,但是推送收到的通知只能从手机顶部下拉看到,无法收到一个顶部的弹框.请问是什么原因? 解决方案: 可能原因一: 消息提醒的方式与消息类别有关,比如: ...

  5. 应用缺少POI数据,如何开发地点深度信息?

    用户在App里搜索某个地点时,并不满足单一的地点信息,希望得到更多可以帮助其做决策的深度信息.例如有打车出行需求的用户,在打车App里搜索地点时可以显示周边的地点,精确到某个路口,让用户可以自由选择合 ...

  6. Ubuntu部署Django三:编写相关配置文件及启动服务

    1. uwsgi 1.1 项目结构如下,你要知道 uwsgi.ini 放在什么位置 projectName |-- app |-- projectName |-- -- wsgi.py |-- -- ...

  7. JS启动Windows上的exe

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. .NET周刊【4月第1期 2024-04-07】

    国内文章 一个程序员的编年史 https://www.cnblogs.com/lunacy/p/18117213 作者拥有15年软件开发经验,曾在多家公司工作,项目和团队起伏充满变数.2007年,在太 ...

  9. 重走py 之路 ——列表(一)

    前言 因为最近公司有python项目维护,所以把python的基础入门的书整理一遍,因为有些忘记了,同时在看<<python编程>>这本书的时候觉得对有基础的有很多的赘余,打算 ...

  10. Pytorch-tensor的创建,索引,切片

    1.基本概念 标量:就是一个数,是0维的,只有大小,没有方向 向量:是1*n的一列数,是1维的,有大小,也有方向 张量:是n*n的一堆数,是2维的,n个向量合并而成 2.a.size(),a.shap ...