Python3基础复习

1. 数据类型和运算符

数据类型

类型说明类型转换
整数 intint(`123`)
浮点数 float相当于C里面的doublefloat(`123`)
字符串strI\'m \"OK"!,输出'm OK!str(123)
布尔值True or False; 运算: and, or, not;bool(1)输出True
空值None

算数运算符

运算说明实例
+加 - 两个对象相加
-减 - 得到负数或是一个数减去另一个数
*乘 - 两个数相乘或是返回一个被重复若干次的字符串
/除 - x除以y10/3输出3.33339/3输出3.0
//取整除 - 返回商的整数部分 - 地板除法10//3输出3
%取模 - 返回除法的余数10%3输出1
**幂 - 返回x的y次幂

比较运算符

运算说明运算说明
==比较对象是否相等!=比较两个对象是否不相等
<>比较两个对象是否不相等(!=)
>大于<小于
>=大于等于<=小于等于

逻辑运算符

运算说明例子
and布尔"与" - 如果 x 为False,x and y 返回 False,否则它返回 y 的计算值。10 and 20 返回 20
or布尔"或" - 如果 x 是非 0,它返回 x 的值,否则它返回 y 的计算值。10 or 20 返回 10
not布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。

成员运算符

运算说明
in如果在指定的序列中找到值返回 True,否则返回 False。
not in如果在指定的序列中没有找到值返回 True,否则返回 False。

身份运算符

运算说明例子
isis 是判断两个标识符是不是引用自一个对象x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is notis not 是判断两个标识符是不是引用自不同对象x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。

身份运算符用于比较两个对象的存储单元。 id() 函数用于获取对象内存地址。

赋值运算符

运算符说明实例
=简单的赋值运算符c = a + ba + b 的运算结果赋值为 c
+=加法赋值运算符c += a 等效于 c = c + a
-=减法赋值运算符c -= a 等效于 c = c - a
*=乘法赋值运算符c *= a 等效于 c = c * a
/=除法赋值运算符c /= a 等效于 c = c / a
%=取模赋值运算符c %= a 等效于 c = c % a
**=幂赋值运算符c **= a 等效于 c = c ** a
//=取整除赋值运算符c //= a 等效于 c = c // a

2. 字符串和编码

Python 中格式化方式和C语言一致,用%实现。

占位符类型说明
%d整数%02d补零
%f浮点数%.2f保留2位小数
%s字符串可以把任何数据类型转换为字符串
%x十六进制整数
>>>'A:%d, B:%02d, C:%.2f, D:%s' % (2,3,3.145,True)
>'A:2, B:03, C:3.15, D:True'

3. 条件判断

  • if...else...
if condition:
	statement
else:
	statement
  • if...elif...else
if condition:
	statement
elif condition:
	statement
else:
	statement

4. 循环

4.1. for...in...

for name in ['A','B','C']:
	print(name)

sum=0
for x in [1,2,3]:
	sum=sum+x
print(sum)

sum = 0
for x in range(101):
    sum = sum + x
print(sum)

>>>list(range(5))
>[0, 1, 2, 3, 4]

4.2. while

while condition:
	statement

4.3. 循环控制

  • break: 提前结束当前循环 (当前循环未执行的将被放弃)
  • continue: 跳过当前这次循环

5. listtuple

5.1. list

一种有序集合,可以随时添加和删除其中元素。

函数和方法

函数和方法说明
list.append(x)把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]
list.extend(L)通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L
list.insert(i, x)在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x)
list.remove(x)删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。
list.pop(i)从列表的指定位置删除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被删除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。)
list.clear()移除列表中的所有项,等于del a[:]
list.index(x)返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
list.count(x)返回 x 在列表中出现的次数。
list.sort()对列表中的元素进行排序。
list.reverse()倒排列表中的元素。
list.copy()返回列表的浅复制,等于a[:]

其他

  • len(list):计算长度,max(list):最大值,min(list):最小值, list(seq):转换为list
  • list下标从0开始
    最后一个元素可以用list[-1]访问; 倒数第k个元素可以用list[-k]访问。
  • list里面元素的数据类型可以不同
  • L=[]建立一个空的list

5.2. tuple

元组是一种有序列表,但一旦初始化便不能修改。

#初始化
classmate = ('Michael', `Bob`, 'Tracy')
#定义一个只有一个元素的tuple
t = (1,)
#元组元素可以是列表等其他元素
t = ('a','b',['A','B'])
t[2][0] = 'X'
t[2][1] = 'Y'
#此处实际上改变的不是tuple而是List
>>>t
>('a','b',['X','Y'])

len(tuple):计算长度,max(tuple):最大值,min(tuple):最小值, tuple(seq):转换为tuple

6. dictset

dict

方法和函数说明
d.keys()输出key,list形式
d.values()输出value,list形式
d.items()输出key-value组合,list形式输出,每个元素是个tuple
d.pop(key)删除对应key-value
d.popitem()输出并删除末尾的key-value组合
d.clear()清空dict
d.get(key_name)输出key_name对应的value,如果此key-value不存在输出none
d.fromkeys(listkeys, default=0)将一个value赋值给listkeys中的所有key
d.copy浅拷贝
sorted(d.items(), key=lambda d: d[k])排序;如果k=0,则按照key排序;如果k=1,则按照value排序
del(d[key_name]) or del(d)删除key_name-values组合,或者删除整个dict
# 字典的添加、删除、修改操作
dict = {"a" : "apple", "b" : "banana", "g" : "grape", "o" : "orange"}
dict["w"] = "watermelon"
del(dict["a"])               #删除键值a所对应的键-值组合
dict["g"] = "grapefruit"     #更新g对应的值
dict.pop("b")                #删除键值b所对应的键-值组合
dict.clear()                 #清空dict

#字典的遍历
for k in dict:
    print("dict[%s] =" % k,dict[k])
#使用.items()方法
for (k, v) in dict.items():
    print("dict[%s] =" % k, v)

#字典的更新
#如果两个字典没有重合的key
dict = {"a" : "apple", "b" : "banana"}
dict2 = {"c" : "grape", "d" : "orange"}
dict.update(dict2)
#如果两个字典有重合的key
dict = {"a" : "apple", "b" : "banana"}
dict2 = {"b" : "grape", "d" : "orange"}
dict.update(dict2)          #dict中键b的对应值更新为grape

#字典的浅拷贝
dict = {"a" : "apple", "b" : "grape"}
dict2 = {"c" : "orange", "d" : "banana"}
dict2 = dict.copy()

字典的深拷贝
import copy
dict = {"a" : "apple", "b" : {"g" : "grape","o" : "orange"}}
dict2 = copy.deepcopy(dict)
dict3 = copy.copy(dict)
dict2["b"]["g"] = "orange"
dict3["b"]["g"] = "orange"

#排序
dict={'Michael':89,'Adam':58,'Bob':100}
#按照key排序 
sorted(dict.items(), key=lambda d: d[0])
#按照value排序 
sorted(dict.items(), key=lambda d: d[1])

###set
setdict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。

  • 创建set
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
  • 运算
运算说明
t \| ss.union(t)t 和 s的并集
t & ss.intersection(t)t 和 s的交集
t – ss.difference(t)求差集(项在t中,但不在s中)
t ^ ss.symmetric_difference(t)对称差集(项在t或s中,但不会同时出现在二者中)
x in s测试 x 是否是 s 的成员
x not in s测试 x 是否不是 s 的成员
s <= ts.issubset(t)测试是否 s 中的每一个元素都在 t 中
s >= ts.issuperset(t)测试是否 t 中的每一个元素都在 s 中
s \|= ts.update(t)返回增加了 set “t”中元素后的 set “s”
s &= ts.intersection_update(t)返回只保留含有 set “t”中元素的 set “s”
s -= ts.difference_update(t)返回删除了set “t”中含有的元素后的 set “s”
s^=ts.symmetric_difference_update(t)返回含有 set “t”或者 set “s”中有而不是两者都有的元素的 set “s”
  • 常用函数和方法
函数或方法说明
t.add('x')添加一项
s.update([10,37,42])在s中添加多项
t.remove('H')使用remove()可以删除一项
s.discard(x)如果在 set “s”中存在元素 x, 则删除
s.pop()删除并且返回 set “s”中的一个不确定的元素, 如果为空则引发 KeyError
s.clear()删除 set “s”中的所有元素
hash(s)返回 s 的 hash 值
s.copy()返回 set “s”的一个浅复制
len(s)set 的长度

7. 函数

7.1. 函数的定义和调用

def my_abs(x):
	# 数据类型检查
    if not isinstance(x,(int,float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x

7.2. 函数的参数

可变和不可变类型

  • 不可变类型:
    类似 C++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
  • 可变类型:
    类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
def add_end(L=None):
    if L is None:
        L=[]
    else:
        L.append('END')
    return L

>>> L=[1,2,3]
>>> add_end(L)
[1, 2, 3, 'END']

参数类型

  • 位置参数或必选参数
  • 默认参数
def power(x,n=2):
	return x**2
  • 可变参数
    传入的参数个数可变,参数前加*。**参数接收到一个tuple。**如果已经有一个list或者tuple,则在其前面加上*作为参数传入。
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

>>>calc(1,2,3,4)
30

>>>calc(*[1,2,3,4])
30
  • 关键字参数
    允许传入0个或任意个含有参数名的参数。这些关键字参数在函数内部被自动组装成一个dict。参数前加**
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)

>>>person('Bob',12,city='Nanjing')
name: Bob age: 12 other: {'city': 'Nanjing'}

>>>extra={'city':'Nanjing','job':'Engineer'}
>>>person('Bob',12,**extra)
name: Bob age: 12 other: {'city': 'Nanjing', 'job': 'Engineer'}
  • 命名关键字参数
    限制关键字参数的名字。
def person(name, age, *,city,job):
    print('name:', name, 'age:', age, 'city:',city,'job:', job)

>>>person('Adam',12,city='Nanjing',job='Engineer')
name: Adam age: 12 city: Nanjing job: Engineer

# 如果函数定义中已经有了可变参数*arg
def person(name, age, *args, city,job):
    print('name:', name, 'age:', 'args:',args ,age, 'city:',city,'job:', job)

>>>person('Adam',12,*[1,2,3],city='Nanjing',job='Engineer')
name: Adam age: args: (1, 2, 3) 12 city: Nanjing job: Engineer
  • 参数组合
    传入函数的参数要按照以下顺序排列,必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
def person(name,age=12,*args,city,job,**kw):
    print(name,age,args,city,job,kw)

>>>extra={'Gender':'Male','Marriage':'No'}
>>>person('Adam',13,*[1,2,3],city='Nanjing',job='Engineer',**extra)
Adam 13 (1, 2, 3) Nanjing Engineer {'Gender': 'Male', 'Marriage': 'No'}

>>>args=['Adam',13,*[1,2,3]]
>>>kw={'city':'Nanjing','job':'Engineer','Gender':'Male','Marriage':'No'}
>>>person(*args,**kw)
Adam 13 (1, 2, 3) Nanjing Engineer {'Gender': 'Male', 'Marriage': 'No'}

8. 高级特性

8.1. 切片 slicing

listtuple的部分元素可以用切片。字符串也可以看成list

#生成一个从0到99的list
L = list(range(100))
L[0:10]      #取L的前十个数(0-9),L[10]不取。
L[:10]       #取L的前十个数(0-9)
L[10:20]     #取L的前11-20个数(10-19)
L[:10:2]     #取L的前10个数,每两个取一个。([0, 2, 4, 6, 8])
L[::5]       #所有数,每5个取一个
L[-1]        #最后一个数
L[-10:-1]    #倒数第十个数到倒数第一个数,但倒数第一个数不取。(9个数)
L[-10:]      #倒数第十个数到末尾。(10个数)

8.2. 迭代 iteration

如果给定一个listtupledict或者字符串,我们可以通过for循环来遍历这个对象,这种遍历我们称为迭代(Iteration)。只要是可迭代对象,无论有无下标,都可以迭代。

通过for循环遍历

#list 列表; tuple类似
L = ['A','B', 3]
for l in L:
    print(l)
A
B
3
#同时引用了两个变量
for x, y in [(1, 1), (2, 4), (3, 9)]:
    print(x, y)
1 1
2 4
3 9

#dict 字典
for key in D.keys():
    print(key)
for v in D.values():
    print(v)
for key,v in D.items():
    print((key,v))

key1
key2
key3
v1
v2
v3
('key1', 'v1')
('key2', 'v2')
('key3', 'v3')

#str 字符串
for ch in 'ABC':
     print(ch)
A
B
C

判断是否可迭代 Iterable

>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False

同时迭代索引和元素对 enumerate

>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C

8.3. 列表生成器 list comprehension

一般格式:

# 单层循环
[fun(x) for x in list if condition]
# 双层循环
[fun(x+y) for x in list1 for y in list2 if condition]

生成[2*2,4*4,6*6,8*8]:

>>>[x*x for x in range(1,10) if x%2==0]
[4, 16, 36, 64]

使用两层循环,可以生成全排列:

>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

一个list中含有字符串、数字和None, 如果我们希望将字符串转换为小写,其他不变,可以采用以下方式。

L = ['Hello', 'World', 18, 'Apple', None]
def fun(x):
    if isinstance(x,str):
        return x.lower()
    else:
        return x
[fun(x) for x in L]

8.4. 生成器 generator

生成器存储的是算法,可以一边循环一边计算,这样可以省去很多存储空间。

利用()创建generator

只要把一个列表生成式的[]改成(),就创建了一个generator

g = (x*x for x in range(10))
  • 可以利用next(g)打印下一个元素
    每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
  • for循环
for n in g:
    print(n)

用函数实现

在某个变量或数前加上yield语句。在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

例1:

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)
g = odd()
next(g)

例2:

def fib(max):
    n,a,b=0,0,1
    while (n<max):
        yield b
        a,b=b,a+b
        n=n+1
    return 'Done'

但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIterationvalue中:

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

8.5. 迭代器 iterator

可以直接作用于for循环的数据类型

一类是集合数据类型,如listtupledictsetstr等;
一类是generator,包括生成器和带yield的generator function。

可迭代对象

list, tuple, dict, set, strgenerator 都是可迭代的

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

迭代器

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator
listdictstrIterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

9. 函数式编程

9.1. 高阶函数

9.1.2. map/reduce

  • map
r = map(f,[x1,x2,x3,...,xn])
list(r) = [f(x1),f(x2),...,f(xn)]

map()传入的第一个参数是f,即函数对象本身。由于结果r是一个IteratorIterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list
例子1:

>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
  • reduce
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
#f接收两个元素

例子1:累加

>>> from functools import reduce
>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25

例子2:将字符串数字`13579`转化为数字13579

from functools import reduce
def char2num(s):
    return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]
def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s))

9.1.3. filter

map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

def is_odd(n):
    return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]

9.1.4. sorted

sorted(iterable,key=None,reverse=False)

key接受一个函数,这个函数只接受一个元素,默认为None
reverse是一个布尔值。如果设置为True,列表元素将被倒序排列,默认为False
默认顺序是按照ASCII码从小到大排序:小数字<大数字<大写字符<小写字符。

students = [('john', 'A', 15), ('jane', 'B', 12), ('dave','B', 10)]
sorted(students,key=lambda x: x[2]) #按照年龄来排序
# 结果:[('dave','B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

9.2. 返回函数

函数作为返回值

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回

def lazy_sum(*args):
    def cal_sum():
        allsum=0
        for i in args:
            allsum=allsum+i
        return allsum
    return cal_sum

>>>f=lazy_sum(*[1,2,3,4])
>>>f()
10

注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用。

闭包

在这个例子中,我们在函数lazy_sum中又定义了函数cal_sum,并且,内部函数cal_sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数cal_sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
有权访问另一个函数作用域内变量的函数都是闭包。
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
例如:

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs
f1, f2, f3 = count()
#f1(),f2(),f3()执行之后的值都是9

如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs
f1, f2, f3 = count()
#f1(),f2(),f3()执行之后的值是1,4,9

9.3. 匿名函数

f = lambda x: x * x
f(0)

9.4. 装饰器

9.5. 偏函数

10. 类

数据封装继承多态只是面向对象程序设计中最基础的3个概念

10.1. 类的定义、实例、属性和方法

# 定义类Student
class Student(object):
	# 属性class_name,由此类生成的实例都有此属性
    class_name='Student_class'
    # 通过__init__为实例强子绑定属性。初始化时必须传入与__init__方法匹配的参数
    def __init__(self,name,score,city):
        self.name=name
        self.score=score
        # __city表示其是private (私有变量)。无法通过`实例变量.__city`访问了
        self.__city=city 
    # method 1
    def print_score(self):
        print('%s:%s,%s' % (self.name,self.score,self.__city))
    # method 2:可以使外部代码要获取private变量
    def get_city(self):
        return self.__city
-----------------------------------------------------------------------
# 实例化
adam = Student('Adam',99,'Nanjing')
# 由于Python是动态语言,根据类创建的实例可以任意绑定属性。
# 为实例绑定属性gender
adam.gender='Male'
# 删除实例的属性gender
del adam.gender
# 打印实例的信息 
adam.print_score()  #Adam:99,Nanjing

10.2. 类的继承和多态

  • **继承:**子类(Subclass)可以继承父类(Base class, Super class)的全部功能。
  • **多态:**如果子类和父类有相同的方法的话,子类的方法会覆盖父类的方法。
  • 开闭原则:1. 对扩展开放:允许新增Animal子类;2. 对修改封闭:不需要修改依赖Animal类型的run_twice()等函数
# Base class
class Animal(object):
    def run(self):
        print('Animal is running...')
    def show_baseclass_name(self):
        print('Baseclass is Animal!')
        
# Subclass of Animal
class Dog(Animal):
    # 此方法会覆盖Animal中的同名方法 
    def run(self):
        print('Dog is running...')
    # 新加一个方法
    def eat(self):
        print('Dog is eating...')
# Subclass of Animal
class Cat(Animal):
    def run(self):
        print('Cat is running...')
        
# Subclass of Dog    
class Husky(Dog):
    def run(self):
        print('Dove is running...')
    def eat(self):
        print('Cat is eating...')

def run_twice(Animal):
    Animal.run()
    Animal.run()
---------------------------------------------------------------------------
# 实例化
animal = Animal()
dog = Dog()
cat = Cat()
husky = Husky()

# 子类继承了父类的方法
dog.show_baseclass_name()     #输出:“Baseclass is Animal!” 

# 子类的run()方法会覆盖父类的run()方法
animal.run()                  #输出:"Animal is running..."
dog.run()                     #输出:“Dog is running...”
cat.run()                     #输出:“Cat is running...”
husky.run()                   #输出:“Husky is running...”

# run_twice()函数
run_twice(dog)                #输出两次"Dog is running..."


11. 错误处理

try…except…finally…
参考:https://www.liaoxuefeng.com/wiki/897692888725344/923056177365248

try:
    print 'try...'
    r = 10 / int('a')
    print 'result:', r
except ValueError, e:
    print 'ValueError:', e
except ZeroDivisionError, e:
    print 'ZeroDivisionError:', e
finally:
    print 'finally...'

#参考资料

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
http://code.ziqiangxuetang.com/python/python-intro.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值