python知识点总结(1)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

声明python不同于其他语言的最厉害之处就在于其他的第三方库可以实现不同的功能但是在学习其他第三方库之前我们还需要学习完python语言的基础。基础我们都学过但是总有一些知识点平时很少使用再碰到很陌生。这里我重新看一篇python基础的博客把里面针对个人不怎么友好的记录下来也可以当作一种复习接下来我们就开始学习第三方库的知识了。

一.基础与环境

1.编程语言

不同的编程语言有不同的规定

  • 有的编程语言要求必须提前将所有源代码一次性转换成二进制指令也就是生成一个可执行程序比如 Windows 下的 .exe 文件比如C语言、C++、Golang、汇编语言等它们都属于编译型语言使用的转换工具称为编译器
  • 有的编程语言可以一边执行一边转换需要哪些源代码就转换哪些源代码不会生成可执行程序比如 PythonJavaScriptPHP、Shell 等这类编程语言称为解释型语言使用的转换工具称为解释器

wyBl.jpg

2.Anaconda神器

想要在程序中使用第三方库必须先手动安装它们可以借助 pip 包管理器但有些情况下用 pip 安装库并不是很方便比如说一次性安装多个库时pip 只能一个一个地安装需要编写各种各样的 pip 命令费时费力。再比如使用 pip 安装不同版本的库时例如不同版本的 Pandas还要考虑两者的兼容性问题否则很容易造成混乱甚至错误。

鉴于此我们可以使用Anaconda它 提供有 600 多个与科学计算相关的第三方库安装 Anaconda 的过程中会顺带安装一些常用的库比如 Pillow、Numpy、Matplotlib 等。根据需要你可以对这些库做更新或者卸载等操作。

Anaconda本身也是一个python的IDE但是他没有图像化界面只能使用命令行编译python文件。我们可以使用它来管理我们的pycharm的第三方库只不过我们需要把pycharm的解释器设置为Anaconda然后通过Anaconda管理第三方库。

3.手机python环境

我们平时的操作都是在电脑上进行的如果你想在手机端编写python文件编译和执行可以使用 QPython 来编写、运行 Python 程序。

QPython 是一个专门在安卓设备上运行 Python 程序的软件包含 Python 解释器、执行 Python 代码的终端Terminal、编写 Python 程序的编辑器等。QPython 既能运行 Python 2 版本的程序也能运行 Python 3 版本的程序。打开应用商店搜索“QPython”就可以下载并安装它。

其实远不止只有这一个软件国内也推出了一些python手机端的IDE只要你去找在手机上配置一个python的IDE还是很快的。

4.内置函数

所谓内置函数即你不导入任何库的情况下就可以使用的函数。

于此同时也意味着你自定义函数时需要避开这些关键字。

w2Jq.jpg

二.结构方法

1.三目运算符

在其他语言中我们都很少使用三目运算符更不谈在python中了。在python中使用if语句来实现三目运算符。

使用 if else 实现三目运算符条件运算符的格式如下

exp1 if contion else exp2

condition 是判断条件exp1 和 exp2 是两个表达式。如果 condition 成立结果为真就执行 exp1并把 exp1 的结果作为整个表达式的结果如果 condition 不成立结果为假就执行 exp2并把 exp2 的结果作为整个表达式的结果。

前面的语句max = a if a>b else b的含义是

  • 如果 a>b 成立就把 a 作为整个表达式的值并赋给变量 max
  • 如果 a> b 不成立就把 b 作为整个表达式的值并赋给变量 max。

2.bytes类

在Python中bytes是一种数据类型用于表示字节序列。bytes对象是不可变的它由0到255的整数构成可以通过字面量或使用bytes()函数创建。

以下是一些常见的方式来创建bytes对象

  1. 使用前缀为b的字符串字面量
my_bytes = b'hello'
  1. 使用bytes()构造函数
my_bytes = bytes([72, 101, 108, 108, 111])
  1. 使用十六进制字符串
my_bytes = bytes.fromhex('48656c6c6f')

bytes对象和Python的其他字符串类型如strbytearray之间可以进行转换。要将bytes对象转换为字符串对象可以使用decode()方法:

my_bytes = b'hello'
my_string = my_bytes.decode('utf-8')
print(my_string)  # 输出hello

要将字符串对象转换为bytes对象可以使用encode()方法

my_string = 'hello'
my_bytes = my_string.encode('utf-8')
print(my_bytes)  # 输出b'hello'

3.运算符优先级

wfwx.jpg

这么多的运算符显然不可能全部记住推荐不清楚运算符的优先级时根据你要运算的顺序使用括号。

4.数据结构

python中经常使用的数据结构有列表、元组、字典和集合四种。

详细的我已经专门写了一篇博客点击这里查看原文。

5.字符串方法

以下是 Python 中常用的字符串方法

  1. str.capitalize()将字符串的首字母大写。
  2. str.lower()将字符串中的所有字母转换为小写形式。
  3. str.upper()将字符串中的所有字母转换为大写形式。
  4. str.title()将字符串中每个单词的首字母大写。
  5. str.swapcase()将字符串中的大小写互换。
  6. str.strip([chars])返回移除字符串开头和结尾指定字符后生成的新字符串。
  7. str.replace(old, new[, count])用新字符串替换旧字符串可选参数 count 指定替换次数默认替换所有匹配项。
  8. str.split([sep[, maxsplit]])将字符串按分隔符切分成列表。
  9. str.join(iterable)合并一个可迭代对象中的元素为一个字符串以 str 为分隔符。
  10. str.startswith(prefix[, start[, end]])检查字符串是否以指定前缀开头。
  11. str.endswith(suffix[, start[, end]])检查字符串是否以指定后缀结尾。
  12. str.find(sub[, start[, end]])查找子字符串第一次出现的位置未找到返回 -1。
  13. str.index(sub[, start[, end]])查找子字符串第一次出现的位置未找到抛出 ValueError 异常。
  14. str.count(sub[, start[, end]])计算子字符串在字符串中出现的次数。
  15. str.format(*args, **kwargs)格式化字符串可使用位置参数或关键字参数指定替换值。

此外还有很多其他的字符串方法可以使用 help(str) 命令查看完整列表。

三.流程控制方法

1.assert

assert 语句又称断言语句可以看做是功能缩小版的 if 语句它用于判断某个表达式的值如果值为真则程序可以继续往下执行反之Python 解释器会报 AssertionError 错误。

assert 语句的语法结构为assert 表达式

assert 语句的执行流程可以用 if 判断语句表示如下所示

if 表达式==True:
  程序继续执行
else:
  程序报 AssertionError 错误

有人可能会问明明 assert 会令程序崩溃为什么还要使用它呢这是因为与其让程序在晚些时候崩溃不如在错误条件出现时就直接让程序崩溃这有利于我们对程序排错提高程序的健壮性。因此assert 语句通常用于检查用户的输入是否符合规定还经常用作程序初期测试和调试过程中的辅助工具。

下面的程序演示了 assert 语句的用法

mathmark = int(input())                    #断言数学考试分数是否位于正常范围内
assert 0 <= mathmark <= 100                #只有当 mathmark 位于 [0,100]范围内程序才会继续执行
print("数学考试分数为",mathmark)

2.break和continue

我们知道在执行 while 循环或者 for 循环时只要循环条件满足程序将会一直执行循环体不停地转圈。但在某些场景我们可能希望在循环结束前就强制结束循环Python 提供了 2 种强制离开当前循环体的办法

  1. 使用 continue 语句可以跳过执行本次循环体中剩余的代码转而执行下一次的循环。
  2. 只用 break 语句可以完全终止当前循环。

这就好比在操场上跑步原计划跑 10 圈可是当跑到第 2 圈的时候突然想起有急事要办于是果断停止跑步并离开操场这就相当于使用了 break 语句提前终止了循环。和 break 语句相比continue 语句的作用则没有那么强大它只会终止执行本次循环中剩下的代码直接从下一次循环继续执行。

仍然以在操作跑步为例原计划跑 10 圈但当跑到 2 圈半的时候突然接到一个电话此时停止了跑步当挂断电话后并没有继续跑剩下的半圈而是直接从第 3 圈开始跑。

3.推导式

推导式又称解析器是 Python 独有的一种特性。使用推导式可以快速生成列表、元组、字典以及集合类型的数据因此推导式又可细分为列表推导式、元组推导式、字典推导式以及集合推导式。这里以列表推导式为例解释

列表推导式的语法格式如下

[表达式 for 迭代变量 in 可迭代对象 [if 条件表达式] ]

此格式中[if 条件表达式] 不是必须的可以使用也可以省略。

通过列表推导式的语法格式明显会感觉到它和 for 循环存在某些关联。其实除去 [if 条件表达式] 部分其余各部分的含义以及执行顺序和 for 循环是完全一样的表达式其实就是 for 循环中的循环体即它的执行顺序如下所示

 for 迭代变量 in 可迭代对象
 	表达式

既然它可以理解为一个for循环那么它同样也是可以嵌套的比如

d_list = [(x, y) for x in range(5) for y in range(4)]
# d_list列表包含20个元素
print(d_list)

上面代码中x 是遍历 range(5) 的迭代变量计数器因此该 x 可迭代 5 次y 是遍历 range(4) 的计数器因此该 y 可迭代 4 次。因此该x,y表达式一共会迭代 20 次。上面的 for 表达式相当于如下嵌套循环

dd_list = []
for x in range(5):    
	for y in range(4):        
		dd_list.append((x, y))

4.zip()函数

zip() 函数是 Python 内置函数之一它可以将多个序列列表、元组、字典、集合、字符串以及 range() 区间构成的列表“压缩”成一个 zip 对象。所谓“压缩”其实就是将这些序列中对应位置的元素重新组合生成一个个新的元组。

my_list = [11,12,13]
my_tuple = (21,22,23)

print(list(zip(my_list,my_tuple)))

注意它的返回值是一个zip对象所以需要把它变成你想要的数据结构。

5.reserved()函数

eserved() 是 Pyton 内置函数之一其功能是对于给定的序列包括列表、元组、字符串以及 range(n) 区间该函数可以返回一个逆序序列的迭代器用于遍历该逆序序列。

reserved() 函数的语法格式如下reversed(seq)

其中seq 可以是列表元素字符串以及 range() 生成的区间列表。

使用 reversed() 函数进行逆序操作并不会修改原来序列中元素的顺序例如

a = [1,2,3,4,5]
#将列表进行逆序
print(list(reversed(a)))
print("a=",a)

程序执行结果为

[5, 4, 3, 2, 1]
a= [1, 2, 3, 4, 5]

四.函数

1.局部函数

ython 函数内部可以定义变量这样就产生了局部变量有读者可能会问Python 函数内部能定义函数吗答案是肯定的。Python 支持在函数内部定义函数此类函数又称为局部函数。

例如下面这个程序

#全局函数
def outdef ():    
	name = "所在函数中定义的 name 变量"    
	#局部函数    
	def indef():        
		nonlocal name        
		print(name)        #修改name变量的值        
		name = "局部函数中定义的 name 变量"    
	indef()
	
#调用全局函数
outdef()

程序执行结果为 所在函数中定义的 name 变量

2.偏函数

简单的理解偏函数它是对原始函数的二次封装是将现有函数的部分参数预先绑定为指定值从而得到一个新的函数该函数就称为偏函数。相比原函数偏函数具有较少的可变参数从而降低了函数调用的难度。

定义偏函数需使用 partial 关键字位于 functools 模块中其语法格式如下

偏函数名 = partial(func, *args, **kwargs)

其中func 指的是要封装的原函数*args 和 **kwargs 分别用于接收无关键字实参和关键字实参。

例如下面代码

from functools import partial
#定义个原函数
def display(name,age):
    print("name:",name,"age:",age)
#定义偏函数其封装了 display() 函数并为 name 参数设置了默认参数
GaryFun = partial(display,name = 'Gary')
#由于 name 参数已经有默认值因此调用偏函数时可以不指定
GaryFun(age = 13)

运行结果为

name: Gary age: 13

注意此程序的第 8 行代码中必须采用关键字参数的形式给 age 形参传参因为如果以无关键字参数的方式该实参将试图传递给 name 形参Python解释器会报 TypeError 错误。

3.函数参数

Python 还支持将函数以参数的形式传入其他函数中。例如

def add (a,b):
    return a+b
def multi(a,b):
    return a*b
def my_def(a,b,dis):
    return dis(a,b)
   
#求 2 个数的和
print(my_def(3,4,add))
#求 2 个数的乘积
print(my_def(3,4,multi))

程序执行结果为

7
12

通过分析上面程序不难看出通过使用函数作为参数可以在调用函数时动态传入函数从而实现动态改变函数中的部分实现代码在不同场景中赋予函数不同的作用。

4.闭包函数

闭包又称闭包函数或者闭合函数其实和前面讲的嵌套函数类似不同之处在于闭包中外部函数返回的不是一个具体的值而是一个函数。一般情况下返回的函数会赋值给一个变量这个变量可以在后面被继续执行调用。

例如计算一个数的 n 次幂用闭包可以写成下面的代码

#闭包函数其中 exponent 称为自由变量
def nth_power(exponent):
    def exponent_of(base):
        return base ** exponent
    return exponent_of # 返回值是 exponent_of 局部函数
square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方
print(square(2))  # 计算 2 的平方
print(cube(2)) # 计算 2 的立方

运行结果为

4
8

在上面程序中外部函数 nth_power() 的返回值是函数 exponent_of()而不是一个具体的数值。

5.lambda表达式匿名函数

lambda 表达式又称匿名函数常用来表示内部仅包含 1 行表达式的函数。如果一个函数的函数体仅有 1 行表达式则该函数就可以用 lambda 表达式来代替。

lambda 表达式的语法格式如下 name = lambda [list] : 表达式

其中定义 lambda 表达式必须使用 lambda 关键字[list] 作为可选参数等同于定义函数是指定的参数列表value 为该表达式的名称。

举个例子如果设计一个求 2 个数之和的函数使用普通函数的方式定义如下

def add(x, y):    
	return x+ y
print(add(3,4))

程序执行结果为

7

由于上面程序中add() 函数内部仅有 1 行表达式因此该函数可以直接用 lambda 表达式表示

add = lambda x,y:x+y
print(add(3,4))

程序输出结果为

7

可以这样理解 lambda 表达式其就是简单函数函数体仅是单行的表达式的简写版本。相比函数lamba 表达式具有以下 2 个优势

  • 对于单行函数使用 lambda 表达式可以省去定义函数的过程让代码更加简洁
  • 对于不需要多次复用的函数使用 lambda 表达式可以在用完之后立即释放提高程序执行的性能。

6.解释器函数

这里的解释器函数指的是eval()和exec()函数这是我个人的叫法。

eval() 和 exec() 函数的功能是相似的都可以执行一个字符串形式的 Python 代码代码以字符串的形式提供相当于一个 Python 的解释器。二者不同之处在于eval() 执行完要返回结果而 exec() 执行完不返回结果。

a=10
b=20
c=30
g={'a':6, 'b':8} #定义一个字典
t={'b':100, 'c':10} #定义一个字典
print(eval('a+b+c', g, t)) #定义一个字典 116

输出结果为

116

7.函数式编程

所谓函数式编程是指代码中每一块都是不可变的都由纯函数的形式组成。这里的纯函数是指函数本身相互独立、互不影响对于相同的输入总会有相同的输出。

Python 仅对函数式编程提供了部分支持主要包括 map()、filter() 和 reduce() 这 3 个函数它们通常都结合 lambda 匿名函数一起使用。

  1. map() 函数的基本语法格式如下map(function, iterable)

其中function 参数表示要传入一个函数其可以是内置函数、自定义函数或者 lambda 匿名函数iterable 表示一个或多个可迭代对象可以是列表、字符串等。

map() 函数的功能是对可迭代对象中的每个元素都调用指定的函数并返回一个 map 对象。

注意该函数返回的是一个 map 对象不能直接输出可以通过 for 循环或者 list() 函数来显示。

  1. filter()函数的基本语法格式如下filter(function, iterable)

此格式中funcition 参数表示要传入一个函数iterable 表示一个可迭代对象。

filter() 函数的功能是对 iterable 中的每个元素都使用 function 函数判断并返回 True 或者 False最后将返回 True 的元素组成一个新的可遍历的集合。

  1. reduce() 函数通常用来对一个集合做一些累积操作其基本语法格式为reduce(function, iterable)

其中function 规定必须是一个包含 2 个参数的函数iterable 表示可迭代对象。

注意由于 reduce() 函数在 Python 3.x 中已经被移除放入了 functools 模块因此在使用该函数之前需先导入 functools 模块。

五.类和对象

1.相关术语

面向对象中常用术语包括

  • 可以理解是一个模板通过它可以创建出无数个具体实例。比如前面编写的 tortoise 表示的只是乌龟这个物种通过它可以创建出无数个实例来代表各种不同特征的乌龟这一过程又称为类的实例化。
  • 对象类并不能直接使用通过类创建出的实例又称对象才能使用。这有点像汽车图纸和汽车的关系图纸本身类并不能为人们使用通过图纸创建出的一辆辆车对象才能使用。
  • 属性类中的所有变量称为属性。例如tortoise 这个类中bodyColor、footNum、weight、hasShell 都是这个类拥有的属性。
  • 方法类中的所有函数通常称为方法。不过和函数所有不同的是类方法至少要包含一个 self 参数后续会做详细介绍。例如tortoise 类中crawl()、eat()、sleep()、protect() 都是这个类所拥有的方法类方法无法单独使用只能和类的对象一起使用。

2.基础格式

鉴于都有一定了解直接举个例子

class tortoise:
    bodyColor = "绿色"
    footNum = 4
    weight = 10
    hasShell = True
    #会爬
    def crawl(self):
        print("乌龟会爬")
    #会吃东西
    def eat(self):
        print("乌龟吃东西")
    #会睡觉
    def sleep(self):
        print("乌龟在睡觉")
    #会缩到壳里
    def protect(self):
        print("乌龟缩进了壳里")

3.__init__()类构造方法

在创建类时我们可以手动添加一个 init() 方法该方法是一个特殊的类实例方法称为构造方法或构造函数。

构造方法用于创建对象时使用每当创建一个类的实例对象时Python 解释器都会自动调用它。Python 类中手动添加构造方法的语法格式如下

def __init__(self,...):
  代码块

注意此方法的方法名中开头和结尾各有 2 个下划线且中间不能有空格。Python 中很多这种以双下划线开头、双下划线结尾的方法都具有特殊的意义。另外__init__() 方法可以包含多个参数但必须包含一个名为 self 的参数且必须作为第一个参数。也就是说类的构造方法最少也要有一个 self 参数。

注意即便不手动为类添加任何构造方法Python 也会自动为类添加一个仅包含 self 参数的构造方法。

仅包含 self 参数的 init() 构造方法又称为类的默认构造方法。

下面我们举个例子来通过该函数创建一个实例

class CLanguage :
    # 下面定义了2个类变量
    name = "CSDN@终究还是散了"
    add = "https://blog.csdn.net/weixin_51496226?spm=1000.2115.3001.5343"
    def __init__(self,name,add):
        #下面定义 2 个实例变量
        self.name = name
        self.add = add
        print(name,"网址为",add)
    # 下面定义了一个say实例方法
    def say(self, content):
        print(content)
# 将该CLanguage对象赋给clanguage变量
clanguage = CLanguage("CSDN@终究还是散了","https://blog.csdn.net/weixin_51496226?spm=1000.2115.3001.5343")

4.封装

和其它面向对象的编程语言如 C++、Java不同Python 类中的变量和函数不是公有的类似 public 属性就是私有的类似 private这 2 种属性的区别如下

  • public公有属性的类变量和类函数在类的外部、类内部以及子类后续讲继承特性时会做详细介绍中都可以正常访问
  • private私有属性的类变量和类函数只能在本类内部使用类的外部以及子类都无法使用。

但是Python 并没有提供 public、private 这些修饰符。为了实现类的封装Python 采取了下面的方法

  • 默认情况下Python 类中的变量和方法都是公有public的它们的名称前都没有下划线_
  • 如果类中的变量和函数其名称以双下划线“__”开头则该变量函数为私有变量私有函数其属性等同于 private。
    #定义个私有方法
    def __display(self):
        print(self.__name,self.__add)

例如上述函数就是一个私有函数它使用的变量也是私有变量。

5.继承

继承机制经常用于创建和现有类功能类似的新类又或是新类只需要在现有类基础上添加一些成员属性和方法但又不想直接将现有类代码复制给新类。也就是说通过使用继承这种机制可以轻松实现类的重复使用。

举个例子假设现有一个 Shape 类该类的 draw() 方法可以在屏幕上画出指定的形状现在需要创建一个 Form 类要求此类不但可以在屏幕上画出指定的形状还可以计算出所画形状的面积。使用类的继承机制实现方法为让 Form 类继承 Shape 类这样当 Form 类对象调用 draw() 方法时Python 解释器会先去 Form 中找以 draw 为名的方法如果找不到它还会自动去 Shape 类中找。如此我们只需在 Form 类中添加计算面积的方法即可示例代码如下

class Shape:    
	def draw(self,content):        
		print("画",content)
		
class Form(Shape):    
	def area(self):        #....        
		print("此图形的面积为...")

上面代码中class Form(Shape) 就表示 Form 继承 Shape。

Python 中实现继承的类称为子类被继承的类称为父类也可称为基类、超类。因此在上面这个样例中Form 是子类Shape 是父类。

子类继承父类时只需在定义子类时将父类可以是多个放在子类之后的圆括号里即可。语法格式如下

class 类名(父类1, 父类2, ...)
  #类定义部分

注意如果该类没有显式指定继承自哪个类则默认继承 object 类object 类是 Python 中所有类的父类即要么是直接父类要么是间接父类。另外Python 的继承是多继承机制和 C++ 一样即一个子类可以同时拥有多个直接父类。

注意有读者可能还听说过“派生”这个词汇它和继承是一个意思只是观察角度不同而已。换句话话继承是相对子类来说的即子类继承自父类而派生是相对于父类来说的即父类派生出子类。

使用多继承经常需要面临的问题是多个父类中包含同名的类方法。对于这种情况Python 的处置措施是根据子类继承多个父类时这些父类的前后次序决定即排在前面父类中的类方法会覆盖排在后面父类中的同名类方法。

6.type()函数

我们知道type() 函数属于 Python 内置函数通常用来查看某个变量的具体类型。其实type() 函数还有一个更高级的用法即创建一个自定义类型也就是创建一个类。

type() 函数的语法格式有 2 种分别如下

type(obj) 
type(name, bases, dict)

以上这 2 种语法格式各参数的含义及功能分别是

  • 第一种语法格式用来查看某个变量类对象的具体类型obj 表示某个变量或者类对象。
  • 第二种语法格式用来创建类其中 name 表示类的名称bases 表示一个元组其中存储的是该类的父类dict 表示一个字典用于表示类内定义的属性或者方法。

这里重点介绍 type() 函数的另一种用法即创建一个新类先来分析一个样例

#定义一个实例方法
def say(self):    
    print("我要学 Python")
#使用 type() 函数创建类
CLanguage = type("CLanguage",(object,),dict(say = say, name = "CSDN@终究还是散了"))
#创建一个 CLanguage 实例对象
clangs = CLanguage()
#调用 say() 方法和 name 属性
clangs.say()
print(clangs.name)

注意Python 元组语法规定当 (object,) 元组中只有一个元素时最后的逗号,不能省略。

可以看到此程序中通过 type() 创建了类其类名为 CLanguage继承自 objects 类且该类中还包含一个 say() 方法和一个 name 属性。

7.多态

类的多态特性要满足以下 2 个前提条件

  1. 继承多态一定是发生在子类和父类之间
  2. 重写子类重写了父类的方法。
class WhoSay:
    def say(self,who):
        who.say()
class CLanguage:
    def say(self):
        print("调用的是 Clanguage 类的say方法")
class CPython(CLanguage):
    def say(self):
        print("调用的是 CPython 类的say方法")
class CLinux(CLanguage):
    def say(self):
        print("调用的是 CLinux 类的say方法")
a = WhoSay()
#调用 CLanguage 类的 say() 方法
a.say(CLanguage())
#调用 CPython 类的 say() 方法
a.say(CPython())
#调用 CLinux 类的 say() 方法
a.say(CLinux())

可以看到CPython 和 CLinux 都继承自 CLanguage 类且各自都重写了父类的 say() 方法。从运行结果可以看出同一变量 a 在执行同一个 say() 方法时由于 a 实际表示不同的类实例对象因此 a.say() 调用的并不是同一个类中的 say() 方法这就是多态。

六.说明

还有几个点没写我准备写在下一篇博客大家期待

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: python