Spark SQL基础

SparkSQL基本介绍

什么是Spark SQL

Spark SQL是Spark多种组件中其中一个,主要是用于处理大规模的结构化数据

什么是结构化数据: 一份数据, 每一行都有固定的列, 每一列的类型都是一致的 我们将这样的数据称为结构化的数据
例如: mysql的表数据
1 张三 20
2 李四 15
3 王五 18
4 赵六 12

Spark SQL 的优势

1- Spark SQL 既可以编写SQL语句, 也可以编写代码, 甚至可以混合使用
2- Spark SQL 可以 和 HIVE进行集成, 集成后, 可以替换掉HIVE原有MR的执行引擎, 提升效率

Spark SQL特点:

1- 融合性: 既可以使用标准SQL语言, 也可以编写代码, 同时支持混合使用

2- 统一的数据访问: 可以通过统一的API来对接不同的数据源

3- HIVE的兼容性: Spark SQL可以和HIVE进行整合, 整合后替换执行引擎为Spark, 核心: 基于HIVE的metastore来处理

4- 标准化连接: Spark SQL也是支持 JDBC/ODBC的连接方式

Spark SQL与HIVE异同

相同点:

1- 都是分布式SQL计算引擎
2- 都可以处理大规模的结构化数据
3- 都可以建立Yarn集群之上运行

不同点:

1- Spark SQL是基于内存计算, 而HIVE SQL是基于磁盘进行计算的
2- Spark SQL没有元数据管理服务(自己维护), 而HIVE SQL是有metastore的元数据管理服务的
3- Spark SQL底层执行Spark RDD程序, 而HIVE SQL底层执行是MapReduce
4- Spark SQL可以编写SQL也可以编写代码,但是HIVE SQL仅能编写SQL语句

Spark SQL的数据结构对比

在这里插入图片描述

说明:
	pandas的DataFrame: 二维表  处理单机结构数据
	Spark Core: 处理任何的数据结构   处理大规模的分布式数据
	Spark SQL: 二维表  处理大规模的分布式结构数据

在这里插入图片描述

RDD: 存储直接就是对象, 比如在图中, 存储就是一个Person的对象, 但是里面是什么数据内容, 不太清楚

DataFrame: 将Person的中各个字段数据, 进行结构化存储, 形成一个DataFrame, 可以直接看到数据

Dataset: 将Person对象中数据都按照结构化的方式存储好, 同时保留的对象的类型, 从而知道来源于一个Person对象

由于Python不支持泛型, 所以无法使用Dataset类型, 客户端仅支持DataFrame类型

Spark SQL构建SparkSession对象

from pyspark import SparkConf, SparkContext
import os
from pyspark.sql import SparkSession

# 绑定指定的Python解释器
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

if __name__ == '__main__':
    # 创建SparkSQL中的顶级对象SparkSession
    # alt+回车
    """
        注意事项:
        1- SparkSession和builder都没有小括号
        2- appName():给应用程序取名词。等同于SparkCore中的setAppName()
        3- master():设置运行时集群类型。等同于SparkCore中的setMaster()
    """
    spark = SparkSession.builder\
        .appName('create_sparksession_demo')\
        .master('local[*]')\
        .getOrCreate()

    # 通过SparkSQL的顶级对象获取SparkCore中的顶级对象
    sc = spark.sparkContext

    # 释放资源
    sc.stop()
    spark.stop()

DataFrame详解

DataFrame基本介绍

在这里插入图片描述

DataFrame表示的是一个二维的表。二维表,必然存在行、列等表结构描述信息

表结构描述信息(元数据Schema): StructType对象
字段: StructField对象,可以描述字段名称、字段数据类型、是否可以为空
行: Row对象
列: Column对象,包含字段名称和字段值

在一个StructType对象下,由多个StructField组成,构建成一个完整的元数据信息

如何构建表结构信息数据:
在这里插入图片描述

DataFrame的构建方式

通过RDD得到一个DataFrame

from pyspark import SparkConf, SparkContext
import os
from pyspark.sql import SparkSession

# 绑定指定的Python解释器
from pyspark.sql.types import StructType, IntegerType, StringType, StructField

os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

if __name__ == '__main__':
    # 1- 创建SparkSession对象
    spark = SparkSession.builder\
        .appName('rdd_2_dataframe')\
        .master('local[*]')\
        .getOrCreate()

    # 通过SparkSession得到SparkContext
    sc = spark.sparkContext

    # 2- 数据输入
    # 2.1- 创建一个RDD
    init_rdd = sc.parallelize(["1,李白,20","2,安其拉,18"])

    # 2.2- 将RDD的数据结构转换成二维结构
    new_rdd = init_rdd.map(lambda line: (
            int(line.split(",")[0]),
            line.split(",")[1],
            int(line.split(",")[2])
        )
    )

    # 将RDD转成DataFrame:方式一
    # schema方式一
    schema = StructType()\
        .add('id',IntegerType(),False)\
        .add('name',StringType(),False)\
        .add('age',IntegerType(),False)


    # schema方式二
    schema = StructType([
        StructField('id',IntegerType(),False),
        StructField('name',StringType(),False),
        StructField('age',IntegerType(),False)
    ])

    # schema方式三
    schema = "id:int,name:string,age:int"

    # schema方式四
    schema = ["id","name","age"]

    init_df = spark.createDataFrame(
        data=new_rdd,
        schema=schema
    )

    # 将RDD转成DataFrame:方式二
    """
        toDF:中的schema既可以传List,也可以传字符串形式的schema信息
    """
    # init_df = new_rdd.toDF(schema=["id","name","age"])
    init_df = new_rdd.toDF(schema="id:int,name:string,age:int")

    # 3- 数据处理
    # 4- 数据输出
    init_df.show()
    init_df.printSchema()

    # 5- 释放资源
    sc.stop()
    spark.stop()

运行结果截图:
在这里插入图片描述
场景:RDD可以存储任意结构的数据;而DataFrame只能处理二维表数据。在使用Spark处理数据的初期,可能输入进来的数据是半结构化或者是非结构化的数据,那么我可以先通过RDD对数据进行ETL处理成结构化数据,再使用开发效率高的SparkSQL来对后续数据进行处理分析。

内部初始化数据得到DataFrame

from pyspark import SparkConf, SparkContext
import os

# 绑定指定的Python解释器
from pyspark.sql import SparkSession

os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

if __name__ == '__main__':
    print("内部初始化数据得到DataFrame。类似SparkCore中的parallelize")

    # 1- 创建SparkSession顶级对象
    spark = SparkSession.builder\
        .appName('inner_create_dataframe')\
        .master('local[*]')\
        .getOrCreate()

    # 2- 数据输入
    """
        通过createDataFrame创建DataFrame,schema数据类型可以是:DataType、字符串、List
            字符串:格式要求
                格式一 字段1 字段类型,字段2 字段类型
                格式二(推荐) 字段1:字段类型,字段2:字段类型
                
            List:格式要求
                ["字段1","字段2"]
    """
    # 内部初始化数据得到DataFrame
    init_df = spark.createDataFrame(
        data=[(1,'张三',18),(2,'李四',30)],
        schema="id:int,name:string,age:int"
    )

    # init_df = spark.createDataFrame(
    #     data=[(1, '张三', 18), (2, '李四', 30)],
    #     schema="id int,name string,age int"
    # )

    # init_df = spark.createDataFrame(
    #     data=[(1, '张三', 18), (2, '李四', 30)],
    #     schema=["id","name","age"]
    # )

    # init_df = spark.createDataFrame(
    #     data=[(1, '张三', 18), (2, '李四', 30)],
    #     schema=["id:int", "name:string", "age:int"]
    # )

    # 3- 数据处理
    # 4- 数据输出
    # 输出dataframe的数据内容
    init_df.show()

    # 输出dataframe的schema信息
    init_df.printSchema()

    # 5- 释放资源
    spark.stop()

运行结果截图:
在这里插入图片描述
场景:一般用在开发和测试中。因为只能处理少量的数据
Schema总结
通过createDataFrame创建DataFrame,schema数据类型可以是:DataType、字符串、List
1: 字符串
格式一 字段1 字段类型,字段2 字段类型
格式二(推荐) 字段1:字段类型,字段2:字段类型

2: List
[“字段1”,“字段2”]

3: DataType(推荐,用的最多)
格式一 schema = StructType()
.add(‘id’,IntegerType(),False)
.add(‘name’,StringType(),True)
.add(‘age’,IntegerType(),False)

格式二 schema = StructType([
StructField(‘id’,IntegerType(),False),
StructField(‘name’,StringType(),True),
StructField(‘age’,IntegerType(),False)
])

读取外部文件

复杂API

统一API格式: 
sparksession.read
	.format('text|csv|json|parquet|orc|avro|jdbc|.....') # 读取外部文件的方式
	.option('k','v') # 选项  可以设置相关的参数 (可选)
	.schema(StructType | String) #  设置表的结构信息
	.load('加载数据路径') # 读取外部文件的路径, 支持 HDFS 也支持本地

简写API

格式: 
	spark.read.读取方式()
	
例如: 
	df = spark.read.csv(
   		path='file:///export/data/spark_sql/data/stu.txt',
        header=True,
        sep=' ',
        inferSchema=True,
        encoding='utf-8',
    )
Text方式读取
from pyspark import SparkConf, SparkContext
import os
from pyspark.sql import SparkSession

# 绑定指定的Python解释器
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

if __name__ == '__main__':
    print("text方式读取文件")

    # 1- 创建SparkSession对象
    spark = SparkSession.builder\
        .appName('text_demo')\
        .master('local[*]')\
        .getOrCreate()

    # 2- 数据输入
    """
        load:支持读取HDFS文件系统和本地文件系统
            HDFS文件系统:hdfs://node1:8020/文件路径
            本地文件系统:file:///文件路径
            
        text方式读取文件总结:
            1- 不管文件中内容是什么样的,text会将所有内容全部放到一个列中处理
            2- 默认生成的列名叫value,数据类型string
            3- 我们只能够在schema中修改字段value的名称,其他任何内容不能修改
    """
    init_df = spark.read\
        .format('text')\
        .schema("my_field string")\
        .load('file:///export/data/stu.txt')

    # 3- 数据处理
    # 4- 数据输出
    init_df.show()
    init_df.printSchema()

    # 5- 释放资源
    spark.stop()

运行结果截图:
在这里插入图片描述
text方式读取文件总结:
1- 不管文件中内容是什么样的,text会将所有内容全部放到一个列中处理
2- 默认生成的列名叫value,数据类型string
3- 我们只能够在schema中修改字段value的名称,其他任何内容不能修改

CSV方式读取
from pyspark import SparkConf, SparkContext
import os
from pyspark.sql import SparkSession

# 绑定指定的Python解释器
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

if __name__ == '__main__':
    print("csv方式读取文件")

    # 1- 创建SparkSession对象
    spark = SparkSession.builder\
        .appName('csv_demo')\
        .master('local[*]')\
        .getOrCreate()

    # 2- 数据输入
    """
        csv格式读取外部文件总结:
            1- 复杂API和简写API都必须掌握
            2- 相关参数作用说明:
                2.1- path:指定读取的文件路径。支持HDFS和本地文件路径
                2.2- schema:手动指定元数据信息
                2.3- sep:指定字段间的分隔符
                2.4- encoding:指定文件的编码方式
                2.5- header:指定文件中的第一行是否是字段名称
                2.6- inferSchema:根据数据内容自动推断数据类型。但是,推断结果可能不精确
    """
    # 复杂API写法
    init_df = spark.read\
        .format('csv')\
        .schema("id int,name string,address string,sex string,age int")\
        .option("sep"," ")\
        .option("encoding","UTF-8")\
        .option("header","True")\
        .load('file:///export/data/stu.txt')

    # 简写API写法
    # init_df = spark.read.csv(
    #     path='file:///export/data/gz16_pyspark/02_spark_sql/data/stu.txt',
    #     schema="id int,name string,address string,sex string,age int",
    #     sep=' ',
    #     encoding='UTF-8',
    #     header="True"
    # )

    # init_df = spark.read.csv(
    #     path='file:///export/data/stu.txt',
    #     sep=' ',
    #     encoding='UTF-8',
    #     header="True",
    #     inferSchema=True
    # )

    # 3- 数据处理
    # 4- 数据输出
    init_df.show()
    init_df.printSchema()

    # 5- 释放资源
    spark.stop()

csv格式读取外部文件总结:
1- 复杂API和简写API都必须掌握
2- 相关参数作用说明:
2.1- path:指定读取的文件路径。支持HDFS和本地文件路径
2.2- schema:手动指定元数据信息
2.3- sep:指定字段间的分隔符
2.4- encoding:指定文件的编码方式
2.5- header:指定文件中的第一行是否是字段名称
2.6- inferSchema:根据数据内容自动推断数据类型。但是,推断结果可能不精确

JSON方式读取

json的数据内容:

{'id': 1,'name': '张三','age': 20}
{'id': 2,'name': '李四','age': 23,'address': '北京'}
{'id': 3,'name': '王五','age': 25}
{'id': 4,'name': '赵六','age': 29}

代码实现

from pyspark import SparkConf, SparkContext
import os
from pyspark.sql import SparkSession

# 绑定指定的Python解释器
os.environ['SPARK_HOME'] = '/export/server/spark'
os.environ['PYSPARK_PYTHON'] = '/root/anaconda3/bin/python3'
os.environ['PYSPARK_DRIVER_PYTHON'] = '/root/anaconda3/bin/python3'

if __name__ == '__main__':
    # 1- 创建SparkSession对象
    spark = SparkSession.builder\
        .appName('json_demo')\
        .master('local[*]')\
        .getOrCreate()

    # 2- 数据输入
    """
        json读取数据总结:
            1- 需要手动指定schema信息。如果手动指定的时候,字段名称与json中的key名称不一致,会解析不成功,以null值填充
            2- csv/json中schema的结构,如果是字符串类型,那么字段名称和字段数据类型间,只能以空格分隔
    """
    # init_df = spark.read.json(
    #     path='file:///export/data.txt',
    #     schema="id2 int,name string,age int,address string",
    #     encoding='UTF-8'
    # )

    # init_df = spark.read.json(
    #     path='file:///export/data.txt',
    #     schema="id:int,name:string,age:int,address:string",
    #     encoding='UTF-8'
    # )

    init_df = spark.read.json(
        path='file:///export/data.txt',
        schema="id int,name string,age int,address string",
        encoding='UTF-8'
    )
    # 3- 数据输出
    init_df.show()
    init_df.printSchema()

    # 4- 释放资源
    spark.stop()

运行结果截图:
在这里插入图片描述
json读取数据总结:
1- 需要手动指定schema信息。如果手动指定的时候,字段名称与json中的key名称不一致,会解析不成功,以null值填充
2- csv/json中schema的结构,如果是字符串类型,那么字段名称和字段数据类型间,只能以空格分隔

DataFrame的相关API

操作DataFrame一般有二种操作方案:一种为【DSL方式】,另一种为【SQL方式】

SQL方式: 通过编写SQL语句完成统计分析操作
DSL方式: 特定领域语言,使用DataFrame特有的API完成计算操作,也就是代码形式

从使用角度来说: SQL可能更加的方便一些,当适应了DSL写法后,你会发现DSL要比SQL更好用
从Spark角度来说: 更推荐使用DSL方案,此种方案更加利于Spark底层的优化处理

SQL相关的API

  • 创建一个视图/表
df.createTempView('视图名称'): 创建一个临时的视图(表名)
df.createOrReplaceTempView('视图名称'): 创建一个临时的视图(表名),如果视图存在,直接替换
临时视图,仅能在当前这个Spark Session的会话中使用

df.createGlobalTempView('视图名称'): 创建一个全局视图,运行在一个Spark应用中多个spark会话中都可以使用。在使用的时候必须通过 global_temp.视图名称 方式才可以加载到。较少使用
  • 执行SQL语句
spark.sql('书写SQL')

DSL相关的API

  • show():用于展示DF中数据, 默认仅展示前20行
    • 参数1:设置默认展示多少行 默认为20
    • 参数2:是否为阶段列, 默认仅展示前20个字符数据, 如果过长, 不展示(一般不设置)
  • printSchema():用于打印当前这个DF的表结构信息
  • select():类似于SQL中select, SQL中select后面可以写什么, 这样同样也一样
  • filter()和 where():用于对数据进行过滤操作, 一般在spark SQL中主要使用where
  • groupBy():用于执行分组操作
  • orderBy():用于执行排序操作
DSL主要支持以下几种传递的方式:  str | Column对象 | 列表
	str格式:  '字段'
	Column对象:  
		DataFrame含有的字段  df['字段']
		执行过程新产生:  F.col('字段')
	列表: 
		['字段1','字段2'...]
		[df['字段1'],df['字段2']]

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为了能够支持在编写Spark SQL的DSL时候,在DSL中使用SQL函数,专门提供一个SQL的函数库。直接加载使用即可

导入这个函数库: import pyspark.sql.functions as F
通过F调用对应的函数即可。SparkSQL中所支持的函数,都可以通过以下地址查询到: 

https://spark.apache.org/docs/3.1.2/api/sql/index.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/315834.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用通俗易懂的方式讲解:一文讲透主流大语言模型的技术原理细节

大家好,今天的文章分享三个方面的内容: 1、比较 LLaMA、ChatGLM、Falcon 等大语言模型的细节:tokenizer、位置编码、Layer Normalization、激活函数等。 2、大语言模型的分布式训练技术:数据并行、张量模型并行、流水线并行、3D …

基于JAVA的数据可视化的智慧河南大屏 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 数据模块 A4.2 数据模块 B4.3 数据模块 C4.4 数据模块 D4.5 数据模块 E 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的数据可视化的智慧河南大屏,包含了GDP、…

Mysql如何优化慢查询

如何优化慢查询 慢 SQL 的优化,主要从两个方面考虑,SQL 语句本身的优化,以及数据库设计的优化。 1、避免不必要的列 覆盖索引会导致回表,且增大了IO 2、分页优化 深分页解决方案 使用子查询in 使用连接表 left join 使用游标&a…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子管理实现

锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

131基于matlab的差分进化算法优化K均值聚类问题

基于matlab的差分进化算法优化K均值聚类问题,可调整K参数得到最佳聚类结果。输出聚类可视化图和优化迭代曲线。可替换自己的数据,程序已调通,可直接运行。 131matlab差分进化算法K均值聚类 (xiaohongshu.com)

解决虚拟机的网络图标不见之问题

在WIN11中,启动虚拟机后,发现网络图标不见了,见下图: 1、打开虚拟机终端 输入“sudo server network-manager stop”,停止网络管理器 输入“cd /回车” , 切换到根目录 输入“cd var回车” ,…

一款快速稳定的漏洞扫描工具【afrog】零基础入门到精通

工具介绍 afrog 是一款快速、稳定的高性能漏洞扫描器。支持用户自定义PoC,内置CVE、CNVD、默认密码、信息泄露、指纹识别、越权访问、任意文件读取、命令执行等多种类型。通过afrog,网络安全专业人员可以快速验证和修复漏洞,这有助于增强他们…

chromedriver 114以后版本下载地址

谷歌浏览器版本经常会升级,chromedriver 也得下载匹配的版本 chromedriver 114以前版本下载地址https://registry.npmmirror.com/binary.html?pathchromedriver/ 找到匹配浏览器版本 查看自己浏览器版本号v120.0 v120.0版本chromedriver下载地址https://google…

impala元数据自动刷新

一.操作步骤 进入CM界面 > Hive > 配置 > 搜索 启用数据库中的存储通知(英文界面搜索:Enable Stored Notifications in Database),并且勾选,注意一定要勾选,配置后面的配置不生效。数据库通知的保留时间默认为2天&#…

二阶贝塞尔曲线生成弧线

概述 本文分享一个二阶贝塞尔曲线曲线生成弧线的算法。 效果 实现 1. 封装方法 class ArcLine {constructor(from, to, num 100) {this.from from;this.to to;this.num num;return this.getPointList();}getPointList() {const { from, to } thisconst ctrlPoint thi…

idea使用docker-compose发布应用程序

非常重要的话说在前头 idea要想使用docker-compose,不能使用ssh创建idea Docker,而需要使用socket创建idea Docker。 socket docker是不安全的,任何人都可以访问你的docker,所以只能测试环境使用,请勿在正式环境使用s…

RT-Thread SMP介绍与移植

SMP:(Symmetrical Multi-Processing)对称多处理,简称SMP,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。 RT-Thread自v4.0.0版本开始支持SMP&a…

超级好看的个人主页源码

源码介绍 超级好看的个人主页源码HTML,使用了 HTML、CSS 和 JavaScript 技术,带音乐播放器 需要修改什么到代码里面自行修改,记事本就可以打开,总之,这个个人主页源码非常漂亮和实用,使用了许多现代的 Web 技术来创建一个响应式、…

个人网站制作 Part 3 用JS添加高级交互(表单验证、动态内容更新) | Web开发项目

文章目录 👩‍💻 基础Web开发练手项目系列:个人网站制作🚀 使用JavaScript进行交互🔨表单验证🔧步骤 1: 添加JavaScript文件🔧步骤 2: 更新表单HTML 🔨动态内容更新🔧步骤…

API设计:从基础到最佳实践

1*vWvkkgG6uvgmJT8GkId98A.png 在这次深入探讨中,我们将深入了解API设计,从基础知识开始,逐步进阶到定义出色API的最佳实践。 作为开发者,你可能对许多这些概念很熟悉,但我将提供详细的解释,以加深你的理解…

冷风机系统的拟定和制冷循环的热力计算

一,冷风机系统的概述 单元式冷风机是一种不带加湿器的非热泵型单元式空气调节机,只能用于夏季降温,按标准 GB/T 17758-1999《单元式空气调节机组》的规定1,单元式冷风机应能使室内温度保持在(18℃-25℃)1℃,相对温度 (…

数据洞察力,驱动企业财务变革

我们不得不面对一个现实,就是数据量的剧增。加上大部分企业并不愿意删除历史数据,以防未来预测分析时需要,这造成数据就像一个雪球,越滚越大。然而,过多的数据和数据不足一样会成为企业发展和理解分析的障碍。从海量数…

Android Studio安卓读取EM4100 TK4100卡卡号源码

本示例使用的读卡器&#xff1a;https://item.taobao.com/item.htm?spma1z10.5-c.w4002-21818769070.35.44005b43nb1q2h&id562957272162 <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmln…

Python学习从0到1 day3 python变量和debug

没关系&#xff0c;这破败的生活压不住我 ——24.1.13 一、变量的定义 1.什么是量&#xff1f; 量是程序运行中的最小单元 2.什么是变量呢&#xff1f; ①变量是存储数据的容器 ②变量存储的数据时临时的&#xff0c;变量只有在程序运行过程中是有效的&#xff0c;当程序执行结…

TreesVariety

树木品种 - 树木和植物捆绑包。与“植被引擎”兼容的包装 通用和HDRP的树木包在这里 树木品种: ● 支持Unity Wind; ● 11种树木,7种植物; ● Unity树创建器树(可编辑); ● 与内置管道配合使用; ● 支持地形广告牌。 树木: ● 8棵桦树; ● 4块枫木; ● 8块橡木; ●…