python常用知识点介绍

1. python 邮件发送

import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

sender='xxx' #发件人邮箱地址
receiver='xxx' #收件人邮箱地址
mail_msg='test' #邮件正文内容

message = MIMEMultipart()   #创建带附件的邮件
message['From'] = Header(sender)
message['To'] = Header(receiver)
subject = 'Python 发送邮件' #邮件主题
message['Subject'] = Header(subject, 'utf-8')
message.attach(MIMEText(mail_msg, 'html', 'utf-8'))

att1 = MIMEApplication(open("a.txt",'rb').read()) #添加附件
att1.add_header('Content-Disposition', 'attachment', filename='a.txt')
message.attach(att1)

try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect("xxx") #邮件服务器地址
    smtpObj.sendmail(sender, receiver, message.as_string())
    print ("Send Mail Succeeds")
except smtplib.SMTPException:
    print ("Error: Can't send Mail")

2. python正则表达式

Python使用 re 模块来实现正则表达式功能,实现字符串匹配
(1) re.match()
函数尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。语法:
re.match (pattern, string, flags)
pattern是正则表达式,string是待匹配的字符串,flag是可选的标志位,常用的标志位如下:
#re.I 使匹配对大小写不敏感
#re.M 多行匹配,影响 ^ 和 $
#re.S匹配换行符

(2) re.search
扫描整个字符串并返回第一个成功的匹配

(3)正则表达式中常用规则介绍

[0-9], \d #表示数字0-9任意之一
[a-z] #小写字母任意之一
[A-Z] #大写字母任意之一
\D #等于[^0-9],匹配非数字
\w #等于[0-9a-zA-Z_],匹配大小写字母,数字和下划线任意一个
\W #等于[^0-9a-zA-Z_],匹配非大小写字母,数字和下划线
. #代表任意一个字符
| #表示“或”操作
* #匹配前面的字符0次或者多次(多次包括1次)
*? #惰性匹配,以最少的此时匹配成功
+ #匹配前一个字符或者子表达式1次或者多次
? #匹配前一个字符或者子表达式0次或者1次
{m,n} #匹配前一个字符或者表达式至少m次之多n次
{m,} #匹配前一个字符或者表达式至少m次

贪婪匹配与惰性匹配

print(re.search('a*?','aaab').group(0)) #输出空串
print(re.search('a*','aaab').group(0))  #输出aaa

(4)使用正则表达式匹配反斜杠‘\’

#正则表达式里面,'\\\\'相当于\,正则表达式里面,会先进行字符串转译,再进行正则转译
print (re.search('\\\\n','Hello\World\\nPython').group(0)) # 输出\n
print (re.search(r'\\W','Hello\World\\nPython').group(0))  # 输出\W

3. python3中的telnet远程连接

import telnetlib
import time
class TelnetClient():
    def __init__(self,host,pwd):
        self.host_ip=host
        self.username='root'
        self.password=pwd
        self.tn = telnetlib.Telnet()
        try:
            self.tn.open(self.host_ip,port=23)
        except:
            print('%s网络连接失败'%self.host_ip)
        # 等待login出现后输入用户名,最多等待10秒
        self.tn.read_until(b'login: ',timeout=10)
        self.tn.write(self.username.encode('ascii') + b'\n')
        # 等待Password出现后输入用户名,最多等待10秒
        self.tn.read_until(b'Password: ',timeout=10)
        self.tn.write(self.password.encode('ascii') + b'\n')
        # 延时两秒再收取返回结果,给服务端足够响应时间
        time.sleep(5)
        # 获取登录结果
        # read_very_eager()获取到的是的是上次获取之后本次获取之前的所有输出
        command_result = self.tn.read_very_eager().decode('ascii')
        # print(command_result)
        if 'Login incorrect' not in command_result:
            pass
            # print('%s登录成功'%self.host_ip)
        else:
            raise Exception('%s登录失败,用户名或密码错误'%self.host_ip)

    def execute_command(self,command):
        # 执行命令
        self.tn.write(command.encode('ascii')+b'\n')
        time.sleep(2)
        # 获取命令结果
        command_result = self.tn.read_very_eager().decode('ascii')
        print('命令执行结果:\n%s' % command_result)
        return command_result

4. python 从键盘获取参数

(1)通过input()函数获取,无论输入的是什么,获取到的都是字符串

print(input())

(2)通过sys.argv获取,sys.argv的参数是在运行脚本文件的时候连同文件名一起输入

import sys
print(sys.argv)

5. Python多线程

进程和线程的区别

  • 进程:进程是系统分配内存的最小单位,拥有独立的内存空间,多进程可以并行执行
  • 线程:线程是执行的最小单位,线程不能独立存在,一个进程里面可以有多个线程,pyhton中同一时间只能有一个线程在执行

死锁:若干线程在竞争系统资源的时候,都在等待其他线程释放资源,导致程序无法继续执行
GIL Global Interpreter Lock 全局解释器锁,它使得任何时刻仅有一个线程在执行
并行:parallel,同一时间,有多个任务同时执行
并发:同一时间,只有一个任务在执行,多个任务之间是交替执行的

(1) 不设置join()和setDaemon(True),主线程结束以后,子线程还会继续执行

import threading,time
def thread(a):
    print(a,time.asctime())
    time.sleep(2)
    print('child1', time.asctime())
if __name__=='__main__':
    print('main',time.asctime())
    t1=threading.Thread(target=thread,args=('child0',))
    t1.start()

输出:

main Tue Sep  1 20:42:42 2020
child0 Tue Sep  1 20:42:42 2020
child1 Tue Sep  1 20:42:44 2020

(2)设置了join(),主线程会在join处阻塞,等待子线程执行完毕,主线程再执行

import threading,time
def thread(a):
    print(a,time.asctime())
    time.sleep(2)
    print('child1', time.asctime())

if __name__=='__main__':
    t1=threading.Thread(target=thread,args=('child0',))
    t1.start()
    t1.join(timeout=1) #主线程阻塞1s后,开始执行,不设置timeoute,主线程在子线程执行完,主线程才继续执行
    print('main  ', time.asctime())

输出:

child0 Tue Sep  1 20:47:28 2020
main   Tue Sep  1 20:47:29 2020
child1 Tue Sep  1 20:47:30 2020

(3)设置了setDaemon(True),主线程结束以后,子线程会被强制结束

import threading,time
def thread(a):
    print(a,time.asctime())
    time.sleep(2)
    print('child1', time.asctime())

if __name__=='__main__':
    t1=threading.Thread(target=thread,args=('child0',))
    t1.setDaemon(True)
    t1.start()
    print('main  ', time.asctime())

输出:

child0main    Wed Sep  2 09:57:11 2020Wed Sep  2 09:57:11 2020

(4)如果设置了setDaemon(True)和timeout=1,主线程等待1s后开始执行,主线程结束后,子线程被强制杀死

import threading,time
def thread(a):
    print(a,time.asctime())
    time.sleep(2)
    print('child1', time.asctime())

if __name__=='__main__':
    t1=threading.Thread(target=thread,args=('child0',))
    t1.setDaemon(True)
    t1.start()
    t1.join(timeout=1)
    print('main  ', time.asctime())

输出:

child0 Wed Sep  2 09:58:32 2020
main   Wed Sep  2 09:58:33 2020

(5)线程锁:通过lock.acquire()和lock.release()来对想要保护的变量加锁和释放

import threading
global_num = 0
lock = threading.Lock()
def test1():
    global global_num
    lock.acquire()
    for i in range(100):
        global_num += 1
    lock.release()
    print("test1", global_num)
def test2():
    global global_num
    lock.acquire()
    for i in range(100):
        global_num += 1
    lock.release()
    print("test2", global_num)

t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()

6 传值 or 传地址?

(1) 如果函数收到的是一个不可变对象(比如数字、字符串或者元组)的引用,就不能直接修改原始对象——相当于传值
(2) 如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于传址

7. __new__和__init__的区别

__init__方法是在对象创建之后调用,对 对象进行初始化的
__new__是在对象创建之前调用,创建一个对象,并返回一个对象给__init__
class Persion:
    def __new__(cls, *args, **kwargs):
        print('__new__')
        instace=object.__new__(cls)
        return instace

    def __init__(self):
        print('__init__')

p=Persion()

输出:

__new__
__init__

单例模式的实现:

class Singleton(object):
    instance=None
    def __new__(cls, *args, **kwargs):
        if cls.instance==None:
            cls.instance=object.__new__(cls)
        return cls.instance

s1=Singleton()
s2=Singleton()
print(s1)
print(s2)

输出:

<__main__.Singleton object at 0x0000000001FFC400>
<__main__.Singleton object at 0x0000000001FFC400>

8. python切片操作

(1) 切片操作可以对list,tuple和string来进行,切片操作符是一堆方括号,调用内置的slice()函数来完成切片
(2) 切片操作语法:seq[start:end:step]
Seq代表的是序列名;start是开始位置;end是结束位置;step是步进,默认的步进是1,截取到的序列是一个[start,end)的序列,即不包括seq[end]的值
(3) 示例

s='asdfghj'
print(s[::]) # 截取整个字符串,输出 asdfghj
print(s[1:3:1]) # 取第一个和第二个字符, 输出sd
print(s[::-1]) # 字符串反转,输出jhgfdsa
a=[0,1,2,3,4,5,6,7,8,9]
print a[0::2]     #取出list中偶数下标的值
print a[1::2]     #取出list中奇数下标的值

9,yield

个人理解,yield的作用是产生一个生成器,一般yield用于自定义for循环的范围

def fun():
    print('start')
    while True:
        res= 5
        yield res
        print('res:',res)

g=fun()   # 无输出,因为函数中有yield关键字,fun()函数并没有真正的去执行,而是得到一个生成器,这里对象的名字是g,
a=next(g) # 输出start,这里调用了next方法,函数开始执行,遇到yield之后返回5
print(a)  # 输出5
a=next(g) # 输出:res: 5,再次调用next方法,程序从yield的下一句继续执行
# for i in range(1,2,0.1):   # **这里会报错,因为python里的range只能接受整数**
#     print(i)

# 需要以float类型进行循环,就需要用到yield
def frange(x, y, step):
    while x <= y:
        yield x
        x += step

ll=frange(1.2,3.5,0.5)
for i in ll:
    print(i)

10. import

aa.py文件

print('aa')
print('name:',__name__)

bb.py文件

import aa # 与aa.py在同一文件夹下,可以直接导入
print('bb')
print('name:',__name__)

(1) 执行aa.py, 输出:

aa
name: __main__

(2) 执行bb.py,输出:

aa
name: aa
bb
name: __main__

(3) 从上面的例子中可以看到:
当import一个py文件的时候,里面的代码会被执行
import一个文件的时候,如果不想该文件中的代码被执行,可以将其写在if__name__==’__main__’语句中
(4)Python3中的import采用的是相对路径的方式,模块导入时候的查找顺序是 内置模块 --> 同目录 – > sys.path
(5)
在这里插入图片描述

问:怎样导入上层目录中的文件?即怎样从b.py文件中导入a.py
答:在A文件夹中,新建 init.py 文件,然后使用from A import a.py导入

11. 匿名函数

(1)匿名函数语法:

lambda [arg1 [,arg2,.....argn]]:expression
a=lambda x,y:x+y
print (a(1,2))  # 输出3

冒号后面只能跟表达式,若是加赋值语句等就会出错

12 高阶函数

(1)map()函数
map()是 Python 内置的高阶函数,它接收一个函数 f (f可以是匿名函数,也可以是普通函数)和一个list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回

li=[1,2,3]
a=lambda x:x+x
print (list(map(a,li)))
# 输出:[2, 4, 6]

(2)filter()函数
filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list

def is_odd(x):
    return x%2==0
n=filter(is_odd,[1,2,3,4,5,6,7,8,9,10])
print(list(n))
# 输出[2, 4, 6, 8, 10]

(3)reduce()函数
reduce函数类似map函数,接收一个函数f和一个list,函数f必须有两个形参;
前两个元素传给 函数参数,函数加工后,然后把得到的结果和第三个元素作为两个参数传给函数参数,以此类推。

from functools import reduce
def f(x,y):
    return x+y
a=[1,2,3,4]
print (reduce(f,a))
# 输出10

13. 获取操作系统类型

import sys
print(sys.platform)

14,None,False,True

None和False它们的主要区别是在语义上:
False和True对应,它作为布尔类型用来描述逻辑中“假”这个概念;
None和“存在元素”相对应,“存在元素”反过来为“不存在元素”,也就是None。None的类型是NoneType。Python中没有null。

print(type(None))  # 输出<class 'NoneType'>
print(type(False)) # 输出<class 'bool'>
print(None==False) # 输出Fales
print(not None) # 输出True

15 文件操作

(1)删除一个文件夹下所有的文件和子文件夹


def del_file(filepath):
    """
    删除某一目录下的所有文件或文件夹
    :param filepath: 路径
    """
    del_list = os.listdir(filepath)
    for f in del_list:
        file_path = os.path.join(filepath, f)
        if os.path.isfile(file_path):
            os.remove(file_path)
        elif os.path.isdir(file_path):
            shutil.rmtree(file_path)

删除文件夹、文件,不推荐使用shutil.rmtree和os.remove,这两种方式删除文件不可找回!
推荐使用send2trash

# 删除文件夹或文件,放置到回收站,比较安全,推荐使用
send2trash.send2trash(('D:/111.txt').replace('/', '\\'))

(2)复制文件夹和文件夹

#复制文件夹
shutil.copytree('D:/test/', 'E:/test/')
#复制文件
shutil.copyfile('D:/111.txt', 'E:/111.txt')

(2)os文件目录方法
os.mkdir()
创建单个目录,默认权限是0777,如该目录已存在抛出异常
os.mkdir(‘A’) 表示在当前目录下创建A文件夹

os.makedirs()
递归创建多层目录,如该目录已存在抛出异常,注意:‘E:/a/b’ 和 ‘E:/a/c’ 并不会冲突

os.path.exists(dirs)
判断文件或者目录是否存在

(3)open()文件方法
!!!不要同时读写文件,这样会使文件内容混乱
A. 创建一个文件
f=open(‘A/kk.txt’,‘a+’)
在这里插入图片描述
B、写入文件
f.writelines([‘1’,‘2’,‘\n’]) 参数可以是字符串或者是字符串列表
f.write(‘fff’) 参数必须是字符串

C、读取文件
f.readlines() 返回一个list
f.read(7). 可以读取固定的字节数

D、关闭文件
f.close()

E、with open() as f
以下两段代码是等价的,with open函数在结束的时候会主动帮我们关闭文件

f=open('aa.txt','w+')
try:
    f.write('sss\n')
finally:
    f.close()
with open('aa.txt','r') as f:
    print f.readlines()

16 字典比较

  1. python字典比较,可以通==直接比较两个字典是否相等
  2. 也可以通过diff函数来比较两个字典的异同,使用前需要先执行 pip3 install dictdiffer
from dictdiffer import diff
d1={'a':1,'b':2}
d2={'a':1}
print(list(diff(d1,d2)))

输出如下,表示d2比d1少一个元素,当d1与d2相等的时候,list为空列表

[('remove', '', [('b', 2)])]

diff()函数原文解释:
Compare two dictionary/list/set objects, and returns a diff result.
Return an iterator with differences between two objects.
The diff items represent addition/deletion/change and the item value is a deep copy from the corresponding source or destination objects.

17 time模块

Python 中时间的表示方式:时间戳,格式化的时间字符串,元组(struct_time)
(1) time.strftime(format)
返回格式化的时间字符串,输入为时间元组,没有输入的时间默认返回当前时间
Format表示字符串的格式
%Y——年份
%m——月份
%d——月份中的天数
%H——小时数
%M——分钟数
%S——秒数

import time
print time.strftime('%Y.%m.%d_%H:%M:%S')

输出:
2019.07.05_10:39:25

(2) time.time()
返回当前时间的时间戳,即1970纪元后经过的浮点秒数

(3)time.asctime()
将一个时间的元组转化为这种形式 Fri Jul 5 10:59:20 2019

(4)获取不同时区的时间

tz = pytz.timezone('Asia/Seoul')
tm_seoul = datetime.datetime.now(tz).strftime('%Y-%m-%S:%M:%S')
print tm_seoul

18 保留小数点后几位

n=11.2284
print '%.2f' % n   %四舍五入,保留两位小数
print round(n,2)   %四舍五入,保留两位小数

19 输出不换行

1)在python2中,在print语句最后加个逗号,可以使当前输出不换行
2)在python3中,print(x, end=“”)

20 装饰器

装饰器:在不改变原函数的情况下,代码运行期间动态增加功能的方式,称为装饰器。装饰器就是一个返回函数的高阶函数

import functools
import time
def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args,**kw):
            print ('%s call %s() '%(text,func.__name__))
            return func(*args,**kw)
        return wrapper
    return decorator
@log(text='I')
# 语法糖等价于 now= log(text='I')(now)
def now():
    print(time.asctime())

if __name__=='__main__':
    now()

执行流程:
执行log(text=‘I’),返回decorator函数
再调用返回的函数,参数是now,返回wrapper函数
调用now()函数的时候,会直接执行wrapper函数
输出:
I call now()
Tue Nov 3 15:23:24 2020

21 py文件生成exe文件

安装pyinstaller:pip3 install pyinstaller
-F:打包为单文件
-n 生成的文件名字

pyinstaller -F Try2.py -n sn_pwd.xe

22 各种空值的布尔值

print(bool([]))  # 输出False
print([] == False)  # 输出False,空数组、空字典、空字符串等的布尔值是False,但直接拿这些空值==Flase,结果却不是True
print({}==False,''==False) # 输出False
print(0==False) # 输出True

None表示空值,它是一个特殊 Python 对象, None的类型是NoneType,None的布尔值是False
python中是没有NULL

not None ==True  # 输出  true

23 enumerate

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串),同时列出数据下标和数据

arr=['a','b']
for i,ele in enumerate(arr):
    print i,ele

输出:
0 a
1 b

24 装饰器

在这里插入图片描述
简单的装饰器

import logging

def use_logging(func):   # 装饰器函数
    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()   # 把 foo 当做参数传递进来时,执行func()就相当于执行foo()
    return wrapper

def foo(): # 被装饰的函数
    print('i am foo')

foo = use_logging(foo)  # 因为装饰器 use_logging(foo) 返回的时函数对象 wrapper,这条语句相当于  foo = wrapper
foo()

输出

i am foo
WARNING:root:foo is running

@语法糖

@ 符号就是装饰器的语法糖,它放在函数开始定义的地方,这样就可以省略最后一步再次赋值的操作。

import logging
def use_logging(func):
    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()
    return wrapper

@use_logging
def foo():
    print("i am foo")
foo()

输出

WARNING:root:foo is running
i am foo

有了 @ ,我们就可以省去foo = use_logging(foo)这一句了,直接调用 foo() 即可得到想要的结果
提高程序的可重复利用性,并增加程序的可读性。

装饰有参函数

import logging
def use_logging(func):
    def wrapper(a):
        logging.warn("%s is running" % func.__name__)
        return func(a)
    return wrapper
@use_logging
def foo(a):
    print("i am foo"+a)
foo('11')

输出

i am foo11
WARNING:root:foo is running

带参数的装饰器

def use_logging(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if level == "warn":
                logging.warn("%s is running" % func.__name__)
            elif level == "info":
                logging.info("%s is running" % func.__name__)
            return func(*args)
        return wrapper

    return decorator

@use_logging(level="warn")
def foo(name='oooo'):
    print("i am %s" % name)

foo()

上面的 use_logging 是允许带参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器。我们可以将它理解为一个含有参数的闭包。当我 们使用@use_logging(level=“warn”)调用的时候,Python 能够发现这一层的封装,并把参数传递到装饰器的环境中。
@use_logging(level=“warn”)等价于@decorator

类装饰器

相比函数装饰器,类装饰器具有灵活度大、高内聚、封装性等优点。使用类装饰器主要依靠类的__call__方法,当使用 @ 形式将装饰器附加到函数上时,就会调用此方法。

class Foo(object):
    def __init__(self, func):
        self._func = func

    def __call__(self):
        print ('class decorator runing')
        self._func()
        print ('class decorator ending')

@Foo
def bar():
    print ('bar')

bar()

输出:

class decorator runing
bar
class decorator ending

装饰器顺序
一个函数还可以同时定义多个装饰器,比如:

@a
@b
@c
def f ():
    pass

它的执行顺序是从里到外,最先调用最里层的装饰器,最后调用最外层的装饰器,它等效于
f = a(b(c(f)))

25 python 读写excel文件

利用openpyxl库来进行

# -*- coding:utf-8 -*-
from openpyxl import Workbook
import datetime
from openpyxl import load_workbook

#----------------向文件中写入-------------
wb=Workbook() #创建一个工作簿
ws=wb.active # 获取工作的激活工作表
ws['A1']=42  # 在A1中插入内容
ws.append([1,2,3])  #这里其实是在第二行插入了3个数字,占用了三个单
ws['A2']=datetime.datetime.now()
wb.save('sample.xlsx')

#--------------读文件-----------------#
book = load_workbook('sample.xlsx')  # 打开文件
sheet = book.active
print sheet['A1'].value
print sheet.cell(row=2, column=1).value

sample.xlsx文件内容
在这里插入图片描述

26 Post请求的数据的两种格式

Post请求的数据有两种格式,一种是from data,另一种是request payload
在这里插入图片描述
在这里插入图片描述

当使用的是request payload格式的时候,需要将字典类型的data转化为json格式

requests.post(url=url, data=json.dumps(data), headers=headers, verify=False)

form data和request payload的区别

  • 如果请求的Content-Type设置为application/x-www-form-urlencoded,那么这个Post请求会被认为是Http Post表单请求,那么请求主体将以一个标准的键值对和&的querystring形式出现。这种方式是HTML表单的默认设置,所以在过去这种方式更加常见

  • 其他形式的POST请求,是放到 Request payload 中(现在是为了方便阅读,使用了Json这样的数据格式),请求的Content-Type设置为application/json;charset=UTF-8或者不指定

27 subprocess中文乱码

import subprocess
import sys

def sub_out(cmd):
    pi = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    while pi.poll() is None:  # None表示正在执行中
        r = pi.stdout.readline().decode('gbk')
        sys.stdout.write(r)
    if pi.poll() != 0:  # 不为0表示执行错误
        err = pi.stderr.read().decode("gbk")
        sys.stdout.write(err)


# sub_out('ping qq.com -n 2')
print (subprocess.check_output('ping 192.168.31.66 -n 1').decode('gbk'))

28 ,字典排序

dict={'A':-1,'B':8,'c':4}

print (dict.items())
ali=sorted(dict.items(),key=lambda x:x[0])  
 # key是排序的依据,x[0]表示按照字典的值进行排序
print ali

[(‘A’, -1), (‘c’, 4), (‘B’, 8)] # dict.items()
[(‘A’, -1), (‘B’, 8), (‘c’, 4)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值