《Python编程——从入门到实践(第2版)》学习笔记

#python

#2022年夏天买的书,但是时隔一年半才进行认真学习。以下是我的对本书的学习笔记和知识总结(结合《Python语言程序设计基础》)。

Part 1 基础知识

一、背景知识

1.1 计算机概念

        计算机是根据指令操作数据的设备。两个基本特性:功能性和可编程性。功能性指对数据的操作,表现为数据计算、输入输出处理和结果存储等。可编程性指它可根据一系列指令自动地、可预测地、准确地完成操作者的意图。

        自1946年第一台数字电子计算机(ENIAC)诞生以来,计算机技术先后经历几次重大技术发展变革,可总结为四个阶段(嵩天)。

        第一个阶段:1946--1981年,“计算机结构系统阶段”。计算机的可编程性主要表现为合理分化软/硬件接口、控制计算部件完成高速运算。这个阶段的计算需求催生了C语言(1972),其可编程性体现在通过指针优化底层内存的使用。随着以IBM PC为代表的个人计算机诞生(1981),计算机技术进入面向大众的新阶段。

        第二个阶段:1982--2007年,“计算机网络和视窗阶段”,以面向全球子网间组网的TCP/IP网络协议的标准化为标志,互联网(Internet)时代。计算机提供满足个人计算需求的视窗应用和网络服务,网络将不同类型系统相互连通,由此诞生了具备跨平台功能的Java语言(1995).同时,由于微软Windows操作系统的高度普及,视窗应用“所见即所得”的开发需求催生了Visual C++、Visual Basic等视窗编程语言。随着iPhone智能手机的推出和普及,计算机技术进入面向移动网络应用的新阶段。

        第三个阶段:2008--,“复杂信息系统阶段”,移动互联网、多核众核、云计算等一批新的计算机概念和技术显著推动了计算技术的更新换代,计算机系统的复杂性会达到人类所能掌控的边界。面对复杂的功能性和紧迫的迭代周期,计算机需要更高抽象级别的程序设计语言来表达可编程性。python语言越来越受到欢迎。

        第四个阶段:??--??“人工智能阶段”,未来可期。

1.2 程序设计语言

        程序设计语言是计算机能够理解和识别用户操作意图的一种交互体系,又叫编程语言。按照程序设计语言规则组织起来的一组计算机指令称为计算机程序。

        包括3个大类:机器语言、汇编语言、高级语言。

       (1) 机器语言是一种二进制语言,直接使用二进制代码表达指令,计算机硬件可以直接识别和执行。不同计算机结构的机器指令不同。(低级语言)

        (2)汇编语言使用助记符与机器语言中的指令进行一一对应,例如:执行数字2和3的加法,指令为:add 2, 3, result,运算结果写入result。(低级语言)

        (3)高级语言是接近自然语言的一种计算机程序设计语言,例如: result = 2 + 3,该代码只与编程语言有关,与计算机结构无关。第一个广泛应用的高级语言是C语言。

        高级语言按照计算机执行方式的不同可分为两类:静态语言(编译执行,编译器Compiler)和脚本语言(解释执行,解释器Interpreter)。解释执行、逐条运行代码,可移植性好;编译整体运行更快。静态语言有:C语言、Java语言等;脚本语言有:JavaScript语言、R语言等。Python语言是一种高级通用脚本编程语言,但它的解释器保留了编译器的部分功能。

1.3 Python特点

        其诞生是个有趣的故事,语法简单、强制可读(强制通过缩进体现语句间的逻辑关系),支持中文(Python3.0解释器采用UTF-8编码表达所有字符信息,可以表达中、法、韩等各类语言),资源丰富。

1.4 程序的基本编写方法——IPO方法

        输入(Input)

        输出(Output)

        处理(Process)

二、搭建编程环境

1.1 Python安装

        Windows系统并非都默认安装了Python,

        首先需要检查你的系统是否安装了python。打开命令窗口(可在“开始”菜单搜索command/“命令提示符”/cmd),在终端窗口输入"python"然后回车,如果出现Python提示符(>>>),就说明系统安装了Python,反之出现错误命令就说明没有安装Python或已安装的Python文件故障。

     (如果已经安装了Python,上图表示找到Python程序并启动,在这个终端界面就可以开始编程,这就是python语言的真面目。)

        如果发现还没有安装或版本低于3.6,由Python官方网页获取安装程序,如下(我下载的版本):                                       https://www.python.org/ftp/python/3.12.0/python-3.12.0-amd64.exe

        默认安装地址是C:\Users\HUAWEI\AppData\Local\Programs\python,但是可以自定义安装(点击Customize installation而不是Install Now),两种选择都记得勾选最下面的"Add Python to PATH"方便配置系统。

如果出现以下界面:

        说明之前有安装过python但是因为某些原因损毁了(比如贸然删了什么文件),需要点击Uninstall将之前安装的文件彻底删除,然后重新安装。

        python安装包将在系统中安装一批与python开发和运行相关的程序,其中最重要的是python命令行和python集成开发环境(IDLE)。

1.2 Python运行

        运行python程序有两种方式:

        交互式:python解释器即时响应用户输入的每条代码,给出输出结果。上文中提到的终端窗口部分即是一种交互式的方法。也可以通过调用安装的IDLE来启动python运行环境,在“开始”菜单中可以找到并打开IDLE。(背景色修改请自行探索)

        文件式(批量式):用户将python程序写在一个或多个文件中,然后启动解释器批量执行文件中的代码(显然,这是最常用的编程方式),和交互式相对应。python代码保存在.py形式的文件中(先创建.txt文件进行编程,重命名为.py),在终端窗口进入.py文件所在目录,输入文件名即可运行文件获得输出。(这里可以看到安装了python之后计算机自行可以理解并运行.py文件)。cd/d 命令是切换磁盘,因为我的hello.py文件存在了D盘。

        打开IDLE创建新文件(New File)也可生成.py文件。

1.3 Python文本编辑器和IDE

       除了默认和自带的文本编辑器以及IDLE,也可以另外下载其他的文本编辑器和IDE辅助学习和编程。文本编辑器的优点在于简单,但是IDE的功能更丰富。

《Python编程》作者推荐安装Sublime Text程序(有官网),这是一个简单的文本编辑器。以下是作者在附录中提供的自定义设置:

        ①将制表符转换为空格:为防止混用制表符和空格键,菜单View->Indentation,确认选择了Indent Using Spaces,确认Tab Width设置为4个空格。如已经混用,菜单View->Indentation->Convert Tabs to Spaces;或单击Sublime Text窗口右下角的Spaces字样访问这些设置。

        ②行长设置:代码行长约定不超过79字符(竖线标识),菜单View->Ruler选择80。

        ③保存配置:想要以上配置对所有SublimeText中打开的文件生效,菜单Preferences->Settings,找到文件Preferences.sublime-settings-User,并在其中输入如下内容:

{
    "rulers": [80],
    "translate_tabs_to_spaces":true
}

1.4 spyder安装

spyder也是一个IDE,我个人喜欢它的界面。下面介绍spyder的安装方法:

①通过Anaconda下载。Anaconda是一个可以便捷获取包且对包能够进行管理,同时对环境可以统一管理的发行版本。支持R、Python等多种语言的开发。需要下载第三方库建议参考:Anaconda 安装python第三方库的各类方法_anaconda第三方库安装-CSDN博客

②直接下载。终端窗口切到python的目录(命令是 cd 目录名)使用pip工具:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple <库名> --trusted-host=pypi.tuna.tsinghua.edu.cn

pip是python安装包自带的工具,这里通过清华大学的镜像网站下载库。依次下载 wheel、PyQt5、spyder(<库名>更换)。

顺便可以安装以下第三方库(主要用于在文件夹里吃灰):

NumPy        矩阵运算
Matplotlib    产品级2D图形绘制
PIL        图像处理
sklearn(scikit-learn)机器学习和数据挖掘【括号内是全名,下载请用全名】
Requests        HTTP协议访问【spyder下载时自带】
Jieba        中文分词
bs4        HTML和XML解析【spyder下载时自带】
Wheel        Python文件打包
pyinstaller    打包Python源文件为可执行文件
Django        Web开发框架
Flask        轻量级Web开发框架
WeRoBot        微信机器人开发框架
Networkx        复杂网络和图结构的建模和分析
SymPy        数学符号计算
pandas        高效数据计算
PyOpenGL    多平台OpenGL开发接口
PyPDF2        PDF文件内容提取及处理
docopt        Python命令行解析
PyGame        简单小游戏开发框架
Plotly        可创建在浏览器中显示的交互式图表

三、变量和简单数据类型

1.变量

变量来源于数学,是计算机语言中能储存计算结果或能表示抽象概念

变量名只能包含字母、数字、下划线,只能以字母或下划线打头,不能包含空格。不能是python关键字和函数名。python保留字一般在编程时会字体高亮,因此容易区分。

大写字母在变量名中有特殊含义(约定在创建“类”时首字母大写)。

python语言中,变量是标签,指向特定的值。

>>> x,y,z = 0,0,0 

python没有内置的常量类型,约定常量字母全部大写。

2.字符串(String)

2.1 表示

         字符串是字符的序列表示,可以由一对单引号、双引号或三引号构成。单引号、双引号作用相同,都可以表示单行字符串,使用单引号时双引号可作为字符串的一部分,反之亦然。三引号可以表示单行或多行字符串:(下图中···表示延续上一行的内容,是二级输入提示)

       input()函数将用户输入的内容当作一个字符串类型

序列:字符串包括两种序号体系,正向递增从左开始0-->(L-1);反向递减从右开始(-1)-->(-L),这两种索引字符可以在一个表示中使用。

区间访问:[N:M], [:M], [N:], [:],空缺索引值即默认值

存储:Python3.X 字符串以Unicode编码存储,因此字符串的英文字符和汉字字符都算作1个字符。

        Python提供了5个字符串的基本操作符

操作符描述
x + y连接字符串
x * n 或  n * x复制n次字符串
x in s如x是s的子串,返回True, 反之False
str[i]返回第i个字符
str[N:M]切片,返回第N到第M的子串(副本),不包含M

        6个与字符串处理相关的内置函数

len(x), str(x);chr(x),返回Unicode编码x对应的单字符;ord(x),返回单字符表示的Unicode编码;hex(x),返回整数x对应的十六进制小写字符串;oct(x),返回整数x对应的八进制小写字符串。 

2.2 方法 

        方法是python可对数据执行的操作。在Python解释器内部,所有数据类型都采用面向对象(Object)方式实现,封装为一个类(Class)。字符串也是一个,它具有类似<a>.<b>()形式的字符串处理函数,( . )让python解释器对变量<a>执行方法<b>( )指定的操作;假设对象是O,则O.a表示对象O的属性a,O.b( )表示对象O的操作b( ),其中a是一个变量值,b( )是一个函数。字符串类型共包含43个内置方法。下列16个常用的方法,方框([ ])表示内部为可选择添加的参数:

方法描述
str.lower()返回全小写的副本
str.upper()······
str.islower()判断是否全小写,返回值为True或False
str.isprintable()所有字符都是可打印时返回True
str.isnumeric()判断是否所有字符都是数字
str.isspace()str所有字符都是空格时返回True
str.endswith(suffix[,start[,end]])str[start,end]以suffix结尾返回True
str.startswith(prefix[,start[,end]])以prefix开始返回True
str.split(sep=None,maxsplit=-1)返回一个列表,由str根据sep被分隔的部分构成
str.count(sub[,start[,end]])返回子串sub在str[start,end]出现次数
str.replace(old,new[,count])······如果count被给出,则前count次old出现被替换
str.center(width[,fillchar])字符串居中函数
str.strip([chars])返回左侧和右侧去掉chars中列出字符副本(例如空格);str.rstrip()只删除字符串尾
str.zfill(width)返回长度width的副本,不足部分在左侧添0
str.format()返回str的一种排版格式
str.join(iterable)返回由str分隔、由iterable变量的每个元素组成的新字符串
2.3 格式化&format()方法

字符串通过format()方法进行格式化处理。基本使用格式如下:

<模板字符串>.format(逗号分隔的参数);或 f<用花括号围住变量的字符串>,称为f字符串。

        模板字符串由一系列槽(用{ }表示)组成,用来控制修改字符串中嵌入值出现的位置,format()方法中逗号分隔的参数按照序号关系替换到槽中,如果{ }中没有序号,则按照出现的顺序替换。如下:

a = "a pen"
print(f"I have {a}.")

         如果需要输出{},采用{{转义{,}}转义},实例如下:

格式控制:{<参数序号>: <格式控制标记>} 

<填充><对齐><宽度><,>< . 精度 ><类型>
引导符号用于填充的单个字符

<左对齐

>右对齐

^居中对齐

槽的设定输出宽度数字的千位分隔符,适用于整数和浮点数浮点数小数部分的精度或字符串最大输出长度

整数类型b,c,d,o,x,X

浮点数类型e,E,f,%(format不能自己实现整数和浮点数之间的转化)

3.数

Python语言提供整数、浮点数、复数3种数字类型。

3.1 整数(int)

        整数有4种进制表示:十进制、八进制(0o/0O)、二进制(0b/0B)、十六进制(0x/0X),默认采用十进制,其他进制需要增加引导符号。理论上整数取值范围负无穷到正无穷,一般认为整数类型没有取值范围限制。

        整数计算被无限制支持且准确。

3.2 浮点数(float)

        所有浮点数必须带有小数部分,小数部分可以是0。浮点数有两种表示方法:十进制表示和科学计数法表示,例如:  0.0,96e-3, 9.6E5。科学计数法使用e/E作为幂的符号。<a>e<b> = a * 10^b。

        python浮点数的数值范围和小数精度受不同计算机系统的限制。

        计算机只能够提供有限个数字的准确性,最后一位由计算机根据二进制计算结果确定,存在误差。

        标准库decimal提供高精度浮点运算类型。

3.3 复数(complex)

        复数的虚数部分通过后缀J/j来表示。例如:

                                12.3+4j        -5.6+7j        1.23e-5+5.67e+89j

        对于复数z,可用z.real和z.imag分别获取它的实数部分和虚数部分。

3.4 操作

        =, -, *, /, //整数商,-x负值,**求幂。数字类型之间的运算结果是更“宽”的类型

        增强赋值操作。

abs(x)
divmod(x,y)(x//y, x%y),输出为二元组形式
pow(x,y[,z])(x**y)%z,但比求幂后求余更节省计算
round(x[,ndigits])四舍五入
max(x1,x2,...,xn)
min(x1,x2,...,xn)

转换:int(x), float(x), complex(re[,im])。

书写很大的数时,可以用下划线将其中的数字分组,如120_000_300_3_70_666,python不会打印其中的下划线。

4.注释

        注释是辅助性文字,用于说明,注释语句一般会被解释器过滤掉不被执行。

        单行注释以#开头,多行注释以'''(3个单引号或3个双引号)开头和结尾。但多行注释存在被解释器执行因而报错的可能(作为字符串被读取),因此建议多行注释尽可能放在结构之外。

        个人学习经验:注释不要怕麻烦,要准确

5.转义符

        需要注意的是,IDLE开发环境不支持部分转义符如\b,\r等,使用这些控制符需要保存代码为.py文件然后在命令行下执行。

\a蜂鸣,响铃
\b回退,向后退一格
\0NULL,什么都不做

四、基本数据结构和控制结构

1. 列表(List)

        列表由一系列按特定顺序排列的元素组成,其中的元素之间没有任何关系,同一个列表里可以同时存在字母、数字或任何其他数据结构。由于列表包含众多东西,因此约定列表名称为复数形式。

        python中,用[ ]表示列表并用逗号分隔其中的元素。元素可通过指定列表名和元素的索引进行访问。

序类类型的通用操作符和函数
x in s ; x not in s
s + t
s * n; n * s
s[i]; s[i, j]; s[i, j, k]
len(s)
max(s)
min(s)
s.index(x[, i[, j] ])从i开始到j位置中第一次出现x的位置
s.count(x)出现x的总次数
1.1 列表修改

        ①要修改元素时,可指定列表名和元素的索引,再指定该元素的新值。

       ② <列表名>.append(x)函数可将元素x添加到列表末尾。<列表名>.insert(index, x)函数则在指定位置插入元素,其他元素的位置会同时自动调整。

        ③del <列表名>[index1: index2: k]语句可删除任意位置的元素;x = <列表名>.pop(index)方法可以删除列表任意位置的元素并让用户接着使用它。列表就像一个栈,删除列表末尾的元素相当于弹出栈顶元素。

        ④当不知道元素的索引时,可用<列表名>.remove(x)直接删除元素x,但是该方法只删除第一个出现的值,如果要删除的值在列表中出现多次,需要使用循环。

1.2 列表组织

        方法<列表名>.sort()使列表按字母顺序排列(永久性修改),传递参数reverse=True可实现返向排序。

        函数sorted(列表名)可以临时排序列表元素,不改变原始排列顺序。

        方法<列表名>.reverse()可以反转列表元素的顺序,注意是反转而不是按字母顺序。

        函数len()可获取列表的长度,即内部元素个数。

        ls.clear()清空内容, ls.copy()创建副本

2. 元组(Tuple)

        元组是特殊的序列类型,一旦创建不能被修改,可以重新定义元组。python中,生成元组只需要使用逗号将元素隔离开即可,可以加上圆括号(),但()不是必需的。一个元组可以作为另一个元组的元素。

        元组的主要用途有:表达固定数据项,函数多返回值,多变量同步赋值,循环遍历等。举例如下:

3. 字典(Dict)

3.1 集合(Set)

        集合类型与数学中集合的概念一致,即包含0个或多个数据项的无序组合。集合中元素只能是固定数据类型,例如整数、浮点数、字符串、元组等,列表、字典和集合本身都是可变数据类型,不能作为集合的元素出现。能够进行哈希运算的类型都可以作为集合元素。python提供了同名的具体数据类型——集合(set)。

        集合用{ }表示,由于是无序组合,没有索引和位置的概念,不能分片,集合中的元素可以动态添加或删除。可以用赋值语句生成一个集合,使用集合类型可以过滤掉重复元素。set()函数用于生成集合。

操作符——描述:

S - T 或 S.difference(T)

返回一个新集合,包括在集合S中但不在集合T中,S值不变。

S -= T 或 S.difference_update(T)

更新集合S,包括在集合S中但不在集合T中。S值改变。

S & T 或 S.intersection(T)

返回一个集合,包含同时在S和T中的元素

S & T 或 S.intersection_update(T)

更新集合S,包含同时在S和T中的元素

S ^ T 或 symmetric_difference(T)

返回一个新集合,包括集合S和T中的元素,但不包括同时在其中的元素。

S ^= T 或 symmetric_difference_update(T)

更新集合S,包括集合S和T中的元素,但不包括同时在其中的元素。

S | T 或 S.union(T)

返回一个新集合,包含集合S和T中的所有元素。

S |= T 或 S.update(T)

更新集合S,包括集合S和T中的所有元素。

S <= T 或 S.issubset(T)

如果S与T相同或者S是T的子集,返回True,否则返回False,可以用S < T 来判断S是否是T的真子集。

S >= T 或 S.issuperset(T)

如果S与T相同或S是T的超集,返回True,否则返回False,可以用S > T 来判断S是否是T的真超集。

操作函数或方法——描述:

S.add(x)

如果数据项x不在S中,则将x增加到s

S.claer()

移除S中的所有数据项

S.copy()

返回集合S的一个副本

S.pop()

随机返回集合S中的一个元素,如果S为空则产生keyError的异常

S.discard()

如果x在集合S中,移除该元素;如果x不在集合S中,不报错。

S.remove(x)

如果x在集合S中,移除该元素;如果x不在集合S中,则产生KeyError异常。

S.isdisjoint(T)

如果集合S和T没有相同元素,则返回True

Len(S)

返回S的元素个数

x in S

如果x是in的元素,则返回True,否则,返回False

x not in S

如果x不是in的元素,则返回True,否则,返回False
(这些都是搬运的,临时需要用建议直接上网搜索)

3.2 哈希运算

        哈希运算可以将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是对数据的一种有损且紧凑的表示形式。内置相应函数hash()。

3.3 键值对(key-value)

        键值对是一种二元关系,源于属性和值的映射关系。键(key)表示一个属性,也可以理解为一个类别或项目,值(value)是属性的内容。键值对将映射关系结构化,用于储存和表达。

3.4 字典的使用

        python语言中字典可以通过{ }建立(直接使用大括号生成一个空的字典而不是集合),建立模式如下:

{<键1>: <值1>, <键2>: <值2>, ......}

        字典类型也具有和集合类似的性质,即键值对没有顺序且不能重复;字典和列表是可以互为元素进行嵌套的。字典最主要的用法是查找与特定键对应的值。下例为对字典进行的操作:

3.5 遍历字典

        for key,value in dict.items():

        for key in dict.keys(); for key in sorted(dict.keys()):

        for value in dict.values():

4. 分支结构(if-elif-else, try-except)

4.1 if-elif-else结构

        判断条件,保留字 or,and

4.2 try-except语句

        try-except语句用于处理异常。通过将可能引发错误的代码(而不是所有代码)放在try-except代码块中,可提高程序抵御错误的能力。

        try-except-else代码块的工作原理如下。python尝试执行try代码块中的代码,只有可能引起异常的代码才需要放在try语句中。有时候,有一些仅在try代码块成功执行时才需要运行的代码,这些代码应放在else代码块中。except代码块告诉python如果尝试运行try代码块中的代码时引发了指定的异常该怎么办;支持多个except语句。异常语句还可以和finally配合使用,无论try代码块是否成功执行,finally代码块都会执行。

try:
    <action1>
except <error1>:
    <action2>
except <error2>:
    <action3>
...
else:
    <action m>
finally:
    <action n>

5. 循环结构(for, while)

        for循环用于针对集合中的每个元素都执行一个代码块,而while循环不断运行直到指定的条件不满足为止。

        break,continue。

6. 函数

        函数是一段具有特定功能的、可重复利用的语句组,用函数名来表示并通过函数名进行功能调用。使用关键字def定义函数,括号内传递参数。函数体的结构使用缩进表示(一个Tab键的事儿)。

def greet_user():
    """显示简单问候语"""      #文档字符串,描述函数做了什么
    print("Hello!")

greet_user()
6.1 参数

        定义函数时,括号内传递的参数为形参(parameter),即函数完成工作所需要的信息。而在调用函数时,将要让函数使用的信息放在圆括号内,称为实参(argument)。函数定义中可能包含多个形参,调用函数时,python必须将每个实参都关联到函数定义的一个形参。

        最简单的关联方式时基于实参的顺序,这种关联方式称为位置实参关键字实参是传递给函数的名称值对(指明形参和对应实参),不会混淆。编写函数时,可给每个形参指定默认值;在调用函数时若给形参传递实参,python将使用指定的实参值,否在将使用形参的默认值(指定默认值时等号两边不要有空格)。关键字实参应当放在位置实参后,接纳任意数量实参的形参必须放在最后。形参    **parameter  中的(**)让python创建一个名为parameter的空字典。

6.2 返回值

        函数可以处理一些数据并返回一个或一组值。

6.3 导入和指名

        from file import fuction  as  fu。

        from file import *  (导入全部函数)

五、实例摘选

1. 汉诺塔

        汉诺塔算是学习编程最经典的教学案例了。每一次移动金盘,都对应一次“操作”,每一次“操作”都是一次迭代。一次假想的“移动”和一层迭代产生了明确的对应关系。

def hannuo(n, a, b, c):
    if n ==1:
        print(a +"-->" + c)
    else:
        hannuo(n-1, a, c, b)
        print(a+"-->"+c)
        hannuo(n-1, b, a, c)

2. 图像的字符画绘制

from PIL import Image
ascii_char = list('""$%_&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-/+@<>i!;:,\^`.')
#这一段不正确

def get_char(r,b,g, alpha=256):
    if alpha == 0:
        return ' '
    gray = int(0.2126 * r + 0.7152 * g + 0.0722 *b)
    unit = 256 / len(ascii_char)
    return ascii_char[int(gray//unit)]

def main():
    im = Image.open('astro.jpg')
    WIDTH, HEIGHT = 100, 60
    im = im.resize((WIDTH, HEIGHT))
    txt = ''
    for i in range(HEIGHT):
        for j in range(WIDTH):
            txt += get_char(*im.getpixel((j,i)))
        txt += '\n'
    fo = open('pic_char.txt','w')
    fo.write(txt)
    fo.close()
main()

  • 20
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值