吃透Python-第 5 章 对象和类型

吃透Python-第 5 章 对象和类型

在 Python 中,一切皆为对象。为了更好地学习后面的内容,我们先来了解一下对象的本质。

对象和变量
类型和值
引用和绑定
标识值
id 函数
存储空间
赋值语句
del 语句
可变类型
不可变类型
身份运算符(is 运算符和 is not 运算符)
None 和 NoneType 类型
引用计数
浮点型(float 型)的特性和精度
算术转换
用于算术运算的内置函数
按位逻辑运算符(运算符 &、运算符 |、运算符 ^ 和运算符 ~)
位移运算符(运算符 << 和运算符 >>1 的补码和 2 的补码

5-1 对象

前面我们使用了各种类型的变量。Python 将一切皆作为对象来处理,所以我们不妨将 Python 中的一切视为对象,而非变量。

什么是对象
  前面,本书曾将变量解释为“类似于存储值的箱子”。实际上,这是不正确的。在进入下一章的学习之前,我们有必要准确理解变量的概念。

首先来看以下对变量的基本说明。

要点 变量是对象的引用,它只是关联到对象的一个名字。

这种说法有点让人难以理解。我们通过交互式 shell 来进行确认(例 5-1)。

在这里插入图片描述

▶ 注意:打印输出的值受程序运行环境等因素的影响。下文亦然。

把 17 赋给变量 n 后,程序调用了两次 id 函数这一内置函数。id 函数用于返回对象的固有值,即标识值(identity)。

▶ 不同对象的标识值一定不同。

Python 的赋值操作并不是像图 5-1 a 那样对值进行复制。

如图 5-1 b 所示,首先有一个值 17 的 int 型对象。为了引用该对象,程序要使用名称 n 进行绑定(bind)。

在这里插入图片描述

图 5-1 对变量进行赋值

这就是整数字面量 17 的标识值和变量 n 的标识值相同的原因。

第 1 章讲过,给变量赋的值,其类型可以与存储在该变量中的值的类型不同。我们通过例 5-2 来确认变量的这种特性。

在这里插入图片描述

赋值为字符串后,n 的标识值发生了变化。

如图 5-2 所示,变量 n 的引用对象从 int 型的 5 变为了 str 型的 ‘ABC’。

在这里插入图片描述

图 5-2 赋值后引用了新的对象

当然,int 型对象 5 的类型和值都没有发生变化。

要点 在对变量进行赋值操作时,不会复制对象的值,只会引用对象。

下面我们来交换两个值(3-2 节)(例 5-3)。

在这里插入图片描述

变量 a 的标识值和变量 b 的标识值进行了交换。如图 5-3 所示,交换的是变量的引用对象而不是变量的值。

在这里插入图片描述

图 5-3 赋值后交换引用对象

现在,大家应该慢慢理解了 Python 中“没有变量,只有对象”的含义了吧。

各个对象会占一定的存储空间(storage),也就是内存(memory)。因此,标识值一般用存储空间上的地址表示。

要点 在 Python 中,一切皆为对象。对象占一定存储空间,并拥有标识值、类型和值等属性。
▶ 不同的对象拥有不同的标识值,对象能通过标识值来区分。

id 函数用于查看对象的标识值。第 1 章介绍的 type 函数可以查看对象的类型。

可变类型和不可变类型
  前面的例子只进行了赋值操作并打印输出标识值。下面对变量进行运算,并确认变量值的变化情况。首先是整数(例 5-4)。

在这里插入图片描述

使用增量赋值运算符 += 对 n 的值进行递增后,n 的标识值发生了变化。

如图 5-4 所示,n 的引用对象从 int 型对象 12 变为 int 型对象 13。
在这里插入图片描述

图 5-4 更新整数值(更新引用对象)

数字和字符串是不可变类型,一旦赋值就不可以改变。

有人可能会反驳说变量 n 的值可以改变,但其实并非如此。正因为整数对象 12 的值不可以改变,所以我们才对 n(的引用对象)进行更新,以引用另一个整数对象 13。

▶ immutable 的意思是“不可变的”,下文提到的 mutable 的意思是“可变的”。

字符串也是如此。我们可以通过例 5-5 进行确认。

在这里插入图片描述

程序生成了新的字符串,在字符串拼接后,s 的标识值发生了变化(图 5-5)。

在这里插入图片描述

图 5-5 更新字符串(更新引用对象)

Python 有两种类型,分别是不可变类型和可变类型。其中,可变类型的值在给定后可以发生改变。

要点 Python 的类型根据值是否可变分为两类。

可变类型:列表、字典、集合等      ※值可以改变。
不可变类型:数字、字符串、元组等    ※值不可以改变。

另外,可变类型对象和不可变类型对象都不能更改类型本身。

身份运算符(is 运算符和 is not 运算符)
  第 3 章讲解的比较运算符 == 和 !=,正如其名字表达的含义一样,是判断对象的值是否相等的运算符。因此,即使 x 和 y 是不同的对象,只要它们的值相等或者不相等,相应的运算符判断就能成立。

表 5-1 的身份运算符与比较运算符相似却不同。is 运算符和 is not 运算符用于判断对象本身是否相同,即对象本身是否具有同一性,不用于判断对象的值是否相等。

▶ 具体来说,身份运算符用于判断等号两边对象的标识值是否相等。像 a is b is c 这样连续使用该运算符的效果,与用 and 进行结合的效果相同。

表 5-1 身份运算符

在这里插入图片描述

代码清单 5-1 是判断两个变量同一性的示例程序。

在这里插入图片描述

程序读取变量 a 的值和变量 b 的值后判断它们是否相同。

图 5-6 显示了两个运行结果中变量和对象的情况。

在这里插入图片描述

图 5-6 变量的同一性(is 运算符和 is not 运算符)

在读取相同值的例子中,因为两个变量引用了相同的对象,所以 a is b 求值后为 True。

这里,程序使用了不可变的 int 型,而实际中程序一般会使用 is 运算符和 is not 运算符比较可变对象,或将可变对象与 None 进行比较。

▶ 存在值相同但标识值不同的情况(后面的章节会介绍)。

赋值语句
  第 1 章介绍过,用于赋值的分隔符 = 不是运算符,而且赋值语句的内涵非常丰富。学到这里,相信大家对赋值语句已经有了一定的理解,现在我们来做一下总结。

在使用赋值语句时:

  1等号右边的值没有复制到等号左边。

  2等号左边的变量名绑定到等号右边的对象(使变量可以引用对象)。

  3等号左边的变量名如果是第一次使用,则新生成一个变量。
3的内容和作用域相关,所以规则比较复杂,第 9 章我将对此进行详细介绍。

del 语句
  与赋值语句相对的是 del 语句(del statement)。del 语句用于删除只作为名字的变量。我们通过例 5-6 来进行确认。

在这里插入图片描述

删除变量 x 后,如果输出 x 的值就会产生错误。

▶ 例 5-6 是有意设计的示例。在实际的程序中,我们可以使用 del 语句删除列表中的元素。

del 语句解除了名称与对象的绑定。如果该名称是对象的唯一引用,程序就能释放该对象的内存(第 117 页的专栏 5-1)。

▶ 使用 del 语句释放对象后,该对象的标识值可以被之后生成的其他对象使用。

None
  NoneType 类型(NoneType type)的 None 可以识别任何对象。None 是一种特殊的值,用于区分“空值”和“不存在的值”。

None 是拥有 NoneType 类型的值的唯一对象。另外,None 的标识值可以通过 id(None) 查看。None 的标识值与其他对象的标识值都不同。

如果对 None 求逻辑值会得到“假”。但 None 本身并不是逻辑值 False。

▶ 整数 0、浮点数 0.0、空字符串 ''、空列表 []、空元组 ()、空字典 {}、空集合 set() 等都被程序视为假(第 52 页),而且都与 None 不相等。

我们可以通过代码清单 5-2 ~代码清单 5-5 来确认上述内容。

在这里插入图片描述

另外,使用 str 函数转换 None 会得到字符串 ‘None’。

可使用 x or ‘’ 的情况有:在变量 x 引用了字符串的情况下,想得到该字符串本身;在变量 x 为 None 的情况下,想得到空字符串。现在我们通过例 5-7 来进行确认。

在这里插入图片描述

▶ 这里利用了 or 表达式的特性,即“x or y”求值后的值是 x 或 y(第 56 页、第 58 页)。

专栏 5-1 不再使用的对象会去哪里

本节提到过变量只用于引用对象,如果不可变类型的变量值更新,标识值也会更新,以引用其他对象。

那么,不再被引用(不再使用)的对象会去哪里呢?如果它们就这样闲置,会占用存储空间。

答案是,Python 使用了引用计数对此进行管理,让程序保存了各个对象被多少个变量所引用(如果某个对象被变量 a 和变量 b 引用,引用计数就为 2)。

如果对象的引用计数为 0,程序则认为不再需要该对象,并释放该对象占有的存储空间(该存储空间可以被再次使用)。注意,该操作并非立即进行。

在 C 语言中有多种存储空间的管理方式,包括程序从开始到结束始终保持存储空间的静态存储期(静态存储生命周期)、只在代码块中保持存储空间的自动存储期等。Python 对存储空间的管理方式与之完全不同。

5-2 类型和运算

我们已经知道,Python 中“只有对象”,变量只不过是名字而已。本节,我会讲解对象的类型和运算。

对象和内置类型
  我们已经学习了许多类型。表 5-2 是 Python 主要内置类型(built-in type)的一览表(可变类型使用红字标记)。

表 5-2 主要的内置类型

在这里插入图片描述

▶ 序列型、集合型、映射型将分别在第 6 章、第 7 章和第 8 章进行讲解。

 这张表展示的就是数据类型。函数(第 9 章)、模块(第 10 章)、类(第 11 章)等也是对象,都有各自的类型。因为在 Python 中一切皆为对象,所以类型本身也是一种对象。

逻辑型
  第 3 章介绍了用于表示真假的逻辑型(bool 型)。现在我们通过例 5-8 确认一下 True 的值和 False 的值。

在这里插入图片描述

▶ Python 中有一个 True 对象和一个 False 对象。因此程序会反复使用这些已有的对象,而不是调用 bool(7)bool(0) 来生成新的对象。

浮点型和实数的运算
  第 1 章演示过在 Python 程序中 7 除以 3 得到的商存在误差(第 8 页)。

在这里插入图片描述

结果的小数部分本应该是 3 无限循环下去,但实际结果的第 16 位变成了 5。这是因为浮点型(float 型)表示的值在大小和精度方面存在限制。

我们通过假设来对此进行理解。

假设最大可以表示 12 位数字,精度为 6 位有效数字。

以 1234567890 为例。该数字有 10 位,在最大的数字范围 12 位以内。但是,由于该数字的精度不超过 6 位,所以对左数第 7 位进行四舍五入后得到 1234570000。图 5-7 是该数字在数学上的表示方法。

在这里插入图片描述

图 5-7 尾数和指数

图中的 1.23457 称为尾数,9 称为指数。尾数的位数相当于精度,指数的值相当于大小。

这里使用了十进制数,而实际上尾数部分和指数部分在 Python 内部都用二进制数表示。因此,在大小为 12 位、精度为 6 位的上述示例中,用十进制整数无法准确表示结果。

表示浮点数的 float 型,其属性与运行环境有关。因此,Python 提供了 sys.float_info 来查看 float 型的属性。具体请看例 5-9。

在这里插入图片描述

▶ 不同运行环境下输出的值不同。

   max, min   可以表示的最大值/最小值

   max_exp    可以表示的最大整数

   dig      可以正确表示的最大十进制浮点数的位数

   epsilon     1 和程序可以表示的最临近的 float 值之间的差(即机器精度)

 这里就不说明其他值的含义了,请读者自行查阅各类文档。

 因为浮点数的精度有限,所以在财务计算等对准确度要求较高的情况下,我们需要使用定义在 decimal 模块中的 Decimal 型(请自行查阅相关内容)。

 另外,chap05/float_info.py 是与例 5-9 的输出内容相同的脚本程序。

算术转换
  例 1-6 进行了整数和浮点数的运算。在对 7(或 7.0)和 3(或 3.0)进行加法运算时,只有 3 + 7 的结果是 int 型的整数,除此之外都是 float 型的浮点数。

这是因为算术运算遵循以下规则。

如果其中一个操作数为复数,则另一个操作数转换为复数。
如果操作数都不是复数且其中一个操作数是浮点数,则另一个操作数转换为浮点数。
如果操作数既不是复数,也不是浮点数,则双方的参数必须为整数,此时不需要转换。

算术运算使用的内置函数
  Python 提供了许多内置函数来进行四则运算以外的算术运算。表 5-3 为这些内置函数的一览表。

代码清单 5-6 使用了该表格内的部分函数。

在这里插入图片描述

在这里插入图片描述

在蓝色底纹部分中,传递给 sum 函数的实参是用 () 包围的 (x, y, z),而不是 x, y, z。多个值用 () 包围后就变成了一个值(元组)。

▶ 元组的相关内容会在第 8 章进行讲解。

 另外,float 函数、hex 函数、int 函数、oct 函数和 sum 函数均已介绍。

 在给 pow 函数指定第 3 个参数 z 时,z 不能是负数。同时,x 和 y 必须是整数。

复数型
  复数型(complex type)又称 complex 型,通过两个浮点数来表示值。实数部分和虚数部分不为 0 的复数用类似于 3.2 + 5.7j 的形式表示。5.7j 的部分称为虚数字面量。这些内容我们在第 3 章已经学习过了。

在 Python 中可以调用 z.real 和 z.imag 取出复数 z 的实数部分和虚数部分。下面是生成一个复数后取出其实数部分和虚数部分的示例。

在这里插入图片描述

▶ 本书作为入门书,对复数型的讲解到此为止。

处理位的运算符
  在计算机内部,数值表现为位的 OFF/ON,而与之对应的是二进制数。大多数编程语言提供了处理位的方法。

Python 提供了专门用于处理整数位的运算符,我们来学习一下这些运算符。

按位逻辑运算符
  首先来看对位进行逻辑运算的 4 种运算符。

& … 按位与运算符(bitwise and operator)

 | … 按位或运算符(bitwise inclusive or operator)

 ^ … 按位异或运算符(bitwise exclusive or operator)

 ~ … 按位取反运算符(bitwise invert operator)

前 3 个运算符是二元运算符,只有运算符 ~ 是一元运算符。这些运算符的大致情况如表 5-4 所示。

表 5-4 按位逻辑运算符

在这里插入图片描述

▶ 操作数必须是整数。优先级从高到低依次为 ~&^|。另外,关于运算符 ~ 生成的值,我们会在第 125 页的专栏 5-2 中学习。

图 5-8 汇总了各个逻辑运算的真值表。

▶ a 、b  和 d 与第 3 章讲解的逻辑运算符类似(第 57 页表 3-2)。

在这里插入图片描述

图 5-8 位的逻辑运算

代码清单 5-7 对这些运算符进行了演示。程序读取两个整数,并打印输出各种逻辑运算的结果。

▶ 该程序在进行屏幕输出时使用了一些技巧。

 变量 f 的值为用于格式化的字符串(6-3 节将对此进行详细讲解)。像运行示例那样,如果 w 等于 8,f 则变为 '{:08b}'。这是因为 '{{' 会变为 '{''}}' 会变为 '}''{}' 会变为 w(十进制数 w 变成了字符串)。

在这里插入图片描述

变量 m 的值为 2w -1。该值是一个有 w 位的二进制数,而且每一位都为 1。像运行示例那样,如果 w 等于 8,则 m 变成二进制数 0b11111111。

~ x 表示对 x 的位取反后的值。在 Python 的语言实现中,~ x 即 -(x + 1)(专栏 5-2)。

▶ 因为 ~ a 和 ~ b 变成负值,所以该程序输出了它们与 m 求逻辑与之后的值。

逻辑运算的应用
  逻辑与、逻辑或和逻辑异或的运算符有以下用途。

逻辑与 :清除任意位(位变为 0)。
逻辑或 :设置任意位(位变为 1)。
逻辑异或:反转任意位。

代码清单 5-8 对此进行了演示。程序针对整数 a 的后 4 位执行清除、设置和反转操作并输出相应的结果。

在这里插入图片描述

▶ 仅针对后 4 位执行清除、设置和反转操作,其他位保持原样。

位移运算符
  << 运算符(<< operator)和 >> 运算符(>> operator)可将整数中所有的位向左或向右移动(错位),并生成相应的值。

这两个运算符统称为位移运算符(bitwise shift operator),如表 5-5 所示。

表 5-5 位移运算符

在这里插入图片描述

▶ 操作数必须是整数。

代码清单 5-9 从键盘读取整数后,对整数进行左移和右移,并输出相应结果。

在这里插入图片描述

▶ 在显示的字符串中,{:b} 表示以二进制数的格式输出字符串(6-3 节将对此进行讲解)。

现在我们运行该程序,来看一下两个运算符的作用。

使用运算符 << 进行左移

表达式 x<< n 表示 x 的所有的位左移 n 位。此时,右侧新产生的位填 0(图 5-9 )。左移后的结果为 x×2n。

▶ 因为二进制数每一位的权重是 2 的多次幂,所以如果左移 1 位,值就会变为原来的 2 倍。这和十进制数左移 1 位,值就会变为原来的 10 倍(例如,196 左移 1 位变成 1960)的原因相同。

使用运算符 >> 进行右移

x>>n 表示 x 的所有的位右移 n 位。右侧的 n 位被移出。右移后的结果为 x÷2n(图 5-9)。

▶ 二进制数右移 1 位,值就会变为原来的一半。这和十进制数右移 1 位,值就会变为原来的十分之一(例如,196 右移 1 位变成 19)的原因相同。

另外,如果不需要生成位移后的值,只对变量值本身进行位移,则可以使用增量赋值运算符 <<= 和 >>=。

在这里插入图片描述

图 5-9 对整数进行位移运算

整数左移 n 位和右移 n 位的结果分别与整数乘以 2n 和除以 2n 的结果相同。我们来通过代码清单 5-10 进行确认。

在这里插入图片描述

这里的运行示例输出的位移运算结果是负数。不论 x 是正数还是负数,程序都会按预想的情况进行位移运算。

专栏 5-2 补码和按位取反运算符

C 语言等编程语言一般只能表示16位或32位的有限位整数,并且符号也含在其中。

在这些编程语言中,负整数在内部的典型表示方式是 1 的补码(one’s complement)或 2 的补码(two’s complement)

图 5C-1 为求 1 的补码和 2 的补码的步骤(以整数 5 为例)。

在这里插入图片描述

图 5C-1 求出补码的步骤

1 的补码通过反转所有位得到。
2 的补码通过对 1 的补码加 1 得到。
  在 Python 内部,负整数并不使用 1 的补码或 2 的补码表示(因为没有必要)。

按位取反运算符 ~ 其实没有反转位。~x 的运算结果通过模仿补码的表示方式计算 -(x + 1) 得到。

另外,连续使用两次运算符 ~ 会得到原来的值。假设 x 等于 5,~x 就等于 -6。对 -6 使用运算符 ~ 会得到 5,即 ~~x 等于 x。

总结
在 Python 中,变量、函数、类和模块皆为对象。
对象会占一定的存储空间(内存),并且拥有标识值(用于判断是否为同一个对象)、类型和值等属性。可以使用 id 函数获取标识值,使用 type 函数获取类型。
变量只是一个和对象绑定(引用对象)的名字。
is 运算符和 is not 运算符是身份运算符,用于判断对象是否为同一个(标识值是否相等)。
在 Python 中,根据值是否可以改变,类型可分为两类。

可变类型: 列表、字典、集合等     ※值可以改变。
不可变类型:数字、字符串、元组等    ※值不可以改变。
如果对不可变类型的变量(引用的对象)的值进行变更,则会生成新的对象,然后变量重新引用新的对象。

赋值语句复制的是对象的引用而不是值。另外,赋值的对象,即等号左边的变量名如果是首次使用,程序则生成新的变量并与等号右边的对象进行绑定。

在这里插入图片描述

与赋值语句相对应的是 del 语句,它用于删除作为名字的变量名。

None 与任何对象都不同,是 NoneType 类型的特殊值。
其他编程语言使用存储期(存储空间生命周期)对变量和对象进行管理。Python 与之不同,它使用引用计数,即引用对象的变量的个数,对变量和对象进行管理。
内置类型包括数值型(int 型、bool 型、float 型和 complex 型)、序列型(str 型、list 型和 tuple 型等)、集合型(set 型、frozenset 型)和映射型(dict 型)。
浮点型(float 型)可以表示的值在大小和精度方面存在限制。使用 sys.float_info 可以查看浮点型的属性。
在进行算术运算时,程序会根据操作数的类型进行算术转换。
复数型是用表示实数部分和虚数部分的两个浮点数来表示值的类型。例如 3.2 + 5.7j。其中,5.7j 称为虚数字面量。
因为在计算机内部,数值用位的 ON/OFF 来表示,所以 Python 可以轻易地表示二进制数。
Python 提供了求逻辑与的运算符 &、求逻辑或的运算符 |、求逻辑异或的运算符 ^ 和生成取反后的值的运算符 ~ 等按位逻辑运算符。

在这里插入图片描述

位移运算符 << 和 >> 将整数中的所有的位向左或向右移动后生成相应的值。

在这里插入图片描述

引用:ros小白太难了 编译了然后不知道该干嘛 我想着应该出可执行文件了 居然忘了在哪里 所以我百度了一下catkin_make稍微了解了下 。 引用:蒋师兄nb!!! 我的包编译出来了 问题是这里的多了一个slam_pp删掉就能够编译了 所以PROJECT_SOURCE_DIR指的是/home/swaglee/ROS_WORKSPACE/UWB_IMU/src/uwb-localization-master/slam_pp/slam_pp/ 对比一下看一下 。 引用:我也不懂原理没搞清楚 但是至少在自己的努力和师兄的帮助下出了点结果,这个都不容易啊搞了我一周,按漆老师的要求我这个时候基本上要把他那篇论文看了,然而我那天差不多一个小时就看完了hhh 看完了啥子都没学到 https://arxiv.org/pdf/1807.10913.pdf 先放到这里吧 然后第二个 没有结果,我问蒋师兄他叫我看报错的原因 我拿到百度上去搜索 一时半会儿也出不了结果,估计我也弄不出来,这就算了 第三个 Can’t open serial port:不能打开串口 我想的是这个怕是要有硬件连接才能出结果哦 实际上也应该是这样的,这个是需要传感器的数据的 当我继续搜索时我发现了硬件了 https://baijiahao.baidu.com/s?id=1640445634686633601&wfr=spider&for=pc http://www.huaxingzhikong.com/product/277818845 这就是硬件介绍了 第二个网页里面的东西挺硬核的 我粗略的看了下 这个就到这里吧,了解了一下github上的大佬的作品,虽然没跑出来完,但是感受了一下自己有多菜,在ros方面以及qt的基础都还没有 后面应该会补上 现在需要去学基础了 当初之所以想着要跑这个包就是因为天天看论文 觉得需要去实践一些东西(其实也没看多少 看得很浅 现在都忘了大部分了 只记住了一些经典的东西 比如uwb的基本定位原理 什么AOA TOA TDOA那些原理看了下 下面还要细看卡尔曼滤波主要是扩展卡尔曼滤波 听说上一届孟哥卡尔曼滤波的原理和代码都是吃透了的 代码都是自己手打的 我先去学习完卡尔曼滤波的理论然后再去手撕代码******来了。 根据引用内容,您提到了uwb imu python。UWB(Ultra-Wideband)是一种无线通信技术,IMU(Inertial Measurement Unit)是一种测量物体姿态和运动的装置。而Python是一种编程语言。 关于如何在Python中使用uwb imu,您可以按照以下步骤进行操作: 1. 首先,确保您的系统已经安装了Python和相关的Python包。 2. 接下来,您需要获取适用于Python的uwb imu库。可以通过在Python包管理器中搜索相关的库,或者在GitHub等代码托管平台上查找可用的uwb imu库。 3. 下载并安装选定的uwb imu库。可以按照库的文档或README文件中提供的指南进行安装。 4. 一旦安装完成,您可以使用导入语句将uwb imu库导入到您的Python脚本中。 5. 根据库的文档或示例代码,使用适当的函数和方法从uwb imu传感器中读取数据,并对数据进行处理和分析。 6. 使用Python的数据处理和可视化库,如NumPy和Matplotlib,对从uwb imu读取的数据进行进一步的处理和可视化。 这是一个基本的步骤和概述,您可以根据选定的uwb imu库的具体要求和用法进行进一步的学习和实践。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值