Python3.5学习之旅——day2

本节内容:

1、模块初识

2、.pyc是什么?

3、Python的数据类型

4、三元运算

5、进制

6、byte类型

7、数据运算

8、列表

9、元组

10、课后练习

 

 

 

 

一、模块初识

由day1的学习我们知道,Python有一个很重要的优点——具有强大的标准库和第三方库,这里的“模块”指的就是存放在标准库或者第三方库中的可以实现某种特定的功能的“程序包”。

下面我们先来学习两个简单的标准库中的模块:sys模块和os模块。

1、sys

我们练习使用一下‘sys'模块,模块名为“sys_mod2.py”

__author__ = 'Sunny Han'
import sys
print(sys.path)#打印出sys模块所在路径

运行结果如下:

可以看到这段程序打印出了sys所在的路径。

再加一段代码:

__author__ = 'Sunny Han'
import sys
print(sys.path)#打印出sys模块所在路径
print(sys.argv)#打印相对路径

也打印出了相对路径。如下:

也就是说,若想导入sys模块,电脑就是在这个路径下去寻找。其次我们要知道的是,Python的标准库都存放在E:\\program\\python\\lib这个路径下(硬盘的选择因人而异,在这里我存的是E盘),Python的第三方库都存放在 'E:\\program\\python\\lib\\site-packages'这个路径下。

此外,我们若是在执行‘sys_mod2.py’时,再在其后加三个参数‘1’,‘2’,‘3’,执行结果如下:

若是想只读取三个参数中的‘2’,由上述执行结果我们可以看到‘2’为第2个参数(计算机从0开始计数),如下图所示:

故代码可以改为:

__author__ = 'Sunny Han'

import sys
print(sys.path)#打印出sys模块所在路径
print(sys.argv[2])#打印相对路径

执行结果为:

2、os

os模块的作用是和本机操作系系统进行交互,下面通过两个例子来说明:

(1)dir功能

__author__ = 'Sunny Han'

import os
os.system("dir")#"dir"在Windows操作系统中的作用是打开当前目录下的文件

执行结果如下:

我们在这里可以先忽略掉执行结果出现的乱码,这是由于Windows的输出的字符编码和我们这里使用的utf-8不一致导致的。我们可以看出上述结果即是“dir”的执行结果这就是os模块的作用。

接下来我们试一下是否可以将上述的输出结果存到一个变量中去,实验如下:

 

__author__ = 'Sunny Han'

import os
os.system("dir")#"dir"在Windows操作系统中的作用是打开当前目录下的文件
cmd_res=os.system("dir")
print("-->",cmd_res)#为了比较清楚的看到我们的变量值,故在变量前加“-->”来明示。

执行结果如下:

我们可以看到这次的执行结果相较上次的仅多了一个"-->”(红框中的内容),也就是说最后变量值为0!而不是之前输出的结果,这是为什么呢?这是因为“os.system("dir")”这条指令只执行命令,而并不保存结果,也就是说它输出了就没了,所以不能存在变量中。那如果我们想将这个输出结果存在变量中应该怎么做呢?请看下面的实验:

__author__ = 'Sunny Han'

import os
cmd_res1=os.popen("dir")  #这时打印的是内存对象地址,而不是我们的结果
cmd_res=os.popen("dir").read()#这里加一个“read”就可以从上述的内存对象地址中将结果取出来
print("-->",cmd_res1)
print(">>>",cmd_res)

执行结果如下:

在这里我们就将输出的结果存入变量中了,而且也没有之前的乱码,全变成可以看懂的中文内容了。在这里我们要注意一下加“read()”和不加的区别,因已在上文代码中解释到,这里不再赘述。

(2)mkdir功能

我们要是想在当前目录下创建一个新的目录,代码如下:

__author__ = 'Sunny Han'
import os
os.mkdir("new dir")  #在当前目录下创建一个新的名为“new dir"的目录

执行结果如下:

就在当前的‘day1’目录下创建了一个名为'new dir'的新目录。

3、自己写一个模块

我们可以练习自己写一个模块,以用户输入用户名和密码为例,文件名为‘login.py’。

代码如下:

__author__ = 'Sunny Han'

import getpass
username='han'
password='123456'
user=input('请输入用户名:')
pwd=getpass.getpass('请输入密码:')
if user==username and pwd==password:
    print("welcome user %s login..."%user)
else:
    print("invalid username or password!")

然后再写一个脚本,直接调用‘login.py’即可,文件名为‘import_login.py’如下:

__author__ = 'Sunny Han'

import login

执行结果与‘login.py’的结果一样,都为用户登录界面。

但是,在这里我们尤其要注意的是,如果我们所写的模块文件(例如‘login.py’)与调用此模块的文件不在同一目录下,那么将会出现报错的情况,即无法调用此模块,所以我们要求这两个文件应该放在同一目录下。这是因为电脑若想调用某模块,首先会在当前目录下寻找该模块,若在当前目录下找不到该模块,则在全局环境变量下寻找。

若我们想调用某不在同一目录下的模块,我们有两种方法:

(1)将此模块copy到我们之前提到过的用于存放第三方库的site-package文件中,这样就可调用成功。

(2)修改环境变量(之后再详细讲解)。

二、.pyc是什么?

1. Python是一门解释型语言?

我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在。如果是解释型语言,那么生成的*.pyc文件是什么呢?c应该是compiled的缩写才对啊!

为了防止其他学习Python的人也被这句话误解,那么我们就在文中来澄清下这个问题,并且把一些基础概念给理清。

  

2. 解释型语言和编译型语言 

计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程。这个过程分成两类,第一种是编译,第二种是解释。

编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是C语言。

解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是Ruby。

通过以上的例子,我们可以来总结一下解释型语言和编译型语言的优缺点,因为编译型语言在程序运行之前就已经对程序做出了“翻译”,所以在运行时就少掉了“翻译”的过程,所以效率比较高。但是我们也不能一概而论,一些解释型语言也可以通过解释器的优化来在对程序做出翻译时对整个程序做出优化,从而在效率上超过编译型语言。

此外,随着Java等基于虚拟机的语言的兴起,我们又不能把语言纯粹地分成解释型和编译型这两种。

用Java来举例,Java首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件。所以我们说Java是一种先编译后解释的语言。

 

3. Python到底是什么 

其实Python和Java/C#一样,也是一门基于虚拟机的语言,我们先来从表面上简单地了解一下Python程序的运行过程吧。

当我们在命令行中输入python hello.py时,其实是激活了Python的“解释器”,告诉“解释器”:你要开始工作了。可是在“解释”之前,其实执行的第一项工作和Java一样,是编译。

熟悉Java的同学可以想一下我们在命令行中如何执行一个Java的程序:

javac hello.java

java hello

 

只是我们在用Eclipse之类的IDE时,将这两部给融合成了一部而已。其实Python也一样,当我们执行python hello.py时,他也一样执行了这么一个过程,所以我们应该这样来描述Python,Python是一门先编译后解释的语言。

4. 简述Python的运行过程

在说这个问题之前,我们先来说两个概念,PyCodeObject和pyc文件。

我们在硬盘上看到的pyc自然不必多说,而其实PyCodeObject则是Python编译器真正编译成的结果。我们先简单知道就可以了,继续向下看。

当python程序运行时,编译的结果则是保存在位于内存中的PyCodeObject中,当Python程序运行结束时,Python解释器则将PyCodeObject写回到pyc文件中。

当python程序第二次运行时,首先程序会在硬盘中寻找pyc文件,如果找到,则直接载入,否则就重复上面的过程。

所以我们应该这样来定位PyCodeObject和pyc文件,我们说pyc文件其实是PyCodeObject的一种持久化保存方式。

三、Python的数据类型

1、数字

数字分为整型、浮点型和复数。

(1)首先关于整型我们这里要说明的一点是,在Python2中,整型分为int和long两种形式,但是在Python3中则没有了long这个概念,即不论整数值有多大都为int类型,如下:

可以看出不论值多大都为int类型。

(2)其次关于浮点型,浮点数是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一个整数定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法例如1.9E13表示1.9×10^13。

(3)复数是指能写成如下形式的数a+bj,这里a和b是实数,j是虚数单位(即-1开根)。在复数a+bj中,a称为复数的实部,b称为复数的虚部,j称为虚数单位。当虚部等于零时,这个复数就是实数;当虚部不等于零时,这个复数称为虚数。

2、布尔值

       真或假
  1 或 0

3、字符串

字符串一般放在两个双引号或者单引号之间,这里我们要注意双引号和单引号同时使用时的规范问题。如下:

__author__ = 'Sunny Han'

print("my name is "jake"")

如果像这样使用双引号的话会造成混乱,机器不能识别出这个输出的字符串到底是哪个,故会报错,修改如下:

__author__ = 'Sunny Han'

print("my name is 'jake'")

这样就可以执行了。

此外再简单介绍一下字符串格式化输出,代码如下:

__author__ = 'Sunny Han'

name='jake'
print("my name is %s"%name)#注意这里的%name应放在括号内,自己之前总是放在括号外,以此提醒大家。

PS: 字符串是 %s;整数 %d;浮点数%f

字符串常用功能:
  • 移除空白
  • 分割
  • 长度
  • 索引
  • 切片

四、三元运算

三元运算是一个相对更为简便的写法,举例如下:

a,b,c=1,2,3
d=a if a>b else c

即如果a>b,则d=a=1,否则d=c=5,那么这里我们可以知道d=5。上述代码可以换成if-else语句,但它比if-else语句更为简洁。

三元运算格式:result=值1 if 条件 else 值2.

五、进制

这里我们介绍四种计算机学习中常用到的进制:二进制、八进制、十进制和十六进制。

  • 二进制,01
  • 八进制,01234567
  • 十进制,0123456789
  • 十六进制,0123456789ABCDEF

这几种进制间的相互转换读者可以自行百度,这里不再赘述,不过我仍要说明强调一点的是通常三位二进制数对应一位八进制数,四位二进制数对应一位十六进制数。

下面是关于十六进制在计算机中的应用的简单介绍:

计算机内存地址和为什么用16进制?
1、计算机硬件是0101二进制的,16进制刚好是2的倍数,更容易表达一个命令或者数据。十六进制更简短,因为换算的时候一位16进制数可以顶4位2进制数,也就是一个字节(8位进制可以用两个16进制表示)。
2、最早规定ASCII字符集采用的就是8bit(后期扩展了,但是基础单位还是8bit),8bit用2个16进制直接就能表达出来,不管阅读还是存储都比其他进制要方便。
3、计算机中CPU运算也是遵照ASCII字符集,以16、32、64的这样的方式在发展,因此数据交换的时候16进制也显得更好。
4、为了统一规范,CPU、内存、硬盘我们看到都是采用的16进制计算。

16进制用在哪里
1、网络编程,数据交换的时候需要对字节进行解析都是一个byte一个byte的处理,1个byte可以用0xFF两个16进制来表达。通过网络抓包,可以看到数据是通过16进制传输的。
2、数据存储,存储到硬件中是0101的方式,存储到系统中的表达方式都是byte方式。
3、一些常用值的定义,比如:我们经常用到的html中color表达,就是用的16进制方式,4个16进制位可以表达好几百万的颜色信息。  
 

六、byte类型

Python 3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python 3不会以任意隐式的方式混用str和bytes,正是这使得两者的区分特别清晰。你不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然)。这是件好事。

不管怎样,字符串和字节包之间的界线是必然的,下面的图解非常重要,务请牢记于心:

下面以一个例子来说明:

__author__ = 'Sunny Han'

msg='我爱中国'
print(msg)
print (msg.encode(encoding='utf-8'))
print (msg.encode(encoding='utf-8').decode(encoding='utf-8'))

执行结果为:

这个问题要这么来看:字符串是文本的抽象表示。字符串由字符组成,字符则是与任何特定二进制表示无关的抽象实体。在操作字符串时,我们生活在幸福的无知之中。我们可以对字符串进行分割和分片,可以拼接和搜索字符串。我们并不关心它们内部是怎么表示的,字符串里的每个字符要用几个字节保存。只有在将字符串编码成字节包(例如,为了在信道上发送它们)或从字节包解码字符串(反向操作)时,我们才会开始关注这点。

七、数据运算

算数运算:

比较运算:

赋值运算:

逻辑运算:

成员运算:

身份运算:

位运算:

 八、列表

1、列表的创建和读取

在这里我们建立一个包含城市名字的列表,并以此为例学习如何进行读取,文件名为“name.py”。

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
print(names)

这样就建立了一个包含五个城市名字的列表。运行结果如下:

接下来尝试将其中的几个元素提取出来,代码如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
print(names)
print('1',names[1]) #将列表中第二个元素(Cleveland)提取出来,需要注意的是,列表元素的计数从0开始而不是1.
print('2',names[0],names[2])#将列表中的第一个和第三个个元素一并提取出来。
print('3',names[1:3])#将列表中的从第二个到第四个元素(但取不到第四个,即顾头不顾尾)读取出来
print('4',names[:3])#相当于print('4',names[0:3]),即这里的0可以省略
print('5',names[-1])#将列表中最后一个元素提取出来
print('6',names[-3:-1])#由顾头不顾尾原则,我们可以知道这里取得是“-3”和“-2”位置上的元素
                       #这里也要注意不能写成[-1:-3],也即冒号左边的数要比右边的小
print('7',names[-3:])#取出列表的最后三个元素

上面的注释已经介绍了相关的用法,这里不再赘述。

代码运行如下:

2、列表的基本操作

(1)增加列表元素

在列表末尾加一个元素,代码如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
names.append('Chicago')#在列表的末尾位置加一行元素"Chicago"
print(names)

代码运行结果如下:

若要在列表任意位置加元素,示例代码如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami',]

names.append('Chicago')#在列表的末尾位置加一行元素"Chicago"

names.insert(2,'Orlando')#将'Orlando'插入到位置2上

print(names)

代码运行结果如下:

 (2)修改列表元素

若想修改列表中部分元素,举例如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
names[3]='The Golden State'#将列表中位置序号为3的元素改为'The Golden State'
print(names)

代码运行结果如下:

可以看到我们将原列表中的位置序号为3的元素(Oakland)改为了‘The Golden State’。

(3)删除列表元素

在这里我们介绍三种删除列表元素的方法,代码如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
names.remove('Cleveland')#删除列表中的元素‘Cleveland’
print(names)

在这里我使用remove来将列表中某元素移除,注意这里的括号里面写的是元素名称,而不是元素位置序号。

代码运行结果如下:

接下来介绍第二种方法,代码如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
del names[2]#删除处在位置2上的元素
print(names)

在这里我使用的是del,可直接将位置2上的元素删除。

代码运行结果如下:

最后介绍第三种方法,代码如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
names.pop()#删除列表中最后一个元素
print(names)

在这里我们使用pop可直接删除列表中的最后一个元素,当然也可以在括号中写想要删除的元素的位置序号。

代码运行结果如下:

(4)查找列表元素序号

若有一个元素数量庞大的列表,元素的序号不能很方便快捷的看出来时怎么办呢,这里我们为大家介绍一种方法,代码如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Miami']
print(names.index('Boston'))

运行结果如下:

这里我们的列表数目较少,体会不到太大的优势,但若列表元素数目很大的话用这个方法会很快捷。我们要注意的是在查找时要注意别写错元素内容,不然会提示列表(list)内没有此元素。

(5)统计元素个数

若想统计列表中某元素的个数,代码实现如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Boston','Miami']
print(names.count('Boston'))#统计元素‘Boston’的个数
print(names.count('Miami'))#统计元素‘Miami’的个数

代码运行结果如下:

(6)列表元素顺序翻转

若想将列表内的元素倒序打印,代码实现如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Boston','Miami']
names.reverse()
print(names)

代码运行结果如下:

(7)列表拓展

若想将列表扩展一下,将另一个列表的元素放进此列表,举例如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Boston','Miami']
name2=['Nanjing','Seatle']
names.extend(name2)#将列表‘name2’的元素放进列表‘names'中
print(names)

代码运行如下:

(8)列表打印

  • 若想将列表逐个循环打印出来,我们可以使用for循环:
names=['Los Angeles','Cleveland','Boston','Oakland','Boston','Miami']
for i in names:
    print(i)

代码执行结果如下:

  • 若想每隔几个元素打印一个,举例如下:
names=['Los Angeles','Cleveland','Boston','Oakland','Orlando','Miami']
print(names[0:-1:2])#从第一个(0)元素每隔一个打印到最后一个(-1)元素
print(names[::2])#相当于print(names[0:-1:2]),也就是说0和-1可以省略

代码运行结果如下:

 3、copy的用法

copy的使用在列表中极为重要,在这里为大家详细的讲解一下。

首先,copy的一个最简单的作用就是复制列表,即将一个列表复制到另一个列表,举例如下:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Boston','Miami']
name2=names.copy()
print(names)
print(name2)

代码运行结果如下:

可以看到列表name2是从列表names复制过来的。

但是,这里有一个问题,假入我们把初始列表names中的元素稍加改动,copy的列表name2会不会也做出相应的变化呢?我们一试便知:

__author__ = 'Sunny Han'
names=['Los Angeles','Cleveland','Boston','Oakland','Boston','Miami']
name2=names.copy()
names[1]='Nanjing'#将列表names中的第二个元素改为‘Nanjing’
print(names)
print(name2)

代码执行结果如下:

根据上面的结果我们可以看到,若改变names列表中的某个元素,copy得到的列表name2并不会做出相应的改变,我们称之为“浅copy”。

接下来我们再来看一个有趣的例子:假如说初始列表names中有一个子列表,若我们改动子列表中的元素时,情况会不会和之前一样呢,示例如下:

names=['Los Angeles',['Utah','Boston'],'Oakland','Miami']
name2=names.copy()
print('->',names)
print('->',name2)
names[0]='Nanjing'#将列表names中的第一个元素改为“Nanjing”
names[1][0]='Phoenix'#将列表names中的子列表的第一个元素改为“Phoenix”
print(names)
print(name2)

代码运行结果如下:

我们可以看到若改动列表names中子列表元素内容时,copy的列表name2也会做出相应的改变,这是为什么呢?

这是因为第一层列表中的第二层列表(子列表)['Utah','Boston'] 存的只是一个列表指针,而并不是元素本身,当使用copy指令时,复制的是第二层列表的内存地址,所以,若第一层做出改变,第二层也会根据内存地址去察觉到相应的变化,并进一步做出改动。同样的,若在name2中改动第二层列表中的元素,则names中的元素也会做出相应改变。

那么如果说我们想避免出现 这种子列表变化,copy列表也会相应变化的情况发生,我们应该怎么办呢?

接下来我为大家介绍一种方法,示例如下:

import copy
names=['Los Angeles',['Utah','Boston'],'Oakland','Miami']
name2=copy.deepcopy(names)
print('->',names)
print('->',name2)
names[0]='Nanjing'#将列表names中的第一个元素改为“Nanjing”
names[1][0]='Phoenix'#将列表names中的子列表的第一个元素改为“Phoenix”
print(names)
print(name2)

代码运行结果如下:

也就是说,我们通过使用deepcopy就可以实现‘只打印一次’的功能。

 九、元组

元组与列表类似,不同的是列表可以修改列表内容,但元组不能修改内容,举个简单的元组的例子,如下:

names=('Los Angeles','Cleveland','Boston','Oakland','Orlando','Miami')
print(names)

代码运行结果如下:

在这里要注意,元组使用小括号()括起来的,列表是用方括号[ ] 括起来的。

除此之外,元组的使用和列表类似,在这里就不作详细的介绍了。

十、课后练习

在本节我们尝试编写一个购物车程序,主要有以下几个要求:

  • 启动程序后,让用户输入工资,然后打印商品列表。
  • 允许用户根据商品列表编号购买商品。
  • 用户选择商品后,检测余额是否足够,够就直接扣款,不够就提醒。
  • 可随时退出,退出时打印已购买的商品和余额。

在这之前,我们先向大家介绍一种可以直接将列表元素和下标一起打印出来的方法:enumerate

举例如下:

__author__ = 'Sunny Han'
a=[2,3,4]
for i in enumerate(a):
    print(i)

代码运行结果如下:

我们可以看到,这里直接将列表中的元素及其下标一同打印了出来。这对我们写购物车程序很有帮助。

接下来我们练习写购物车程序,代码如下:

__author__ = 'Sunny Han'
product_list=[
    ('Iphone',5800),('Mac Pro',9800),('Bike',800),('Watch',10600),('coffee',31)
]
shopping_list=[]
salary=input('input your salary:')#输入工资
if salary.isdigit():
    salary=int(salary)#将salary转为整型变量
    while True:
        for index,item in enumerate(product_list):
            print(index,item)

        user_choice=input('请问要买什么商品:>>>:')
        if user_choice.isdigit():
            user_choice=int(user_choice)
            if user_choice>len(product_list)-1:
                print('商品 [%s] 不存在!'%user_choice)
            else:
               p_item=product_list[user_choice] #将用户选择的商品信息值赋给p_item
               if p_item[1]<=salary:   #如果余额大于商品价格,则买得起
                   salary-=p_item[1]   #salary=salary-p_item[1],即自动扣款
                   shopping_list.append(p_item)  #将所购商品的信息加进空列表shopping_list
                   print('已将 %s 放入您的购物车,您的余额为 %s'%(p_item,salary))
               else:
                  print('余额不足。')
        elif user_choice=='q': #若用户想要退出系统,输入“q"
            print('----购物车----')
            for p in shopping_list:
             print(p)
            print('您的余额为:',salary)
            exit()  #注意这里要有一个退出的部分,否则用户输入"q"后会一直停留在商品列表界面
        else:
         print('请输入商品编号!')
else:
    print('格式错误!')

代码写好后,我们尝试着执行一下,结果如下:

第一步会出现让我们输入自己工资的界面,假设输入9999,如下:

输入后会显示商品列表并询问自己想要购买什么商品,假设要购买IPhone,我们输入商品的下标0,执行如下:

我们可以看到界面会给出我们的余额和已购买商品信息,假如再买一杯咖啡,运行如下:

 

 我们可以看到与之前类似的界面,只不过余额扣除了咖啡的价格,假如我们想买一个“Mac Pro”,我们看看会发生什么情况:

我们可以看到会提示余额不足,这时假若我们想退出购物系统,就输入“q”,运行如下 :

我们可以看到界面会显示我们已购买的商品信息和余额。

以上就是我们本节课的练习内容。

转载于:https://www.cnblogs.com/sunny0824/p/10023530.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值