python可变类型和不可变类型有哪些_关于python:不可变类型与可变类型

我对什么是不变类型感到困惑。我知道float对象被认为是不可变的,这类例子来自我的书:

class RoundFloat(float):

def __new__(cls, val):

return float.__new__(cls, round(val, 2))

由于类结构/层次结构,这是否被认为是不可变的?,表示float位于类的顶部,是它自己的方法调用。类似于这类例子(尽管我的书中说dict是可变的):

class SortedKeyDict(dict):

def __new__(cls, val):

return dict.__new__(cls, val.clear())

虽然可变的东西在类内有方法,但是使用这种类型的示例:

class SortedKeyDict_a(dict):

def example(self):

return self.keys()

另外,对于最后一个class(SortedKeyDict_a),如果我将这种类型的集合传递给它:

d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))

不调用example方法,返回字典。带有__new__的SortedKeyDict将其标记为错误。我试着用__new__将整数传递给RoundFloat类,它没有显示错误。

您还可以使用&91;:&93;和python查看列表分配,了解何时使用copy.copy,我还回答了有关可变性的更多信息。

什么?浮点数是不变的?但我不能这样做

x = 5.0

x += 7.0

print x # 12.0

那不是"mut"x吗?

你同意字符串是不变的,对吗?但你也可以做同样的事情。

s = 'foo'

s += 'bar'

print s # foobar

变量的值会改变,但它会通过改变变量所指的内容而改变。一个可变的类型可以这样改变,它也可以"就地"改变。

这就是区别。

x = something # immutable type

print x

func(x)

print x # prints the same thing

x = something # mutable type

print x

func(x)

print x # might print something different

x = something # immutable type

y = x

print x

# some statement that operates on y

print x # prints the same thing

x = something # mutable type

y = x

print x

# some statement that operates on y

print x # might print something different

具体实例

x = 'foo'

y = x

print x # foo

y += 'bar'

print x # foo

x = [1, 2, 3]

y = x

print x # [1, 2, 3]

y += [3, 2, 1]

print x # [1, 2, 3, 3, 2, 1]

def func(val):

val += 'bar'

x = 'foo'

print x # foo

func(x)

print x # foo

def func(val):

val += [3, 2, 1]

x = [1, 2, 3]

print x # [1, 2, 3]

func(x)

print x # [1, 2, 3, 3, 2, 1]

注意:python列表是可变的,python tuple不是。

你给我解释的意思是:可变变量是通过引用传递的,不可变变量是通过值传递的。这是正确的吗?

差不多,但不完全是。从技术上讲,所有变量在python中都是通过引用传递的,但其语义更像C中的pass-by值。使用C中的pass-by引用,可以通过调用该函数来更改参数的值。在Python中,该函数不做任何事情。def f(my_list): my_list[:] = [1, 2, 3]会做些什么。

可变类型可以就地更改。不可变类型不能就地更改。这就是Python看待世界的方式。不管变量如何传递给函数。

如前所述,使用id()- >>> d = 10 - >>> id(d) - 30483204 - >>> d+=10 - >>> id(d) - 30483084 - >>> l = [] - >>> id(l) - 35637088 - >>> l.append(10) - >>> id(l) - 35637088。

Python语义和C++传递引用语义之间的关键区别在于,Python中的赋值不是突变,而是C++。(当然,这一点很复杂,因为像a += b这样的增强分配有时是突变。分配给一个较大的对象的一部分有时意味着对那个较大的对象的突变,只是部分的突变,例如,a[0] = b不改变EDCOX1〔5〕,但它可能会变异EDCOX1〔6〕……这就是为什么最好不要尝试用C++来处理事物,而只是描述Python做了什么。它自己的术语…)

《晨星:FYI》,你几乎肯定会想到C++参考文献。C没有引用,只有指针(和"模拟引用",即数组)。该代码的C版本也不会做任何事情:void f(list* my_list) { my_list = (list*) malloc(sizeof(list)); }不会更改参数,只会更改(本地)参数。

这是一个有点误导性的回答。例如:x = ([],2) #Immutable type、func(x)、print x可能打印出不同的内容,例如(['a', 'b', 'c'], 2)。

我发现这个答案有误导性,因为它不使用id(),这对于理解不可变的含义是至关重要的。

@晨星,'那不是"咕噜"吗?'-留下这样的印象:浮点数是可变的,而事实恰恰相反。我认为这种回答方式可能会让新手感到困惑。

您必须理解,python将其所有数据表示为对象。其中一些对象(如列表和字典)是可变的,这意味着您可以在不更改其标识的情况下更改其内容。其他对象如整数、浮点数、字符串和元组是不能更改的对象。理解这一点的一个简单方法是查看对象ID。

下面是一个不可变的字符串。您不能更改其内容。如果你试图改变它,它将提高一个TypeError。另外,如果我们分配新的内容,将创建一个新的对象,而不是要修改的内容。

>>> s ="abc"

>>>id(s)

4702124

>>> s[0]

'a'

>>> s[0] ="o"

Traceback (most recent call last):

File"", line 1, in

TypeError: 'str' object does not support item assignment

>>> s ="xyz"

>>>id(s)

4800100

>>> s +="uvw"

>>>id(s)

4800500

你可以用一个列表来做,它不会改变对象的标识。

>>> i = [1,2,3]

>>>id(i)

2146718700

>>> i[0]

1

>>> i[0] = 7

>>> id(i)

2146718700

要了解更多关于Python数据模型的信息,您可以查看Python语言参考:

python 2数据模型

python 3数据模型

+1用于链接到python文档。然而,我花了一段时间才意识到,今天您需要区分beten python 2&3—我更新了答案以强调这一点。

通用不可变类型:

编号:int()、float()、complex()。

不可变序列:str()、tuple()、frozenset()、bytes()。

常见的可变类型(几乎所有其他类型):

可变序列:list()、bytearray()。

机组类型:set()。

映射类型:dict()。

类,类实例

等。

快速测试类型是否可变的一个技巧是使用id()内置函数。

示例,使用整数,

>>> i = 1

>>> id(i)

***704

>>> i += 1

>>> i

2

>>> id(i)

***736 (different from ***704)

使用列表,

>>> a = [1]

>>> id(a)

***416

>>> a.append(2)

>>> a

[1, 2]

>>> id(a)

***416 (same with the above id)

解释得很好。喜欢id()的检查概念。+ 1。

很好的答案,简洁和使用id()是一个很好的技巧。

实际上,使用id()在这里是误导性的。给定对象在其生存期内始终具有相同的ID,但由于垃圾收集,不同时间存在的不同对象可能具有相同的ID。

首先,一个类是否有方法或者它的类结构与可变性无关。

ints和floats是不变的。如果我这样做

a = 1

a += 5

它将名称a指向位于第一行内存中某个位置的1。在第二行,它查找到1,加上5,得到6,然后把a指向记忆中的6,它没有以任何方式将1改为6。使用其他不可变类型,同样的逻辑适用于以下示例:

b = 'some string'

b += 'some other string'

c = ('some', 'tuple')

c += ('some', 'other', 'tuple')

对于可变类型,我可以做一些实际更改存储在内存中的值的事情。用:

d = [1, 2, 3]

我在内存中创建了1、2和3的位置列表。如果我那么做

e = d

我只是把e指向同一个listd点。我可以这样做:

e += [4, 5]

同时更新e和d点所在的列表,使其在内存中也有4和5的位置。

如果我回到一个不变的类型,用一个tuple做这个:

f = (1, 2, 3)

g = f

g += (4, 5)

那么,f仍然只指向原来的tuple——你已经把g指向了一个全新的tuple。

现在,举个例子

class SortedKeyDict(dict):

def __new__(cls, val):

return dict.__new__(cls, val.clear())

你经过的地方

d = (('zheng-cai', 67), ('hui-jun', 68),('xin-yi', 2))

(这是tuples的tuple与val一样,因为tuple没有.clear()方法,所以你会得到一个错误——你必须把dict(d)作为val传递给它才能工作,在这种情况下,你会得到一个空的SortedKeyDict。

这是很好的解释。喜欢这个问题和许多有趣的(新的)观点来解释它。

对象是否可变取决于其类型。这不取决于它是否有某些方法,也不取决于类层次结构的结构。

用户定义的类型(即类)通常是可变的。有一些异常,例如不可变类型的简单子类。其他不可变类型包括一些内置类型,如int、float、tuple和str,以及一些在C中实现的python类。

python语言参考中"数据模型"一章的一般解释:

The value of some objects can change. Objects whose value can change

are said to be mutable; objects whose value is unchangeable once they

are created are called immutable.

(The value of an immutable container

object that contains a reference to a mutable object can change when

the latter’s value is changed; however the container is still

considered immutable, because the collection of objects it contains

cannot be changed. So, immutability is not strictly the same as having

an unchangeable value, it is more subtle.)

An object’s mutability is

determined by its type; for instance, numbers, strings and tuples are

immutable, while dictionaries and lists are mutable.

+1请注意,尽管只有一些扩展类型(您可能希望查看您对此的定义,但所有Python的内置类型都是用C实现的)是不可变的。其他(大多数,我敢说)是完全可变的。

你说得对。我把答案修改得更准确了。

@Delnan您称之为"扩展类型"是什么?

@Eyquem:我在回答中错误地使用了"扩展类型"这个词,Delnan指的是这个。在他的评论之后,我修改了我的答案,避免使用这个词。

如果您是从另一种语言(除了一种非常像python的语言,比如ruby)来到python,并且坚持用另一种语言来理解它,那么人们通常会在这里感到困惑:

>>> a = 1

>>> a = 2 # I thought int was immutable, but I just changed it?!

在python中,赋值不是python中的突变。

在C++中,如果你写a = 2,你会调用EDCOX1×1 },这会改变存储在EDCOX1×2中的对象。(如果a中没有存储对象,那就是错误。)

在python中,a = 2对a中存储的内容没有任何作用;它只是意味着2现在存储在a中。(如果a中没有存放物品,那就好了。)

最终,这是一个更深层次的区别的一部分。

像C++这样的语言中的变量是内存中的一个类型化的位置。如果a是一个int,这意味着编译器知道的4个字节应该被解释为int。所以,当您执行a = 2操作时,它会将存储在这4个字节内存中的内容从0, 0, 0, 1更改为0, 0, 0, 2。如果在其他地方还有另一个int变量,它有自己的4个字节。

像python这样的语言中的变量是一个拥有自己生命的对象的名称。有一个对象用于数字1,另一个对象用于数字2。a不是表示为int的4字节内存,它只是指向1对象的名称。把数字1转换成数字2对a = 2是没有意义的(这会给任何一个python程序员太多的能力来改变宇宙的基本工作);相反,它所做的只是让a忘记1对象并指向2对象。

所以,如果任务不是突变,那么什么是突变?

调用一个记录为突变的方法,比如a.append(b)。(注意,这些方法几乎总是返回None)。不可变类型没有任何此类方法,可变类型通常有。

分配给对象的一部分,如a.spam = b或a[0] = b。不可变类型不允许为属性或元素赋值,可变类型通常允许一个或另一个。

有时使用增强赋值,如a += b,有时不使用。可变类型通常会改变值;不可变类型永远不会改变,而是给您一个副本(它们计算a + b,然后将结果赋给a)。

但是,如果赋值不是突变,那么如何赋值给对象的一部分突变呢?这就是问题的症结所在。a[0] = b不突变EDCX1〔32〕(同样,与C++不同),但它确实变异EDCX1〔2〕(与C++不同,除了间接地)。

所有这一切都是为什么最好不要把Python的语义放在一种你习惯的语言上,而是用它们自己的术语来学习Python的语义。

说"嗨"。a[0]='f'将有'print a'打印输出'f i'(我说得对吗?)所以,当你说它不会变异A[0],而不是A,这意味着什么?A[N]现在是否也有自己的位置,改变它的值会使它指向不同的值?

可变对象必须至少有一个方法能够改变对象。例如,list对象有append方法,它实际上会改变对象:

>>> a = [1,2,3]

>>> a.append('hello') # `a` has mutated but is still the same object

>>> a

[1, 2, 3, 'hello']

但是类float没有改变float对象的方法。你可以做到:

>>> b = 5.0

>>> b = b + 0.1

>>> b

5.1

但=操作数不是一种方法。它只是在变量和它右边的任何对象之间建立一个绑定,其他的都没有。它从不更改或创建对象。它是一个变量指向什么的声明,从现在开始。

当执行b = b + 0.1操作时,=操作数将变量绑定到一个新的浮点,并使用5 + 0.1的结果创建wich。

当您将一个变量赋给一个现存的对象时,无论变量是否可变,=操作数都会将该变量绑定到该对象。什么都没有发生

在这两种情况下,=只是做了约束。它不会更改或创建对象。

当执行a = 1.0操作时,=操作数不是用来创建浮点的,而是行的1.0部分。实际上,在编写1.0时,它是float(1.0)的简写,是一个返回float对象的构造函数调用。(这就是为什么如果键入1.0并按Enter键,您会得到下面打印的"echo"1.0;这是您调用的构造函数函数的返回值)

现在,如果b是一个浮点数,而你给a = b赋值,这两个变量都指向同一个对象,但实际上变量之间不能相互通信,因为对象是不可变的;如果你给b += 1赋值,现在b指向一个新对象,a仍然指向旧对象,并且不知道b所指的。

但是如果c是,比如说,list,而你指定a = c,那么现在a和c可以"通信",因为list是可变的,如果你指定c.append('msg'),那么只要检查a就可以得到消息。

(顺便说一句,每个对象都有一个唯一的ID号,它与id(x)有关。因此,您可以检查对象是否相同,或者不检查其唯一ID是否已更改。)

可变对象和不可变对象的区别定义

可变对象:创建后可以更改的对象。不可变对象:创建后不能更改的对象。

在python中,将尝试更改它将给新对象的不可变对象的值。可变物件

下面是python中可变类型的列表对象:

list

Dictionary

Set

bytearray

user defined classes

不可变对象

以下是Python中不可变类型的列表对象:

int

float

decimal

complex

bool

string

tuple

range

frozenset

bytes

一些悬而未决的问题

问题:字符串是不可变类型吗?答:是的,但你能解释一下吗?证据1:

a ="Hello"

a +=" World"

print a

产量

"Hello World"

在上面的示例中,字符串一度被创建为"hello",最后改为"hello world"。这意味着字符串属于可变类型。但不是这样的,我们可以检查它的身份,检查它是否是可变类型。

a ="Hello"

identity_a = id(a)

a +=" World"

new_identity_a = id(a)

if identity_a != new_identity_a:

print"String is Immutable"

产量

String is Immutable

证据2:

a ="Hello World"

a[0] ="M"

产量

TypeError 'str' object does not support item assignment

问题:元组是不变的类型吗?答:是的。证据1:

tuple_a = (1,)

tuple_a[0] = (2,)

print a

产量

'tuple' object does not support item assignment

【46】:a="hello"in【47】:id(a)out【47】:140071263880128 in【48】:a=a.替换【49】:a out【49】:gello'in【50】:id(a)out【50】:140071263881400

你愿意证明你的物品分配问题到我上面给出的例子吗?

不可变类型中不存在项分配问题。在您的例子中,您正在更改字符串A,但在内存中它被分配给一个新的变量。在我的例子中,项目分配不会像列表或字典那样改变变量的内存。如果要进行替换,则创建的是一个新变量,而不是修改现有变量

在我看来,你在和一个问题斗争,那就是可变/不变实际上意味着什么。下面是一个简单的解释:

首先,我们需要一个基础来解释。

所以把你编程的任何东西想象成一个虚拟对象,一个保存在计算机内存中的二进制数字序列。(不过,不要太难想象。^^)现在在大多数计算机语言中,您将不会直接使用这些二进制数,而是更多地使用二进制数的解释。

例如,您不考虑像0x110、0xAF0278297319或类似的数字,而是考虑像6这样的数字或像"hello,world"这样的字符串。这些数字或字符串绝不是计算机内存中二进制数字的一种解释。变量的任何值也是如此。

简而言之:我们不使用实际值编程,而是使用实际二进制值的解释。

现在我们确实有了不能为了逻辑和其他"整洁的东西"而改变的解释,而有些解释很可能会被改变。例如,考虑一个城市的模拟,换言之,一个程序中有许多虚拟对象,其中一些是房屋。现在,这些虚拟物体(房屋)可以被改变吗?它们还能被认为是相同的房屋吗?当然可以。因此,它们是可变的:它们可以在不成为"完全"不同对象的情况下进行更改。

现在想想整数:它们也是虚拟对象(计算机内存中二进制数的序列)。所以,如果我们改变其中的一个,比如将值6增加1,它仍然是6吗?当然不是。因此,任何整数都是不可变的。

所以:如果虚拟对象中的任何更改意味着它实际上成为另一个虚拟对象,那么它就称为不可变。

最后备注:

(1)不要把你的易变和不变的现实经验与用某种语言编程混淆在一起:

每种编程语言都有自己的定义,对象可以在其中静音,而对象不能静音。

因此,虽然您现在可以理解意义上的差异,但是您仍然需要学习每种编程语言的实际实现。…事实上,语言的目的可能是使6变为7。然后这又是一些非常疯狂或有趣的东西,比如对平行宇宙的模拟。^^

(2)这个解释当然不科学,它是为了帮助你理解易变和不易变之间的区别。

这个答案的目标是创建一个单一的地方来找到关于如何判断你是否正在处理变异/不变异(不可变/可变)的所有好主意,并且在可能的情况下,如何处理它?有时,突变是不可取的,在这方面,对于来自其他语言的编码人员来说,python的行为可能会感觉到违反直觉。

根据@mina gabriel的有用帖子:

阅读这本书可能会有所帮助:"Python中的数据结构和算法"

摘自那本列出可变/不变类型的书:可变/可变类型图像

分析以上内容并结合@arrak的w/a post?n:

什么不能意外地改变?

scalars(存储单个值的变量类型)不会意外更改

数字示例:int()、float()、complex())

有一些"可变序列":

str(),tuple(),frozenset(),bytes()。

什么可以?

类列表对象(列表、字典、集合、bytearray())

这里的帖子还提到类和类实例,但这可能取决于类继承自什么和/或如何构建。

"出乎意料"的意思是,来自其他语言的程序员可能不会期望这种行为(有异常或Ruby,可能还有其他一些"类似于Python"的语言)。

添加到此讨论:

这种行为是一种优势,当它防止您意外地用占用大量数据结构的多个内存副本填充代码时。但当这是不可取的,我们如何绕过它呢?

使用列表,简单的解决方案是创建一个这样的新列表:

list2=列表(list1)

其他结构…解决方案可能更棘手。一种方法是循环元素,并将它们添加到新的空数据结构(同一类型)中。

当传入可变结构时,函数可以改变原始值。怎么说?

在这个线程的其他注释上有一些测试,但是有一些注释表明这些测试不是完全证明。

object.function()是原始对象的一个方法,但其中只有一些会发生变化。如果他们什么也不归还,他们可能会这么做。人们会期望.append()在不测试给定名称的情况下发生变异。.union()返回set1.union(set2)的并集,并且不会发生变化。如果有疑问,可以检查函数的返回值。如果返回=无,则不会发生变化。

在某些情况下,sorted()可能是解决方法。因为它返回原始版本的排序版本,所以它可以允许您在以其他方式开始处理原始版本之前存储一个未变异的副本。但是,此选项假定您不关心原始元素的顺序(如果这样做,则需要找到其他方法)。相反,.sort()会改变原始文件(正如人们所期望的那样)。

非标准方法(如有帮助):在麻省理工学院许可证下发布的Github上找到了这个:

Github存储库位于:tobgu下,名为:pyrsistant

它是什么:当不希望发生突变时,编写用于代替核心数据结构的python持久数据结构代码

对于自定义类,@分号建议检查是否有__hash__函数,因为可变对象通常不应该有__hash__()函数。

这是我目前在这个话题上积累的全部内容。欢迎其他意见、更正等。谢谢。

A class is immutable if each object of that class has a fixed value upon instantiation that cannot SUBSEQUENTLY be changed

换言之,更改该变量(name)的整个值,或者不使用它。

例子:

my_string ="Hello world"

my_string[0] ="h"

print my_string

您希望此操作正常并打印Hello World,但这将引发以下错误:

Traceback (most recent call last):

File"test.py", line 4, in

my_string[0] ="h"

TypeError: 'str' object does not support item assignment

解释器说:我不能更改这个字符串的第一个字符

您必须更改整个string才能使其工作:

my_string ="Hello World"

my_string ="hello world"

print my_string #hello world

检查此表:

来源

如何以比上面显示的更简洁的方式修改python字符串的组件?

@卢克戴维斯,你可以做埃多克斯1〔0〕。这将生成一个名为my_string的新字符串,而原来的my_字符串已不存在(打印id(my_string)以查看此内容)。当然,这并不是很灵活,一般情况下,你可以转换成列表和返回:l = list(my_string)l[0] = 'h'my_string = ''.join(l)。

区别的一种思考方式:

在python中对不可变对象的赋值可以被认为是深度复制,而对可变对象的赋值是浅的

这是不正确的。python中的所有赋值都是引用的。不涉及复制。

最简单的答案是:

可变变量是其值可能在适当位置发生变化的变量,而在不可变变量中,值的变化不会在适当位置发生。修改不可变变量将重新生成同一个变量。

例子:

>>>x = 5

将创建X引用的值5

X>5

>>>y = x

此语句将使y引用x中的5

X---------->5

>>>x = x + y

因为x是一个整数(不可变类型),所以已经重新生成。

在语句中,rhs上的表达式将生成值10,当它被分配给lhs(x)时,x将重新生成为10。所以现在

X----> 10

Y---->>5

例如,对于不可变对象,赋值将创建值的新副本。

x=7

y=x

print(x,y)

x=10 # so for immutable objects this creates a new copy so that it doesnot

#effect the value of y

print(x,y)

对于可变对象,赋值不会创建值的另一个副本。例如,

x=[1,2,3,4]

print(x)

y=x #for immutable objects assignment doesn't create new copy

x[2]=5

print(x,y) # both x&y holds the same list

在python中,有一个简单的方法可以知道:

不变的:

>>> s='asd'

>>> s is 'asd'

True

>>> s=None

>>> s is None

True

>>> s=123

>>> s is 123

True

Mutable:

>>> s={}

>>> s is {}

False

>>> {} is {}

Flase

>>> s=[1,2]

>>> s is [1,2]

False

>>> s=(1,2)

>>> s is (1,2)

False

还有:

>>> s=abs

>>> s is abs

True

所以我认为内置函数在Python中也是不可变的。

但我真的不明白浮动是如何工作的:

>>> s=12.3

>>> s is 12.3

False

>>> 12.3 is 12.3

True

>>> s == 12.3

True

>>> id(12.3)

140241478380112

>>> id(s)

140241478380256

>>> s=12.3

>>> id(s)

140241478380112

>>> id(12.3)

140241478380256

>>> id(12.3)

140241478380256

真奇怪。

但这显然是无效的。因为元组是不可变的。类型x = (1, 2),然后尝试变异x,这是不可能的。我发现一种检查可变性的方法是hash,它至少适用于内置对象。hash(1)hash('a')hash((1, 2))hash(True)全部工作,hash([])hash({})hash({1, 2})全部不工作。

@如果对象定义了一个__hash__()方法,那么用户定义类的分号将起作用,即使用户定义类通常是可变的。

@Augurar我的意思是"是的",但是Python中没有任何东西可以保证任何东西,因为Python没有真正的静态类型或形式保证。但是hash方法仍然是一个很好的方法,因为可变对象一般不应该有__hash__()方法,因为在字典中为它们设置键是很危险的。

@augurar和分号(或者其他人,如果他们知道的话):uuhash_uuu()解决方案…自定义类的创建者是否必须添加它才能存在?如果是这样,那么规则是如果存在,那么对象应该是不可变的;如果它不存在,我们就无法判断,因为创建者可能只是离开了它。

我没有阅读所有的答案,但是所选的答案是不正确的,我认为作者有一个想法,能够重新分配一个变量意味着任何数据类型都是可变的。事实并非如此。可变性与通过引用传递有关,而不是通过值传递。

假设你创建了一个列表

a = [1,2]

如果你说:

b = a

b[1] = 3

即使您重新分配了B上的值,它也会重新分配A上的值。这是因为当您分配"B=A"时。您正在将"引用"传递给对象,而不是值的副本。这不是字符串、浮点数等的情况。这会使列表、字典和类似内容可变,但布尔值、浮点数等不可变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值