• python函数总结


    函数

    函数的定义

    封闭一个功能

    • 节省代码,减少重复率
    • 提高代码可读性

    函数的结构

    def func():
        pass
    

    函数的返回值retrun

    1,结束函数

    2,给函数的调用者(执行者)返回值

    只有return -->None

    return 单个值:返回单个值,不改变数据类型

    return 多个值:以元组的形式返回

    没有return:默认返回None

    函数的参数

    形参

    位置参数:按顺序一一对应

    默认参数:传值即覆盖

    动态参数:*args, **kwargs万能参数

    当函数定义的时候(*,**的作用):
    *, **代表聚合,*将实参对应的所有位置参数聚合到一个元组,赋值给
    args,**将实参对应的所有的关键字参数聚合到一个字典中,赋值给kwargs
    

    当函数调用的时候(*,**的作用):

    *,**代表打散。*是将所有的iterable元素打散成实参的位置参数。
    **是将字典的所有键值对打散成关键字参数。
    

    形参的顺序:位置参数,*args, 默认参数, **kwargs

    实参

    位置参数:按顺序一一对应

    关键字参数:name='python'一一对应

    混合参数:关键字参数一定要放在位置参数后面

    内存,空间

    全局作用域

    全局名称空间存储当前py文件:变量与值的对应关系

    内置名称空间builtins,模块

    局部作用域

    局部名称空间

    当函数执行时,内存临时开辟一个空间存储函数内部变量与值的关系,随着函数的结束而消失。
    

    加载顺序:

    内置名称空间-->程序运行时 全局名称空间-->函数调用时 局部名称空间

    取值顺序:就近原则LEGB

    L-Local(function);函数内的名字空间
    E-Enclosing function locals;外部嵌套函数的名字空间(例如closure)
    G-Global(module);函数定义所在模块(文件)的名字空间
    B-Builtin(Python);Python内置模块的名字空间
    

    global nonlocal

    global

    1,在函数内部,对全局作用域的变量进行修改

    2,在函数内部,声明一个全局变量

    nonlocal 下级函数对上级函数非全局变量进行修改

    函数名的应用

    1,函数名即函数地址

    2,函数名可以作为变量

    3,函数名可以作为函数的参数

    4,函数名可以作为函数的返回值

    5,函数名可以作为容器类类型的元素

    闭包

    内层函数对外层函数非全局变量的引用,并将内层函数函数名返回

    机制:python解释器遇到闭包,那么这个空间不会随着函数的结束而释放

    闭包的应用场景

    装饰器

    爬虫

    迭代器

    1,可迭代对象:内部含有__iter__方法

    2,迭代器:内部含有__iter__方法和__next__

    3,可迭代对象-->迭代器iter(可迭代对象)

    4,迭代器取值__next__()next()或for循环

    close()

    生成器

    通过python代码写的迭代器,本质就是迭代器

    生成器的形成方式:

    1,生成器函数人(含有yield)

    send与next区别

    以后加

    2,生成器推导式

    循环模式(变量(加工后的变量)for i in iterable)
    筛选模式 (变量(加工后的变量)for i in iterable if 条件)

    内置函数

    查看python的内置函数

    >>> dir(__builtins__)
    ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
    

    面向对象相关(9)

    定义特殊方法的装饰器(3)

    classmethod
    stacticmethod
    property
    property是一个装饰器函数
    所有的装饰器函数都怎么用? 在函数、方法、类的上面一行直接@装饰器的名字
    装饰器的分类:
        装饰函数
        装饰方法 : property
        装饰类
    
    class Student:
        def __init__(self,name,age):
            self.__name = name
            self.age = age
        @property   # 将一个方法伪装成一个属性
        def name(self):
            return self.__name
    zhuge = Student('诸葛',20)
    print(zhuge.name)
    
    from math import pi
    class Circle:
        def __init__(self,r):
            self.r = r
        @property
        def area(self):
            return self.r ** 2 * pi
        @property
        def perimeter(self):
            return 2 * self.r * pi
    
    c1 = Circle(10)
    print(c1.area)
    print(c1.perimeter)
    c1.r = 5
    print(c1.area)
    print(c1.perimeter)
    

    判断对象/类与类间的关系(2)

    isinstance
    issubclass

    所有类的基类 object

    继承相关 super

    封装相关 vars

    数据类型相关 type

    作用域相关 ★★★★★

    locals() 函数会以字典的类型返回当前位置的全部局部变量。若在最外面,与globals()相同。

    globals() 函数以字典的类型返回全部全局变量。

    a = 1
    b = 2
    def f1():
        c = 1
        print('inner locals>>>>', locals())
    f1()
    print('globals>>>>', globals())
    print('outer locals>>>>', locals())
    
    print(globals() == locals())  ## 若在最外面,与globals()相同。结果为True
    '''
    inner locals>>>> {'c': 1}
    globals>>>> {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000262523AC1D0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:\oldboy_project\test3.py', '__cached__': None, 'a': 1, 'b': 2, 'f1': <function f1 at 0x00000262522A2E18>}
    outer 
    locals >>>> {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000262523AC1D0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:\oldboy_project\test3.py', '__cached__': None, 'a': 1, 'b': 2, 'f1': <function f1 at 0x00000262522A2E18>}
    True
    '''
    

    其他相关

    字符串类型代码的执行 eval,exec,complie,不建议使用★★★☆☆

    ## print(eval('x')) ## not defined
    x = 1
    print(eval('x + 3')) ## 4
    print(exec('x + 3')) ## None
    

    输入输出相关 input,print ★★★★★

      input:函数接受一个标准输入数据,返回为 string 类型。参数默认为None,若给了字符串,会出现提示内容。

      print:打印输出。

    print(*args, sep=' ', end='
    ', file=sys.stdout, flush=False)
    sep 是args每个参数显示的间隔。
    end 是最后以什么结束。
    file 接收文件句柄,可以赋值给一个文本文件。
    flush 立即把内容输出到流文件,不作缓存
    
    with open('print.txt', mode='w', encoding='utf-8') as f:
        print('hello world!I am learning python.', file=f)
    ## 命令行中没有显示结果,而新建了一个“print.txt"文件,里面有所写的内容。
    
    print(1, 2, 3, sep='|') ## 1|2|3
    

    内存相关 hash id ★★★☆☆

    • hash:获取一个对象(可哈希对象:int,str,Bool,tuple)的哈希值。
      hash一般会得到一个长度为18的数字,
      若是数值长度超过18会得到一个长度18的数字。
      长度小于18会是它原来的数值。
    >>> a = 100
    >>> b = '100'
    >>> c = True
    >>> tu = (1, 2)
    >>> hash(a)    #数字还是它所显示的值。
    100
    >>> hash(b)
    5677959494014640638
    >>> hash(c)
    1
    >>> hash(tu)
    3713081631934410656
    
    • id: 获取该对象的内存地址。

    文件操作相关

    open() ★★★★★

    函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。

    模块相关__import__  ★★★☆☆

     __import__:函数用于动态加载类和函数 。

    帮助 help:函数用于查看函数或模块用途的详细说明。 ★★☆☆☆

    name = 'alex'
    print(help(str))
    

      

    调用相关 callable ★★★☆☆

      函数用于检查一个对象是否是可调用的。如果返回True,object仍然可能调用失败;但如果返回False,调用对象ojbect绝对不会成功。

    >>> def f1():
    ...     print('a')
    ...
    >>> callable(f1)
    True
    >>> name = 'python'
    >>> callable(name)
    False
    

    查看内置属性 dir ★★★☆☆

      函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。
    如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。

    >>> s = 'abc'
    >>> dir(s)
    ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
    

    迭代生成器相关

    range:函数可创建一个整数对象,一般用在 for 循环中。

     python2x: range(3) ---> [0,1,2] 列表
               xrange(3) ---> 一个生成器
     python3x: range(3) ---> range(0,3) 可迭代对象
    

    next:内部实际使用了__next__方法,返回迭代器的下一个项目。

    ## 首先获得Iterator对象:
    it = iter([1, 2, 3, 4, 5])
    ## 循环:
    while True:
        try:
            ## 获得下一个值:
            x = next(it)
            print(x)
        except StopIteration:
            ## 遇到StopIteration就退出循环
            break
    

    iter:函数用来生成迭代器(即一个可迭代对象,生成迭代器)。

    from collections import Iterable
    from collections import Iterator
    l = [1,2,3]
    print(isinstance(l,Iterable))  ## True
    print(isinstance(l,Iterator))  ## False
    
    l1 = iter(l)
    print(isinstance(l1,Iterable))  ## True
    print(isinstance(l1,Iterator))  ## True
    

    基础数据类型相关

    数字相关

    数据类型(4)
    bool :用于将给定参数转换为布尔类型,如果没有参数,返回 False。
    >>> bool()
    False
    >>> bool(0)==bool('')==bool([])==bool(tuple())==bool(set())==bool({})
    True
    
    int:函数用于将一个字符串或数字转换为整型。
    >>> int('10', base=2)  #二进制转十进制
    2
    >>> int('10', base=8)  #八进制转十进制
    8
    >>> int('1e', base=16) #十六进制转十进制
    30
    >>> int(3.8)   ## 浮点数强制转整形
    3
    >>> int()   ## 默认为0
    0
    
    
    float:函数用于将整数和字符串转换成浮点数。
    >>> float()
    0.0
    >>> float('+1.23')
    1.23
    >>> float('   -12345
    ')
    -12345.0
    >>> float('1e-003')
    0.001
    >>> float('+1E6')
    1000000.0
    >>> float('-Infinity')
    -inf
    
    
    complex:

    函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。

    进制转换(3)
    bin:将十进制转换成二进制并返回。
    >>> bin(3)
    '0b11'
    >>> bin(-10)
    '-0b1010'
    
    oct:将十进制转化成八进制字符串并返回。
    >>> oct(8)
    '0o10'
    >>> oct(-56)
    '-0o70'
    
    hex:将十进制转化成十六进制字符串并返回。
    >>> hex(255)
    '0xff'
    >>> hex(-42)
    '-0x2a'
    
    数学运算(7):
    abs:函数返回数字的绝对值。
    >>> abs(-20)
    20
    >>> abs(-28.33)
    28.33
    
    divmod:计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b),可以用到页码的计算。
    >>> divmod(2.4, 1.1)
    (2.0, 0.19999999999999973)
    >>> divmod(33, 15)
    (2, 3)
    >>>
    
    round:保留浮点数的小数位数,默认保留整数。
    >>> round(0.5)
    0
    >>> round(1.5)
    2
    ##  if two multiples are equally close, rounding is done toward the even choice ## (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2). 
    
    pow:求xy次幂。(三个参数为xy的结果对z取余)
    >>> pow(3, -2, 3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: pow() 2nd argument cannot be negative when 3rd argument specified
    >>> pow(3, 2, 7)
    2
    
    sum:对可迭代对象进行求和计算(可设置初始值)。
    >>> sum([1,2,3,4], 10)
    20
    
    min:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最小值)。 key可以跟lambda函数用。
    >>> min([-1, 3, 4, 9, -10])
    -10
    >>> min([-1, 3, 4, 9, -10], key=abs)
    -1
    
    max:返回可迭代对象的最大值(可加key,key为函数名,通过函数的规则,返回最大值)。key可以跟lambda函数用。
    >>> max([-1, 3, 4, 9, -10])
    9
    >>> max([-1, 3, 4, 9, -10], key=abs)
    -10
    

    和数据结构相关

    列表和元祖(2)
    list:将一个可迭代对象转化成列表(如果是字典,默认将key作为列表的元素)。
    >>> list({'a':1, 'b':3})
    ['a', 'b']
    
    tuple:将一个可迭代对象转化成元祖(如果是字典,默认将key作为元祖的元素)。
    相关内置函数(2)
    reversed:将一个序列翻转,并返回此翻转序列的迭代器。
    >>> reversed([3,1,6,4,9])   ## Return a reverse iterator. 
    <list_reverseiterator object at 0x000001B2B4258E80> 
    >>> list(reversed([3,1,6,4,9]))
    [9, 4, 6, 1, 3]
    
    slice:构造一个切片对象,用于列表的切片。
    >>> li = ['a','b','c','d','e','f','g']
    >>> li[slice(3)]
    ['a', 'b', 'c']
    >>> li[slice(1, 3)]
    ['b', 'c']
    >>> li[slice(1, None, 2)]
    ['b', 'd', 'f']
    >>> li[slice(1, None, 1)]
    ['b', 'c', 'd', 'e', 'f', 'g']
    
    字符串相关(9)
    str:将数据转化成字符串。
    class str(object='')
    class str(object=b'', encoding='utf-8', errors='strict')
    Return a string version of object. If object is not provided, returns the empty string. Otherwise, the behavior of str() depends on whether encoding or errors is given, as follows.
    
    If neither encoding nor errors is given, str(object) returns object.__str__(), which is the “informal” or nicely printable string representation of object. For string objects, this is the string itself. If object does not have a __str__() method, then str() falls back to returning repr(object).
    
    If at least one of encoding or errors is given, object should be a bytes-like object (e.g. bytes or bytearray). In this case, if object is a bytes (or bytearray) object, then str(bytes, encoding, errors) is equivalent to bytes.decode(encoding, errors). Otherwise, the bytes object underlying the buffer object is obtained before calling bytes.decode(). See Binary Sequence Types — bytes, bytearray, memoryview and Buffer Protocol for information on buffer objects.
    
    Passing a bytes object to str() without the encoding or errors arguments falls under the first case of returning the informal string representation (see also the -b command-line option to Python). For example:
    
    >>>
    >>> str(b'Zoot!')
    "b'Zoot!'"
    
    format:与具体数据相关,用于计算各种小数,精算等。★★☆☆☆
    >>> format('text', '<20')
    'text                '
    >>> format('text', '>20')
    '                text'
    >>> format('text', '^20')
    '        text        '
    
    bytes:用于不同编码之间的转化。 ★★★★☆

    unicode ---> bytes 类型

    >>> sz = '深圳'
    >>> sz.encode('utf-8')
    b'xe6xb7xb1xe5x9cxb3'
    
    >>> bytes(sz,encoding='utf-8')
    b'xe6xb7xb1xe5x9cxb3'
    >>> _ == sz.encode('utf-8')
    True
    
    bytearry:返回一个新字节数组。这个数组里的元素是可变的,并且每个元素的值范围: 0 <= x < 256。
    >>> ret  = bytearray('python', encoding='utf-8')
    >>> ret
    bytearray(b'python')
    >>> id(ret)
    1337379950296
    >>> ret[0]
    112
    >>> ret
    bytearray(b'python')
    >>> id(ret)
    1337379950296
    
    memoryview
    >>> ret  = memoryview(bytes('你好', encoding='utf-8'))
    >>> ret
    <memory at 0x00000137620F6048>
    >>> len(ret)
    6
    >>> bytes(ret[:3]).decode('utf-8')
    '你'
    >>> bytes(ret[3:]).decode('utf-8')
    '好'
    
    ord:输入字符找该字符编码 unicode 的位置
    >>> ord('x')
    120
    >>> ord('好')
    22909
    
    chr:输入位置数字找出其对应的字符 unicode
    >>> chr(120)
    'x'
    >>> chr(22909)
    '好'
    
    ascii:是ascii码中的返回该值,不是则返回他在unicode的位置(16进制。)
    >>> ascii('x')
    "'x'"
    >>> ascii('好')
    "'\u597d'"
    >>> ascii(120)
    '120'
    >>> ascii('x好')
    "'x\u597d'"
    
    repr:返回一个对象的string形式(原形毕露)。★★★★
    >>> 'python'
    'python'
    >>> repr('python')
    "'python'"
    >>> '你是个%r人' % '好'    # 格式化输出 %r
    "你是个'好'人"
    
    数据集合(3)
    dict:创建一个字典。
    >>> a = dict(one=1, two=2, three=3)
    >>> b = {'one': 1, 'two': 2, 'three': 3}
    >>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
    >>> d = dict([('two', 2), ('one', 1), ('three', 3)])
    >>> e = dict({'three': 3, 'one': 1, 'two': 2})
    >>> a == b == c == d == e
    True
    
    set:创建一个集合。
    >>> set('abc')
    {'c', 'b', 'a'}
    
    frozenset:返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。
    >>> frozenset('abc')
    frozenset({'c', 'b', 'a'})
    >>> hash(_)
    -76181078804554994
    
    >>> set('abc')
    {'c', 'b', 'a'}
    >>> hash(_)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'set'
    
    相关内置函数(8)
    len:返回一个对象中元素的个数。
    sorted:对所有可迭代的对象进行排序操作。★★★★★
    >>> l1 = [2,3,5,3,1,9,8,6]
    >>> l1.sort() 形成了一个新列表
    >>> l1
    [1, 2, 3, 3, 5, 6, 8, 9]
    >>> l1 = [2,3,5,3,1,9,8,6]
    >>> sorted(l1)
    [1, 2, 3, 3, 5, 6, 8, 9]
    >>> l1
    [2,3,5,3,1,9,8,6] # 原列表不变
    
    sorted(iterable, *, key=None, reverse=False)  # ------>   pass
    
    enumerate:枚举,返回一个枚举对象。 第二参数为开始计数
    >>> enumerate([1,2,3])
    <enumerate object at 0x00000137620ED678>
    >>> for i in _:
    ...     print(i)
    ...
    (0, 1)
    (1, 2)
    (2, 3)
    >>> enumerate([1,2,3])
    <enumerate object at 0x00000137620ED750>
    >>> for index, i in _:
    ...     print(index, i)
    ...
    0 1
    1 2
    2 3
    
    
    all:可迭代对象中,全都是True才是True
    >>> all([0, 2])
    False
    >>> all([1, 2])
    True
    
    any:可迭代对象中,有一个True 就是True
    >>> any([1, 0])
    True
    >>> any(['', 0])
    False
    
    zip:

    函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。

    >>> l1 = [1,2,3,4,5,6,7]
    >>> tu1 = ('a','b', 'c', 'd')
    >>> dic = {'name':'python', 'price':9999}
    >>> zip(l1, tu1, dic)
    <zip object at 0x00000137620F1548>
    >>> list(_)
    [(1, 'a', 'name'), (2, 'b', 'price')]
    
    filter:过滤·。
    >>> l1 = [1, 2, 3, 4, 5, 6, 7, 8]
    >>> filter(lambda x:x % 2, l1)
    <filter object at 0x00000137620F70B8>
    >>> list(_)
    [1, 3, 5, 7]
    
    map:会根据提供的函数对指定序列做映射。
    >>> l1 = [1, 2, 3, 4, 5, 6, 7, 8]
    >>> map(lambda x:x**2, l1)
    <map object at 0x00000137620F7128>
    >>> list(_)
    [1, 4, 9, 16, 25, 36, 49, 64]
    

    匿名函数

    函数名 = lambda 参数 :返回值
    
    #参数可以有多个,用逗号隔开
    #匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
    #返回值和正常的函数一样可以是任意数据类型
    
  • 相关阅读:
    jQuery EasyUI 详解
    The Google Test and Development Environment (持续更新)
    MTSC 2019 深圳站精彩议题第一波更新! | 七五折门票火热售票中
    MTSC2019-深圳站 议题征集
    [ZZ] [精彩盘点] TesterHome 社区 2018年 度精华帖
    MTSC2018 | 确认过眼神,在这里能遇见Google、阿里、百度......
    四岁啦 | 第四届中国移动互联网测试大会期待您的光临
    聊聊优酷上的那些车评
    聊聊Google DSM产品的发布
    尝试 Markdown 写测试用例
  • 原文地址:https://www.cnblogs.com/lanhoo/p/9526482.html
Copyright © 2020-2023  润新知