python 函数修饰器 父类_Python函数嵌套、回调函数、闭包、装饰器和类

markdown内容:Python函数嵌套、回调函数、闭包、装饰器和类

一级标题:主要描述内容

二级标题:各个内容

三级标题:重要概念

一、函数嵌套

1.1、作用域和嵌套函数

LEGB查找规则的 E, E 包括了任意外层函数局部作用域的形式。嵌套作用域有时也叫作静态嵌套作用域。

1.2、变量名查找规则:LEGB 规则

对于一条def语句:

​ ---在默认情况下,变量名赋值会创建或者改变局部变量;

​ ---变量名引用至多可以在四个作用域内进行查找:首先是局部,其次是外层的函数(如果有的话),之后是全局,最后是内置。

​ ---使用global和nonlocal语句声明的名称将赋值的变量名分别映射到外围的模块和函数的作用域。

​ 所有函数 def 语句内赋值的变量名默认均为局部变量。函数能够随意使用在外层函数或者全局作用域中的变量名,但要改变其属性必须声明为非局部变量和全局变量。

LEGB规则

(1)、当你在函数中使用未限定的变量名时,Python将查找4个作用域并在第一次找到该变量名的地方停下来:首先是局部作用域(L),其次是外一层的def或lambda的局部作用域(E),之后是全局作用域(G),最后是内置作用域(B)。如果在这一过程中没有被查找到,Python会报错。

(2)、当你在函数中给一个变量名赋值时,(而不是只在一个表达式中对其进行引用),Python便会创建或改变局部作用域的变量名,除非该函数变量名已经在该函数中被声明为局部变量。

(3)、当你在所有函数的外面给一个变量名赋值时,此时的局部作用域就是全局作用域。

1.3、global语句

global语句包含关键词global,其后跟着一个或多个由 ‘,’ 分割开的变量名。当函数主体被赋值或引用时,所有列出来的变量名被映射到整个模块的作用域内。

x = 1

def cal():

global x

x = 17

print('function is over')

cal() #out: function is over

print(x) #out: 17

二、回调函数

2.1、回调函数:通过一个函数指针调用的函数。

如果你把函数的指针(地址)作为一个参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是一个回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

在Python中,函数本身也是对象,所以可以将函数作为参数传入另一函数并进行调用。

回调函数还可以进行异步调用,即非阻塞调用,通常用在多线程或者多进程中。

def calculate(x,y,func):

return func(x,y)

def max(x,y):

while x>y:

print(x)

else:

print(y)

def sum(x,y):

print(x+y)

if __name__ = "_main_":

result_max = calculate(5,7,max)

print(result_max)

result_sum = calculate(5,7,sum)

print(result_sum)

2.2、C语言指针:指针是一种保存变量地址的变量

C语言里面,变量存放在内存之中,而内存其实就是一组有序字符串组成的数组,每个字节有惟一的内存地址。CPU通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。这里,数据对象是指内存中的一个指定数据类型的数值或字符串,他们都有一个自己的地址,而指针便是保存这个地址的变量。也就是说,指针是一种保存变量地址的变量。

内存是一组有序字节组成的数组,数组中,每个字节大小固定,都是8 bit。这些连续字节从0开始进行编号,每个字节都有唯一的一个编号,这个编号便是内存地址。如图:

左侧十六进制编号就是内存地址,每个内存地址对应一个字节的内存空间。而指针变量保存的就是这个编号,也即内存地址。

三、工厂函数(factory function):闭包(closure)

3.1、什么是闭包

闭包能够记忆外层作用域里的值,不管那些嵌套作用域是否还在内存中存在。从结果上看,它们附加了内存包(又称状态记忆),它对于每一个被创建的嵌套函数副本而言都是局部的,从这一作用来看,它们经常提供了一种类的简单替代方法。

在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。

一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。

使用闭包的过程中,一旦外函数被调用一次返回了内函数的引用,虽然每次调用内函数,是开启一个函数执行过后消亡,但是闭包变量实际上只有一份,每次开启内函数都在使用同一份闭包变量

3.2、如何调用

#工厂函数

# 实例一

def power(n):

def func(x):

return x**n

return func

f_p4 = power(4)

m = f_p4(5)

print(m) #out:625

n = f_p4(3)

print(n) #out:81

f_p6 = power(6)

l = f_p6(2)

print(l) #out:64

# 实例二

def max():

x = 77

def ming():

return x

return ming

f = max()

print(f()) #f() = 77

四、装饰器

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

# 实例一

'''我们希望在不修改"sayhi"函数的情况下在其之前再输出一句话,这种在代码运行期间动态增加功能的方法,称之为“装饰器”。'''

ddef decorator(func):

print('给你一张漂亮的地图')

def wrapper():

func()

print('给你一台电子计算机')

return func

return wrapper

@decorator

def gift():

print('我想要一个礼物')

gift()

'''输出结果:给你一张漂亮的地图我想要一个礼物给你一台电子计算机'''

# 实例二

4.1、装饰器的概念

装饰是为函数和类指定管理或增加代码的一种方式。装饰器本身可以采取可调用对象的形式(如函数),并处理其他可调用对象。

函数装饰器:

在函数定义的时候进行名称重绑定,提供一个逻辑层来管理函数和方法,以及管理随后对它们的调用。

类装饰器:

在类定义的时候进行名称重绑定,提供一个逻辑层来管理类,以及管理随后它们所创建的实例。

简而言之,装饰器提供了一种方法,在函数和类定义语句结束时,插入自动运行的代码。对于函数装饰器,def语句结束时插入;对于类装饰器,在class语句结束时插入。

4.2、管理和调用

在通常的方法中,这种自动运行的代码可能用来扩展对函数和类的调用。它通过安装随后被调用的包装器(即代理)对象来实现这一点:

调用代理:

函数装饰器安装包装器对象,以在需要的时候拦截之后的函数调用并处理它们,通常将调用继续传递到原始函数以执行管理好的动作。

接口代理:

类装饰器安装包装器对象,以在需要的时候拦截之后的实例创建调用并处理它们,通常将调用继续传递到原始类以执行管理好的实例。

装饰器通过def和class语句的末尾自动把函数名和类名重绑定到其他可调用对象上来实现这些效果。当之后调用的时候,这些可调用对象可以完成诸如跟踪和计时函数调用、管理类实例属性访问等任务。

五、类

5.1、类定义

在Python中,所有数据类型都被视为是对象(object),也可以自定义对象。自定义对象数据类型就是面向对象中的类(class)的概念。

类提供了一种组合数据和功能的方法。 创建一个新类意味着创建一个新的对象类型,从而允许创建一个该类型的新实例 。 每个类的实例可以拥有保存自己状态的属性。 一个类的实例也可以有改变自己状态的(定义在类中的)方法。

5.2、一些相关的概念类:用来描述具有相同属性和方法的对象的对象的集合。类定义了集合中每个对象共有的属性和方法。对象是类的实例。

类变量(属性):类变量在整个实例化的对象中是公用的。类变量定义在类中,且在方法之外。类变量通常不作为实例变量使用。类变量也称作属性。

数据成员:类变量或实例变量用于处理类及其实例对象的相关数据。

方法重写:如果从父类继承过来的方法不能满足子类的需求,就可以对其进行改写,这个过程称为方法的覆盖(override),也称为方法的重写。

实例变量:定义在方法中的变量,只作用于当前类的实例。

多态(polymorphism):对不同类的对象使用同样的操作。

封装(encapsulation):对外部世界隐藏对象的工作细节。

继承(inheritance):即一个派生类(derived class)继承基类(base class)的字段和方法。继承允许把一个派生类的对象作为一个基类对象来对待,以普通类为基础建立专门的类对象。

实例化(instance):创建一个类的实例、类的具体对象。

方法:类中定义的函数。

对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

5.3、类属性(类变量)

类变量指的是在类中,但在各个类方法外定义的变量。

类变量(属性):类变量在整个实例化的对象中是公用的。类变量定义在类中,且在方法之外。类变量通常不作为实例变量使用。类变量也称作属性。

class Stu():

school = "peking university" # 类变量

grade = "freshman" # 类变量

def __init__(self,name):

self.name = name

self.age = 19

类变量的特点是,所有类的实例化对象都同时共享类变量,也就是说,类变量在所有实例化对象中是作为公用资源存在的。类属性的调用方式有 2 种( object.name ),既可以使用 “类名.属性名” 直接调用,也可以使用 “类的实例化对象名.属性名”调用。

class Stu():

school = "peking university" # 类变量

grade = "freshman" # 类变量

def __init__(self,name):

self.name = name

self.age = 19

print(Stu.school) #推荐方法

print(Stu.grade) #推荐方法

s = Stu('学生')

print(s.school) #不推荐

print(s.grade) #不推荐

5.4、实例属性(实例变量)

实例变量:定义在方法中的变量,只作用于当前类的实例。

实例变量指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象。另外,实例变量只能通过对象名访问,无法通过类名访问。

class Stu():

school = "peking university" # 类变量

grade = "freshman" # 类变量

def __init__(self,name):

self.name = name #实例变量

self.age = 19 #实例变量

def campus(self):

self.cam = 'medical college'

s = Stu('xuyang')

print(Stu.name) #报错

print(s.name)

print(s.age)

s1 = Stu('xiehe')

s1.campus() #只有调用campus方法,才能取出实例属性self.cam

print(s1.cam)

我们可以将类看做一个独立的空间,则类属性其实就是在类体中定义的变量,类方法是在类体中定义的函数。无论是类属性还是类方法,都无法同普通变量或是函数那样,在类的外部直接就能调用。

5.5、实例方法、self参数在类编程中,一般情况下在类中定义的方法/函数默认都是实例方法。

python 的类编程中实例方法最少要有一个 self 参数,该 self 参数的作用是绑定调用此方法的实例对象。下面代码中的 sel f参数,不管是 __init__ 方法还是 campus 方法,其中的 self 都是指向实例s和s1本身。

self在内存中其实是一串地址。

只能由实例对象调用。

class Stu():

school = "peking university" # 类变量

grade = "freshman" # 类变量

def __init__(self,name):

self.name = name #实例变量

self.age = 19 #实例变量

def campus(self):

self.cam = 'medical college'

s = Stu('xuyang')

print(Stu.name) #报错

print(s.name)

print(s.age)

s1 = Stu('xiehe')

s1.campus() #只有调用campus方法,才能取出实例属性self.cam

print(s1.cam)

5.6、类方法 ( classmethod )

Python 中的类方法和实例方法类似,但类方法需要满足以下要求:类似于实例方法,类方法至少需要包含一个参数,但与实例方法不同,该参数非为self,而是python约定俗成的参数:cls

Python 会自动将类本身绑定到cls参数上面(并不是类的对象),在调用时,无需显式地为 cls 传递参数

定义类方法需要使用修饰语句: @classmethod

类方法可以通过类直接调用,也可以通过实例直接调用(不推荐)。但无论哪种调用方式,最左侧传入的参数一定是类本身。

class Stu():

count = 0

@classmethod

def grade(cls):

cls.count += 1

if cls.count >= 6:

print('错误')

else:

print('学生的年级是:%d'%cls.count)

def age(self):

self.age = 14

print(self.age += 1)

pass

Stu.grade() #grade方法是是类方法,但是同实例方法一样,不需要显式地为cls传递参数进去

s = Stu()

s.grade()

s.age()

print(s.age)

5.7、静态方法 (staticmethod )定义:

​ 使用装饰器 @staticmethod 。参数随意,没有“self”和“cls”参数。方法体中不能使用类或实例的任何属性和方法。类中的静态方法,实际上就是普通函数,存在的唯一区别是:

​ 类静态方在类命名空间中定义,而函数则在程序的全局命名空间中定义。注意:

​ 类静态方法没有 self、cls 这样的特殊参数,故 Python 解释器不会对其进行任何类或对象的绑定。类静态方法中无法调用任何类和对象的属性和方法,类静态方法与类的关系不大。调用:

​ 实例对象和类对象都可以调用。在调用过程中,无需将类实例化,直接使用“object.name"调用。

静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。

class City():

def __init__(self,city1,city2,city3,p):

self.city_rec = city1

self.city_med = city2

self.city_send = city3

self.price = p

@classmethod

def cost(cls):

cls.cost = (self.self.city_rec - self.self.city_med - cls.self.city_send) * p

@staticmethod

def ad():

ad_dic = {'fz':108,'sh':202,'fz' = 704}

def

5.8、方法和函数

封装了一系列动作。方法和函数最大的区别就是调用方法。

5.9、公有变量、私有变量、保护变量

Python并没有真正的私有化支持,使用双下划线进行伪私有。

私有属性(private attributes),包括私有方法和私有变量,指的是只供一个类或者实例内部使用的方法和变量。这些方法和变量能在类和实例的外部调用。

'''var:公有变量_var:单前置下划线,保护变量,类对象(即类的实例)和子类对象自己能访问到这些变量,需通过类提供的接口进行访问。但不能通过 from module import * 导入__var:双前置下划线,私有变量,无法在类外部直接访问(命名重整机制,访问不到)。但可以通过 instance._Class__object 访问。var_:单后置下划线,用于变量命名,为了避免与Python中自有的关键词的冲突'''

class Stu():

__college = 'pku'

def __init__(self):

self.__grade = '1'

print('学校是%s,年级是%s'%(self.__college,self.__grade),end='\n\n')

pass

s = Stu()

#s.__college 会报错

print (s._Stu__college) #只能使用这种方法来访问

5.10、@property

Python内置有三大装饰器:@ staticmethod (静态方法)、@ classmethod (类方法)、@property (描述符)。

@property装饰器,这是个python内置的装饰器,主要是作用是把类中的一个方法变为类中的一个属性,并且使定义属性和修改现有属性变的更容易。被 @property 装饰的方法是获取属性值的方法,被装饰方法的名字会被用做属性名。

被 @方法名.setter 装饰的方法是设置属性值的方法。

被 @方法名.deleter 装饰的方法是删除属性值的方法。

Python中属性和方法访问存在权限的问题,一般我们不太建议将属性设置为私有的。但是如果直接将属性暴露给外界也是很有问题的,容易在类外部被破坏。建议是将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问。

这就可以考虑使用@property装饰器来进行包装,通过getter(访问器)和setter(修改器)方法,使得对属性的访问既安全又方便。

那么如果想访问属性可以通过属性的getter(访问器)和setter(修改器)方法对类所定义的方法进行对应的操作,将类中的封装的属性进行一定程度的隔离。

class City():

def __init__(self,province):

self.__eara = 'east'

self.__province = province

@property

def eara(self):

return self.__eara

@eara.setter #setter方法的eara必须同上面@property的eara相同,它们装饰的是同一个方法

def eara(self,p):

self.__province = p

self.__eara = 'west'

print('地点%s,省份%s'%(self.__eara,self.__province))

pass

c = City('zhejiang')

print(c.eara)

c.eara = 'xu'

print(c.eara)

5.11、魔术方法

5.12、描述器

5.12.1、定义:

一般地,一个描述器是一个包含 “绑定行为” 的对象,对其属性的存取被描述器协议中定义的方法覆盖。这些方法有:___get()、__set()、__delete()。如果某个对象中定义了这些方法中的任意一个,那么这个对象就可以被称为一个描述器。

(描述器是一个对象,可以描述一个属性的操作。其作用是对属性的操作做验证和过滤,如对一个人的年龄赋值时,不能赋值为负数,这是需要验证和过滤,当属性过多时,由于不能在赋值前进行验证,所以用到描述器,每次验证时就会进入描述器中进行相关操作。)描述器的定义方式一:使用property将操作方法与属性进行关联,即可在操作属性时自动进行相关方法执行。

描述器的定义方式二:对方式一进行优化,即多个属性时,由于操作内容不同,在主类中代码会过于繁琐,为简化代码,将属性的操作方法封装到类中,在主类中对方法类的实例对象进行操作即可。

5.12.2、property

可以使用定义类的方式使用描述符,但是如果每次为了一个属性都单独定义一个类,有时将变得得不偿失。为此,python提供了一个轻量级的数据描述符协议函数 Property(),其使用装饰器的模式,可以将类方法当成属性来访问。它的标准定义是:

property(fget=None,fset=None,fdel=None,doc=None)

前面3个参数都是未绑定的方法,所以它们事实上可以是任意的类成员函数,分别对应于数据描述符的中的、__get__(),__set__(),__del__()方法,所以它们之间会有一个内部的与数据描述符的映射。

property有两种使用方式,一种是函数模式,一种是装饰器模式。

5.12.3、描述器协议

5.12.4、调用描述器

5.12.5、相关实现实例

#实例一,不用任何描述器,进行属性增删改查操作

class Stu(object):

def __init__(self):

self.__college = 'pku'

self.__adr = 'beijing'

self.__grade = 1

def get__grade(self):

return self.__grade

def set__grade(self,value):

if value >1 and value <5:

self.get__grade = value

else :

print('error')

def delete__grade(self):

del self.__grade

pass

s1 = Stu()

print(s1) #(self)结果为一串内存地址:<__main__.stu object at>

print(s1.get__grade()) #1

s1.set__grade(5) #error

s1.delete__grade()

#实例二,使用property的函数模式

class Stu(object):

def __init__(self):

self.__college = 'pku'

self.__adr = 'beijing'

self.__grade = 3

def get__grade(self):

return self.__grade

def set__grade(self,value):

if value >1 and value <5:

self.get__grade = value

else :

print('error')

def delete__grade(self):

del self.__grade

__grade = property(get__grade,set__grade,delete__grade) #__grade必须是一个被操作的属性,同上

pass

s = Stu()

print(s.get__grade)

print(s.set__grade(7))

print(s.set__grade(4))

#print(s.get__grade):3

#print(s.set__grade(7)):error

#None #需要自己查阅解释

#None #需要自己查阅解释

#实例三,使用@property(装饰器模式)

class Stu():

def __init__(self):

self.__college = 'pku'

self.__adr = 'beijing'

self.__grade = 3

@property

def grade(self):

return self.__grade

@grade.setter

def grade(self,value):

if value >5 or value<0 :

return self.__grade

else:

self.__grade = value

'''将value赋值给self.__grade尤为重要(在出现else所写的情况时,将value赋值给self.__grade)。否则,赋值操作并不能成功显示在结果中(显示的self.__grade仍然是初始化方法中的self.__grade)'''

@grade.deleter

def grade(self):

del self.__grade

s = Stu()

s.grade = 4

print(s.grade)

s.grade = 7

print(s.grade)

#4

#4

5.12.3、调用机制:

属性访问的默认行为是从一个对象的字典中获取、设置或删除属性。例如,a.x 的查找顺序会从 a.__dict__['x'] 开始,然后是 type(a).__dict__['x'],接下来依次查找 type(a) 的基类,不包括元类。 如果找到的值是定义了某个描述器方法的对象,则 Python 可能会重载默认行为并转而发起调用描述器方法。这具体发生在优先级链的哪个环节则要根据所定义的描述器方法及其被调用的方式来决定。

描述器是一个强大而通用的协议。 它们是特征属性、方法静态方法、类方法和 super() 背后的实现机制。 它们在 Python 内部被广泛使用来实现自 2.2 版中引入的新式类。 描述器简化了底层的 C 代码并为 Python 的日常程序提供了一组灵活的新工具。

5.12.6、新式类和经典类

5.12.7、None

5.12.8、类查找机制

5.13、索引、切片、遍历

5.14、元类

六、迭代器与生成器

6.1、迭代和推导

for循环可以用于Python中的任何序列类型,包括列表、元组以及字符串。

实际上,它可以用于任何可迭代对象。

可迭代对象(iterable),本质而言,是序列观念的一种通用化,如果对象是序列或是可以在迭代工具中(例如,for循环)一次产生一个结果的对象,那么久可以看做是可迭代的。总之,可迭代对象包括实际序列,以及能够按照需求计算的虚拟序列。

# 实例

for i in [1,2,3,4]:

print(i,end = ' ')

for x in 'generator':

print(i,end = ' ')

6.2、迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()。

迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。可以迭代不是序列但表现出序列行为的对象,例如字典的键,一个文件的行,等等。

根本上说,迭代器就是有一个next()方法的对象,而不是通过索引来计数。当你或是一个循环机制(例如for语句)需要下一个项时,调用迭代器的next(i)方法就可以获得它。条目全部取出后,会引发一个StopIterationy异常,这并不表示错误发生,只是告诉外部调用者,迭代完成。 迭代器也有一些限制。例如你不能向后移动,不能回到开始,也不能复制一个迭代器。如果你要再次(或者是)同时迭代同个对象,你只能创建另一个迭代器对象。 python中,任意对象,只要定义了next方法,它就是一个迭代器。因此,python中的容器如列表、元组、字典、集合、字符串都可以被称作迭代器。

6.3、完整的迭代协议

下面这个图完整勾勒出了迭代协议的轮廓。该协议被Python中所有的迭代工具使用,并被广泛地为许多对象所支持。该协议分别基于用在不同的两个步骤中的两种对象:

​ ----可迭代对象:迭代的被调对象,其 __iter__ 方法被iter函数所调用;

​ ----迭代器对象:可迭代对象的返回结果,在迭代过程中世纪提供值得对象。它的 __next__方法被next运行,并在结束时触发 StopIteration异常 。

Python迭代协议广泛用于for循环、推导语法、映射等,得到文件、列表、字典和生成器的支持。其中一些既是迭代上下文的对象,也是可迭代对象,例如生成器表达式、map和zip等。另一些对象既是可迭代对象,也是迭代器对象,它们会在iter( )调用中返回他们自己。

注:iter()方法

iter ( object , [ , sentinel] ) #返回一个迭代器对象

'''object ---- 必须是支持迭代的集合对象;sentinel ---- 如果传递了第二个参数,则参数object必须是一个可调用对象(如函数)。此时,iter创建了一个迭代器对象,每次调用这个迭代器的 __next()__ 方法时,都会调用object。如何判定一个对象可否迭代?from collections import Iterableisinstance(object,Iterable)定义一个可迭代对象?需要在类class里面实现 def __iter__(self): 方法 ,该方法的返回值是一个可迭代的对象。'''

迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()。

字符串,列表或元组对象都可用于创建迭代器。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值