万字干货,Python语法大合集,一篇文章带你入门(二)收藏必备!

目录:

控制流和迭代

判断语句

Python当中的判断语句非常简单,并且Python不支持switch,所以即使是多个条件,我们也只能罗列if-else

# Let's just make a variable
some_var = 5

# Here is an if statement. Indentation is significant in Python!
# Convention is to use four spaces, not tabs.
# This prints "some_var is smaller than 10"
if some_var > 10:
    print("some_var is totally bigger than 10.")
elif some_var < 10:    # This elif clause is optional.
    print("some_var is smaller than 10.")
else:                  # This is optional too.
    print("some_var is indeed 10.")
复制代码

循环

我们可以用in来循环迭代一个list当中的内容,这也是Python当中基本的循环方式。


"""
For loops iterate over lists
prints:
    dog is a mammal
    cat is a mammal
    mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
    # You can use format() to interpolate formatted strings
    print("{} is a mammal".format(animal))
复制代码

如果我们要循环一个范围,可以使用range。range加上一个参数表示从0开始的序列,比如range(10),表示[0, 10)区间内的所有整数:

"""
"range(number)" returns an iterable of numbers
from zero to the given number
prints:
    0
    1
    2
    3
"""
for i in range(4):
    print(i)
复制代码

如果我们传入两个参数,则代表迭代区间的首尾

"""
"range(lower, upper)" returns an iterable of numbers
from the lower number to the upper number
prints:
    4
    5
    6
    7
"""
for i in range(4, 8):
    print(i)
复制代码

如果我们传入第三个元素,表示每次循环变量自增的步长

"""
"range(lower, upper, step)" returns an iterable of numbers
from the lower number to the upper number, while incrementing
by step. If step is not indicated, the default value is 1.
prints:
    4
    6
"""
for i in range(4, 8, 2):
    print(i)
复制代码

如果使用enumerate函数,可以同时迭代一个list的下标和元素

"""
To loop over a list, and retrieve both the index and the value of each item in the list
prints:
    0 dog
    1 cat
    2 mouse
"""
animals = ["dog", "cat", "mouse"]
for i, value in enumerate(animals):
    print(i, value)
复制代码

while循环和C++类似,当条件为True时执行,为false时退出。并且判断条件不需要加上括号:

"""
While loops go until a condition is no longer met.
prints:
    0
    1
    2
    3
"""
x = 0
while x < 4:
    print(x)
    x += 1  # Shorthand for x = x + 1
复制代码

捕获异常

(免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流)

Python当中使用try和except捕获异常,我们可以在except后面限制异常的类型。如果有多个类型可以写多个except,还可以使用else语句表示其他所有的类型。finally语句内的语法无论是否会触发异常都必定执行

# Handle exceptions with a try/except block
try:
    # Use "raise" to raise an error
    raise IndexError("This is an index error")
except IndexError as e:
    pass                 # Pass is just a no-op. Usually you would do recovery here.
except (TypeError, NameError):
    pass                 # Multiple exceptions can be handled together, if required.
else:                    # Optional clause to the try/except block. Must follow all except blocks
    print("All good!")   # Runs only if the code in try raises no exceptions
finally:                 #  Execute under all circumstances
    print("We can clean up resources here")
复制代码

with操作

在Python当中我们经常会使用资源,最常见的就是open打开一个文件。我们打开了文件句柄就一定要关闭,但是如果我们手动来编码,经常会忘记执行close操作。并且如果文件异常,还会触发异常。这个时候我们可以使用with语句来代替这部分处理,使用with会自动在with块执行结束或者是触发异常时关闭打开的资源

以下是with的几种用法和功能:

# Instead of try/finally to cleanup resources you can use a with statement
# 代替使用try/finally语句来关闭资源
with open("myfile.txt") as f:
    for line in f:
        print(line)

# Writing to a file
# 使用with写入文件
contents = {"aa": 12, "bb": 21}
with open("myfile1.txt", "w+") as file:
    file.write(str(contents))        # writes a string to a file

with open("myfile2.txt", "w+") as file:
    file.write(json.dumps(contents)) # writes an object to a file

# Reading from a file
# 使用with读取文件
with open('myfile1.txt', "r+") as file:
    contents = file.read()           # reads a string from a file
print(contents)
# print: {"aa": 12, "bb": 21}

with open('myfile2.txt', "r+") as file:
    contents = json.load(file)       # reads a json object from a file
print(contents)     
# print: {"aa": 12, "bb": 21}
复制代码

可迭代对象

凡是可以使用in语句来迭代的对象都叫做可迭代对象,它和迭代器不是一个含义。

当我们调用dict当中的keys方法的时候,返回的结果就是一个可迭代对象。

# Python offers a fundamental abstraction called the Iterable.
# An iterable is an object that can be treated as a sequence.
# The object returned by the range function, is an iterable.

filled_dict = {"one": 1, "two": 2, "three": 3}
our_iterable = filled_dict.keys()
print(our_iterable)  # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface.

# We can loop over it.
for i in our_iterable:
    print(i)  # Prints one, two, three
复制代码

我们不能使用下标来访问可迭代对象,但我们可以用iter将它转化成迭代器,使用next关键字来获取下一个元素。也可以将它转化成list类型,变成一个list。

# However we cannot address elements by index.
our_iterable[1]  # Raises a TypeError

# An iterable is an object that knows how to create an iterator.
our_iterator = iter(our_iterable)

# Our iterator is an object that can remember the state as we traverse through it.
# We get the next object with "next()".
next(our_iterator)  # => "one"

# It maintains state as we iterate.
next(our_iterator)  # => "two"
next(our_iterator)  # => "three"

# After the iterator has returned all of its data, it raises a StopIteration exception
next(our_iterator)  # Raises StopIteration

# We can also loop over it, in fact, "for" does this implicitly!
our_iterator = iter(our_iterable)
for i in our_iterator:
    print(i)  # Prints one, two, three

# You can grab all the elements of an iterable or iterator by calling list() on it.
list(our_iterable)  # => Returns ["one", "two", "three"]
list(our_iterator)  # => Returns [] because state is saved
复制代码

函数

使用def关键字来定义函数,我们在传参的时候如果指定函数内的参数名,可以不按照函数定义的顺序传参:

# Use "def" to create new functions
def add(x, y):
    print("x is {} and y is {}".format(x, y))
    return x + y  # Return values with a return statement

# Calling functions with parameters
add(5, 6)  # => prints out "x is 5 and y is 6" and returns 11

# Another way to call functions is with keyword arguments
add(y=6, x=5)  # Keyword arguments can arrive in any order.
复制代码

可以在参数名之前加上*表示任意长度的参数,参数会被转化成list:

# You can define functions that take a variable number of
# positional arguments
def varargs(*args):
    return args

varargs(1, 2, 3)  # => (1, 2, 3)
复制代码

也可以指定任意长度的关键字参数,在参数前加上**表示接受一个dict:

# You can define functions that take a variable number of
# keyword arguments, as well
def keyword_args(**kwargs):
    return kwargs

# Let's call it to see what happens
keyword_args(big="foot", loch="ness")  # => {"big": "foot", "loch": "ness"}
复制代码

当然我们也可以两个都用上,这样可以接受任何参数:

# You can do both at once, if you like
def all_the_args(*args, **kwargs):
    print(args)
    print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) prints:
    (1, 2)
    {"a": 3, "b": 4}
"""
复制代码

传入参数的时候我们也可以使用*和**来解压list或者是dict:

# When calling functions, you can do the opposite of args/kwargs!
# Use * to expand tuples and use ** to expand kwargs.
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
all_the_args(*args)            # equivalent to all_the_args(1, 2, 3, 4)
all_the_args(**kwargs)         # equivalent to all_the_args(a=3, b=4)
all_the_args(*args, **kwargs)  # equivalent to all_the_args(1, 2, 3, 4, a=3, b=4)
复制代码

Python中的参数可以返回多个值

# Returning multiple values (with tuple assignments)
def swap(x, y):
    return y, x  # Return multiple values as a tuple without the parenthesis.
                 # (Note: parenthesis have been excluded but can be included)

x = 1
y = 2
x, y = swap(x, y)     # => x = 2, y = 1
# (x, y) = swap(x,y)  # Again parenthesis have been excluded but can be included.
复制代码

函数内部定义的变量即使和全局变量重名,也不会覆盖全局变量的值。想要在函数内部使用全局变量,需要加上global关键字,表示这是一个全局变量:

# Function Scope
x = 5

def set_x(num):
    # Local var x not the same as global variable x
    x = num    # => 43
    print(x)   # => 43

def set_global_x(num):
    global x
    print(x)   # => 5
    x = num    # global var x is now set to 6
    print(x)   # => 6

set_x(43)
set_global_x(6)
复制代码

Python支持函数式编程,我们可以在一个函数内部返回一个函数:

# Python has first class functions
def create_adder(x):
    def adder(y):
        return x + y
    return adder

add_10 = create_adder(10)
add_10(3)   # => 13
复制代码

Python中可以使用lambda表示匿名函数,使用:作为分隔,:前面表示匿名函数的参数,:后面的是函数的返回值:

# There are also anonymous functions
(lambda x: x > 2)(3)                  # => True
(lambda x, y: x ** 2 + y ** 2)(2, 1)  # => 5
复制代码

我们还可以将函数作为参数使用map和filter,实现元素的批量处理和过滤。

# There are built-in higher order functions
list(map(add_10, [1, 2, 3]))          # => [11, 12, 13]
list(map(max, [1, 2, 3], [4, 2, 1]))  # => [4, 2, 3]

list(filter(lambda x: x > 5, [3, 4, 5, 6, 7]))  # => [6, 7]
复制代码

我们还可以结合循环和判断语来给list或者是dict进行初始化:

# We can use list comprehensions for nice maps and filters
# List comprehension stores the output as a list which can itself be a nested list
[add_10(i) for i in [1, 2, 3]]         # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5]  # => [6, 7]

# You can construct set and dict comprehensions as well.
{x for x in 'abcddeef' if x not in 'abc'}  # => {'d', 'e', 'f'}
{x: x**2 for x in range(5)}  # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
复制代码

模块

使用import语句引入一个Python模块,我们可以用.来访问模块中的函数或者是类。

# You can import modules
import math
print(math.sqrt(16))  # => 4.0
复制代码

我们也可以使用from import的语句,单独引入模块内的函数或者是类,而不再需要写出完整路径。使用from import *可以引入模块内所有内容(不推荐这么干)

# You can get specific functions from a module
from math import ceil, floor
print(ceil(3.7))   # => 4.0
print(floor(3.7))  # => 3.0

# You can import all functions from a module.
# Warning: this is not recommended
from math import *
复制代码

可以使用as给模块内的方法或者类起别名:

# You can shorten module names
import math as m
math.sqrt(16) == m.sqrt(16)  # => True
复制代码

我们可以使用dir查看我们用的模块的路径:

# You can find out which functions and attributes
# are defined in a module.
import math
dir(math)
复制代码

这么做的原因是如果我们当前的路径下也有一个叫做math的Python文件,那么会覆盖系统自带的math的模块。这是尤其需要注意的,不小心会导致很多奇怪的bug。

我们来看一个完整的类,相关的介绍都在注释当中(免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流)​​​​​​​

# We use the "class" statement to create a class
class Human:

    # A class attribute. It is shared by all instances of this class
    # 类属性,可以直接通过Human.species调用,而不需要通过实例
    species = "H. sapiens"

    # Basic initializer, this is called when this class is instantiated.
    # Note that the double leading and trailing underscores denote objects
    # or attributes that are used by Python but that live in user-controlled
    # namespaces. Methods(or objects or attributes) like: __init__, __str__,
    # __repr__ etc. are called special methods (or sometimes called dunder methods)
    # You should not invent such names on your own.
    # 最基础的构造函数
    # 加了下划线的函数和变量表示不应该被用户使用,其中双下划线的函数或者是变量将不会被子类覆盖
    # 前后都有双下划线的函数和属性是类当中的特殊属性
    def __init__(self, name):
        # Assign the argument to the instance's name attribute
        self.name = name

        # Initialize property
        self._age = 0

    # An instance method. All methods take "self" as the first argument
    # 类中的函数,所有实例可以调用,第一个参数必须是self
    # self表示实例的引用
    def say(self, msg):
        print("{name}: {message}".format(name=self.name, message=msg))

    # Another instance method
    def sing(self):
        return 'yo... yo... microphone check... one two... one two...'

    # A class method is shared among all instances
    # They are called with the calling class as the first argument
    @classmethod
    # 加上了注解,表示是类函数
    # 通过Human.get_species来调用,所有实例共享
    def get_species(cls):
        return cls.species

    # A static method is called without a class or instance reference
    @staticmethod
    # 静态函数,通过类名或者是实例都可以调用
    def grunt():
        return "*grunt*"

    # A property is just like a getter.
    # It turns the method age() into an read-only attribute of the same name.
    # There's no need to write trivial getters and setters in Python, though.
    @property
    # property注解,类似于get,set方法
    # 效率很低,除非必要,不要使用
    def age(self):
        return self._age

    # This allows the property to be set
    @age.setter
    def age(self, age):
        self._age = age

    # This allows the property to be deleted
    @age.deleter
    def age(self):
        del self._age
复制代码

 

下面我们来看看Python当中类的使用:

# When a Python interpreter reads a source file it executes all its code.
# This __name__ check makes sure this code block is only executed when this
# module is the main program.
# 这个是main函数也是整个程序入口的惯用写法
if __name__ == '__main__':
    # Instantiate a class
    # 实例化一个类,获取类的对象
    i = Human(name="Ian")
    # 执行say方法
    i.say("hi")                     # "Ian: hi"
    j = Human("Joel")
    j.say("hello")                  # "Joel: hello"
    # i和j都是Human的实例,都称作是Human类的对象
    # i and j are instances of type Human, or in other words: they are Human objects

    # Call our class method
    # 类属性被所有实例共享,一旦修改全部生效
    i.say(i.get_species())          # "Ian: H. sapiens"
    # Change the shared attribute
    Human.species = "H. neanderthalensis"
    i.say(i.get_species())          # => "Ian: H. neanderthalensis"
    j.say(j.get_species())          # => "Joel: H. neanderthalensis"

    # 通过类名调用静态方法
    # Call the static method
    print(Human.grunt())            # => "*grunt*"

    # Cannot call static method with instance of object 
    # because i.grunt() will automatically put "self" (the object i) as an argument
    # 不能通过对象调用静态方法,因为对象会传入self实例,会导致不匹配
    print(i.grunt())                # => TypeError: grunt() takes 0 positional arguments but 1 was given

    # Update the property for this instance
    # 实例级别的属性是独立的,各个对象各自拥有,修改不会影响其他对象内的值
    i.age = 42
    # Get the property
    i.say(i.age)                    # => "Ian: 42"
    j.say(j.age)                    # => "Joel: 0"
    # Delete the property
    del i.age
    # i.age                         # => this would raise an AttributeError
复制代码

这里解释一下,实例和对象可以理解成一个概念,实例的英文是instance,对象的英文是object。都是指类经过实例化之后得到的对象。

继承

继承可以让子类继承父类的变量以及方法,并且我们还可以在子类当中指定一些属于自己的特性,并且还可以重写父类的一些方法。一般我们会将不同的类放在不同的文件当中,使用import引入,一样可以实现继承。

from human import Human

# Specify the parent class(es) as parameters to the class definition
class Superhero(Human):

    # If the child class should inherit all of the parent's definitions without
    # any modifications, you can just use the "pass" keyword (and nothing else)
    # but in this case it is commented out to allow for a unique child class:
    # pass
    # 如果要完全继承父类的所有的实现,我们可以使用关键字pass,表示跳过。这样不会修改父类当中的实现

    # Child classes can override their parents' attributes
    species = 'Superhuman'

    # Children automatically inherit their parent class's constructor including
    # its arguments, but can also define additional arguments or definitions
    # and override its methods such as the class constructor.
    # This constructor inherits the "name" argument from the "Human" class and
    # adds the "superpower" and "movie" arguments:
    # 子类会完全继承父类的构造方法,我们也可以进行改造,比如额外增加一些参数
    def __init__(self, name, movie=False,
                 superpowers=["super strength", "bulletproofing"]):

        # add additional class attributes:
        # 额外新增的参数
        self.fictional = True
        self.movie = movie
        # be aware of mutable default values, since defaults are shared
        self.superpowers = superpowers

        # The "super" function lets you access the parent class's methods
        # that are overridden by the child, in this case, the __init__ method.
        # This calls the parent class constructor:
        # 子类可以通过super关键字调用父类的方法
        super().__init__(name)

    # override the sing method
    # 重写父类的sing方法
    def sing(self):
        return 'Dun, dun, DUN!'

    # add an additional instance method
    # 新增方法,只属于子类
    def boast(self):
        for power in self.superpowers:
            print("I wield the power of {pow}!".format(pow=power))
复制代码
if __name__ == '__main__':
    sup = Superhero(name="Tick")

    # Instance type checks
    # 检查继承关系
    if isinstance(sup, Human):
        print('I am human')
    # 检查类型
    if type(sup) is Superhero:
        print('I am a superhero')

    # Get the Method Resolution search Order used by both getattr() and super()
    # This attribute is dynamic and can be updated
    # 查看方法查询的顺序
    # 先是自身,然后沿着继承顺序往上,最后到object
    print(Superhero.__mro__)    # => (<class '__main__.Superhero'>,
                                # => <class 'human.Human'>, <class 'object'>)

    # 相同的属性子类覆盖了父类
    # Calls parent method but uses its own class attribute
    print(sup.get_species())    # => Superhuman

    # Calls overridden method
    # 相同的方法也覆盖了父类
    print(sup.sing())           # => Dun, dun, DUN!

    # Calls method from Human
    # 继承了父类的方法
    sup.say('Spoon')            # => Tick: Spoon

    # Call method that exists only in Superhero
    # 子类特有的方法
    sup.boast()                 # => I wield the power of super strength!
                                # => I wield the power of bulletproofing!

    # Inherited class attribute
    sup.age = 31
    print(sup.age)              # => 31

    # Attribute that only exists within Superhero
    print('Am I Oscar eligible? ' + str(sup.movie))
复制代码

多继承

我们创建一个蝙蝠类:


# Another class definition
# bat.py
class Bat:

    species = 'Baty'

    def __init__(self, can_fly=True):
        self.fly = can_fly

    # This class also has a say method
    def say(self, msg):
        msg = '... ... ...'
        return msg

    # And its own method as well
    # 蝙蝠独有的声呐方法
    def sonar(self):
        return '))) ... ((('

if __name__ == '__main__':
    b = Bat()
    print(b.say('hello'))
    print(b.fly)
复制代码

我们再创建一个蝙蝠侠的类,同时继承Superhero和Bat:

# And yet another class definition that inherits from Superhero and Bat
# superhero.py
from superhero import Superhero
from bat import Bat

# Define Batman as a child that inherits from both Superhero and Bat
class Batman(Superhero, Bat):

    def __init__(self, *args, **kwargs):
        # Typically to inherit attributes you have to call super:
        # super(Batman, self).__init__(*args, **kwargs)      
        # However we are dealing with multiple inheritance here, and super()
        # only works with the next base class in the MRO list.
        # So instead we explicitly call __init__ for all ancestors.
        # The use of *args and **kwargs allows for a clean way to pass arguments,
        # with each parent "peeling a layer of the onion".
        # 通过类名调用两个父类各自的构造方法
        Superhero.__init__(self, 'anonymous', movie=True, 
                           superpowers=['Wealthy'], *args, **kwargs)
        Bat.__init__(self, *args, can_fly=False, **kwargs)
        # override the value for the name attribute
        self.name = 'Sad Affleck'

    # 重写父类的sing方法
    def sing(self):
        return 'nan nan nan nan nan batman!'
复制代码

执行这个类:

if __name__ == '__main__':
    sup = Batman()

    # Get the Method Resolution search Order used by both getattr() and super().
    # This attribute is dynamic and can be updated
    # 可以看到方法查询的顺序是先沿着superhero这条线到human,然后才是bat
    print(Batman.__mro__)       # => (<class '__main__.Batman'>, 
                                # => <class 'superhero.Superhero'>, 
                                # => <class 'human.Human'>, 
                                # => <class 'bat.Bat'>, <class 'object'>)

    # Calls parent method but uses its own class attribute
    # 只有superhero有get_species方法
    print(sup.get_species())    # => Superhuman

    # Calls overridden method
    print(sup.sing())           # => nan nan nan nan nan batman!

    # Calls method from Human, because inheritance order matters
    sup.say('I agree')          # => Sad Affleck: I agree

    # Call method that exists only in 2nd ancestor
    # 调用蝙蝠类的声呐方法
    print(sup.sonar())          # => ))) ... (((

    # Inherited class attribute
    sup.age = 100
    print(sup.age)              # => 100

    # Inherited attribute from 2nd ancestor whose default value was overridden.
    print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
复制代码

进阶

生成器

我们可以通过yield关键字创建一个生成器,每次我们调用的时候执行到yield关键字处则停止。下次再次调用则还是从yield处开始往下执行:

# Generators help you make lazy code.
def double_numbers(iterable):
    for i in iterable:
        yield i + i

# Generators are memory-efficient because they only load the data needed to
# process the next value in the iterable. This allows them to perform
# operations on otherwise prohibitively large value ranges.
# NOTE: `range` replaces `xrange` in Python 3.
for i in double_numbers(range(1, 900000000)):  # `range` is a generator.
    print(i)
    if i >= 30:
        break
复制代码

除了yield之外,我们还可以使用()小括号来生成一个生成器:

# Just as you can create a list comprehension, you can create generator
# comprehensions as well.
values = (-x for x in [1,2,3,4,5])
for x in values:
    print(x)  # prints -1 -2 -3 -4 -5 to console/terminal

# You can also cast a generator comprehension directly to a list.
values = (-x for x in [1,2,3,4,5])
gen_to_list = list(values)
print(gen_to_list)  # => [-1, -2, -3, -4, -5]
复制代码

 

装饰器

我们引入functools当中的wraps之后,可以创建一个装饰器。装饰器可以在不修改函数内部代码的前提下,在外面包装一层其他的逻辑:

# Decorators
# In this example `beg` wraps `say`. If say_please is True then it
# will change the returned message.
from functools import wraps

def beg(target_function):
    @wraps(target_function)
    # 如果please为True,额外输出一句Please! I am poor :(
    def wrapper(*args, **kwargs):
        msg, say_please = target_function(*args, **kwargs)
        if say_please:
            return "{} {}".format(msg, "Please! I am poor :(")
        return msg

    return wrapper

@beg
def say(say_please=False):
    msg = "Can you buy me a beer?"
    return msg, say_please

print(say())                 # Can you buy me a beer?
print(say(say_please=True))  # Can you buy me a beer? Please! I am poor :(
复制代码

 

结尾

不知道有多少小伙伴可以看到结束,如果都能读懂并且理解的话,那么Python这门语言就算是入门了。

如果你之前就有其他语言的语言基础,我想本文读完应该不用30分钟。当然在30分钟内学会一门语言是不可能的,也不是我所提倡的。但至少通过本文我们可以做到熟悉Python的语法,知道大概有哪些操作,剩下的就要我们亲自去写代码的时候去体会和运用了。

根据我的经验,在学习一门新语言的前期,不停地查阅资料是免不了的。希望本文可以作为你在使用Python时候的查阅文档。

今天的文章就到这里,原创不易,需要你的一个关注,请顺手点个赞,关注我,每天几篇小文章,进步 的 不只是一丢丢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值