资讯动态

Python学习第三部分

发布时间:2026/8/23 8:50:48 来源:尧图企业网站定制
一、函数1、介绍函数组织好的、可重复使用的、用来实现单一或相关联功能的代码块能提高代码的模块性和复用性。函数分为内置函数和自定义函数内置函数自定义函数自定义函数就是你自己用def定义的、按需封装的代码块用来执行特定任务并随时调用。2、函数的定义Python函数的定义包括对函数名、函数的参数与函数功能的描述使用def关键字。语法注意无参函数有参函数Python允许函数体为空的函数。语法pass 是空语句是为了保持程序结构的完整性“这里先预留位置回头再补上具体的代码实现”。3、函数的调用语法函数名([实际参数列表])①如果调用的是无参数函数则实参列表省略。②通常将函数定义和函数调用都放在一个程序文件中然后运行程序文件。嵌套调用指在一个函数内部调用另一个函数通过函数间的层层协作来完成复杂任务。4、递归函数1什么是递归递归函数是指一个函数的函数体中又直接或间接地调用该函数本身的函数。递归出口停止递归调用的条件基线条件防止无限循环下去。递归体函数内部调用自身的那部分逻辑负责把大问题分解成更小的同类子问题。2举例子①实例 求n!的递归函数。②实例 求的递归函数。5、函数参数的传递1当参数类型为固定数据类型如整数、浮点数、字符串、元组等时类似 C 的值传递在函数内部直接修改形参的值不会影响实参。2当参数类型为可变数据类型如列表、字典、集合等时类似 C 的引用传递。在函数内部使用下标或其他方式为其增加、删除元素或修改元素值时修改后的结果是可以反映到函数之外的即实参也会得到相应的修改。可变和不可变数据类型不可变数据类型创建后内容不能被修改如整数、浮点数、字符串、元组任何“修改”操作实际上会生成新对象。可变数据类型创建后内容可以被修改如列表、字典、集合修改时对象本身不变只是内部元素变化。6、参数的类型1位置参数调用函数时实参和形参的顺序必须严格一致并且实参和形参的数量必须相同。2关键字参数关键字参数的形式为形参名实参值通过形式参数的名称来指示为哪个形参传递什么值这可以跳过某些参数或脱离参数的顺序。(实参名来自形参的名字)3默认值参数默认值参数的形式为形参名默认值注意1默认值参数必须出现在形参表的最右端。也就是说第一个形参使用默认值参数后它后面的所有形参也必须使用默认值参数否则会出错。2所有的位置参数必须在默认参数前包括函数定义和调用4可变长度参数定义函数时不确定需要传递多少个参数可以使用包裹传递在形参名前面加*用来接受任意多个实参并将其放在一个元组中。元组可变长度形参在形参名前面加**可以接受任意多个关键字实参值 形式的实参。关键字参数和实参值参数被放入一个字典分别作为字典的关键字和字典的值。字典可变长度形参注意可变长度参数永远放在参数的最后面。5参数的解包裹传递调用函数时若函数接收的实参为元组或字典类型可以对函数参数进行解包裹①使用*可以解压传递到函数中的元组、列表、字符串等类型并按位置传递到函数入口参数中。②使用**可以解压待传递到函数的字典并按关键字传递到函数入口参数中。⚠️注意包裹和解包裹并不是相反操作是两个相对独立的过程。示例1元组解包裹示例2字典解包裹输出结果综合示例求三角形面积三边长从键盘输入面积公式其中。7、变量的作用域变量的作用域可以理解为变量的作用范围它决定了在代码的哪些位置可以访问该变量超出其作用域范围则无法被引用。①局部变量在函数中定义的。②全局变量在函数外面、全局范围内定义的。1什么是局部变量在一个函数体内或语句块内定义的变量称为局部变量局部变量仅在定义它的函数体或语句块内部生效离开该范围就无法使用外部代码无权访问。2什么是全局变量定义在函数体外的变量称为全局变量全局变量定义在函数外部在整个程序范围内都可访问。当全局变量与局部变量同名时在函数内部优先访问局部变量局部覆盖全局。3全局变量 - global关键字在函数内部修改一个定义在函数外的变量时须使用global关键字明确声明变量。在函数内部通过global关键字来声明或定义全局变量。4“看不见”的字典变量名key变量值valuePthon提供3个工具函数来获取指定范围内的“变量字典”①globals()全局②locals()局部③vars(Object)获取指定对象范围内所有变量组成的“变量字典”如果不传入Object参数vars()和locals()作用完全相同。⚠️注意vars()只能传入具有__dict__属性的对象如自定义类实例、模块、类本身不能传入内置类型如字典、列表、整数等。5globals()和locals()的区别和联系locals()总是获取当前局部范围内所有变量组成的“变量字典”因此在全局范围内函数之外调用 locals()函数同样会获取全局范围内所有变量组成的“变量字典” 。globals()它无论在哪儿都获取全局范围。 获取的“变量字典”可被修改不影响变量本身。6局部变量屏蔽全局变量的解决方法有以下两个解决办法①通过globals()函数访问被遮蔽的全局变量。②使用global语句来声明全局变量。7nonlocal关键字Python3.x引入了nonlocal关键字只要在内层函数中用nonlocal语句说明变量就可以让解释器在外层函数中修改变量的值。nonlocal和global 功能大致相似区别只是 global 用于声明访问全局变量而 nonlocal 用于声明访问当前函数所在函数内的局部变量。8、函数嵌套定义函数嵌套python允许在函数中定义另外一个函数定义在其他函数内部的函数称为内建函数包含有内建函数的函数称为外部函数。9、函数的返回值return用于返回函数值并结束函数。可有多条但仅执行一条执行后后续语句不再运行。无 return 时隐式返回 None。多返回值本质是元组。使用函数嵌套直接使用内置sum函数结果10、函数作为对象赋值或传参1函数赋值给变量Python的函数也是一种值即所有函数都是function对象所以可以把函数赋值给变量通过该变量来调用函数。2函数作为另一个函数的形参Python的本身也提供了一个map函数。3函数作为另一个函数的返回值4闭包闭包就是能够读取其他函数内部变量的函数。闭包特性①可以外部访问函数内部变量②内部函数可以访问外层函数变量③局部变量可以常驻内存代码分析外部函数fout内部定义了局部变量x和嵌套函数finfin引用了x。当fout执行完毕并返回fin后x并没有被销毁而是被fin携带保留下来。因此result实际是带有记忆的fin函数调用result(5)时能访问到之前保留的x3最终输出8。5装饰器装饰器本质上是一个闭包函数用于在不修改原函数代码的前提下为其增加额外功能。核心要点本质闭包函数接收一个函数作为参数返回一个新的函数对象作用在不改动原函数代码的情况下动态增强或改变其功能语法采用装饰器名的语法糖格式如classmethod、property常见应用场景插入日志、性能测试、事务处理、缓存、权限校验等为什么要使用装饰器在不修改被装饰对象的前提下为其添加新功能。开放封闭原则开放指的是对拓展功能是开放的。允许添加新功能封闭指的是对修改源代码是封闭的。不应改动已有代码工作原理示例代码代码执行顺序①执行funA(funB)输出C语言中文网、python的学习、https://kecheng.com。②funB被赋值值为装饰器的返回值。③执行print(funB)输出装饰器的返回值。11、lambda函数形参和返回值冒号前面是形参列表冒号后面是返回值表达式匿名函数也称为lambda函数用lambda语句创建的函数对象没有名称定义形式lambda [参数1[,参数2,……,参数n]]:表达式lambda函数的定义与调用将lambda语句作为对象赋值给变量通过变量名进行调用说明①lambda定义的是单行函数省去函数定义过程代码简洁。②lambda语句可以包含多个参数。③使用后立即释放提高了性能。④lambda语句中的表达式不能含有命令且仅限一条表达式避免滥用。1匿名函数作为函数返回值2匿名函数作为序列或字典的元素以列表为例一般格式为列表名[匿名函数1,匿名函数2,……,匿名函数n]调用方法以序列或字典元素引用作为函数名来调用匿名函数。调用格式为 列表或字典元素引用(匿名函数实参)总结把匿名函数放进列表或字典里然后用[索引]或[键名]取出来加括号()调用。二、类和对象1、面向对象的程序设计1面向对象与面向过程①面向过程核心思想采用自顶向下的设计方法将程序分解为若干个功能模块每个模块用函数实现按步骤顺序执行。优点极大降低了写程序的复杂度只需按执行步骤堆叠代码即可。缺点一套流程解决一个问题代码牵一发而动全身扩展性差。应用场景需求一旦完成就很少改变的场景如 Linux 内核、git、Apache HTTP Server 等。②面向对象核心思想万物皆为对象编程时尽可能模拟现实世界。任何一个动作的发生都存在一个支配该动作的实体对象功能的实现就是各个对象发挥各自能力并协调调用的过程。优点解决了程序的扩展性对单个对象修改会立刻反映到整个体系中。缺点可控性差无法像面向过程那样精准预测处理流程与结果程序由对象间交互解决问题最终结果难以预判。应用场景需求经常变化的软件主要集中在用户层如互联网应用、企业内部软件、游戏等。2采用面向对象的思想第一步分析哪些动作是由哪些实体发出的。第二步定义这些实体为其增加相应的属性和功能。第三步让实体去执行相应的功能或动作。3面向对象三大特征2、类与对象1什么是类和对象对象现实世界中客观存在的事物称为对象。任何对象都具有属性特征用数据表示和方法行为用程序代码实现。对象由属性和方法共同组成。类类是具有相同属性和行为的一组对象的集合为所有该类对象提供统一的抽象描述。对象是类的具体实例。简而言之类是对象的模板抽象对象是类的实例具体。2类与对象的关系类具有相同特征的一类事物(人、狗、老虎)对象实例具体的某一个事物隔壁阿花、楼下旺财实例化类➔对象的过程3类的定义①什么是类类class是具有相同属性和行为的一组对象的集合由3部分组成的类名类名大驼峰单词之间无分隔符。属性一组数据比如角色性别等。方法允许进行操作的方法比如走路。②类与函数③定义一个类➊__init__方法构造方法无需手动调用在生成实例对象时自动执行。作用是初始化新创建对象的属性。若类中未定义__init__实例化时会自动调用默认的无参构造方法。➋self参数代表当前类的实例指向实例对象本身。Python 规定实例方法的第一个参数必须是实例对象本身习惯命名为self非关键字可改名但强烈推荐使用self。调用实例方法时无需手动传入self系统会自动传递。④this指针与self提示self在功能上等同于C的this指针可以把self看作一个this指针。区别它们在功能上完全相同都是指代当前实例区别在于 Python 要求显式声明和使用而 C 是隐式的。4创建对象 -- 类的实例化⚠️注意在访问对象的方法时实参要与除self以外的其他形参匹配。实参与形参一一对应每次创建的对象在内存中的地址是不相同的。示例代码定义矩形类Rectangle有三个方法1__init__方法初始化长和宽2getArea方法返回矩形的面积3getPerimeter方法返回矩形的周长3、属性和方法的访问控制1类属性类属性定义在类中、方法之外的变量属于类对象本身用于记录与类整体相关的特征。核心特点被该类的所有实例对象所共享在内存中只保留一个副本。类属性既可以通过类名直接访问也可以通过实例名访问。特殊的类属性①类名.__name__ # 类的名字②类名.__doc__ # 类的文档字符串③类名.__base__ # 类的第一个父类④类名.__bases__ # 类所有父类构成的元组⑤类名.__dict__ # 类的字典属性⑥类名.__module__ # 类定义所在的模块⑦类名.__class__ # 实例对应的类2实例属性实例属性在__init__构造函数中定义的属性属于具体的实例对象只能通过对象名访问。虽然也可以在类中其他方法里随意添加新属性但不提倡这样做。最佳实践所有实例属性都应在__init__方法中集中定义和初始化这样有助于清晰地管理类的属性结构便于维护和修改。总结实例属性属于具体对象最好在__init__中统一定义通过对象名访问。3方法的访问控制实例方法类方法静态方法①实例方法实例方法是类中默认定义的方法必须通过实例化对象才能调用。它的核心特征是至少包含一个self参数用于绑定调用该方法的实例对象由 Python 自动完成绑定。通常通过实例对象调用也可以使用类名调用但需要手动为self参数传入一个实例对象作为实参。两个特殊的实例方法构造方法__init__(self)析构方法__del__(self)析构方法一般无需定义当对象在内存中被释放时自动触发执行。②类方法类方法是类对象拥有的方法操作类级别的数据用classmethod装饰器标识无需实例化即可调用。核心特点第一个参数是cls代表类本身由 Python 自动传入。可通过类名或实例名访问类名.方法名()或实例.方法名()。主要作用修改类属性、调用其他类方法。应用场景方法中只涉及静态属性类属性时使用。实例属性discount的主要弊端无法统一管理每个实例独立存储修改折扣需逐一操作效率低下。数据一致性差容易遗漏某些实例导致同类商品折扣不一致。内存浪费每个实例重复存储相同的属性值。维护成本高批量修改需遍历所有实例代码冗余。关键点类属性discount被所有实例共享内存中只存在一份。类方法change_discount通过cls参数修改类属性无需实例化即可调用。实例方法new_price通过Goods.discount访问类属性所有实例统一使用当前折扣。总结共享数据应定义为类属性避免重复存储和逐一维护。③静态方法静态方法用staticmethod装饰器标识不需要self或cls参数本质上是一个与类解耦的独立函数只是被放在类的命名空间中。核心特点无需self或cls参数与类和实例没有直接关联。可通过类名或实例名访问类名.方法名()或实例.方法名()。不能访问类属性或实例属性功能等同于普通函数。应用场景方法逻辑与类本身无关但功能上归属于该类如工具函数、辅助计算等。与类方法的区别静态方法既不使用实例属性也不使用类属性就是放在类里的普通函数。类方法不使用实例属性只使用类属性用于操作类级别的数据第一个参数是cls。三、封装、继承和多态1、封装1什么是封装封装将属性和方法整合到一个类中类是封装的载体。核心要点①隐藏内部细节用户无法直接查看或操作类内部的数据结构只能通过类提供的公开方法进行访问。②保护数据完整性通过限制外部直接访问避免内部数据被随意篡改确保数据安全。③提高可维护性内部实现变更时只要公开接口保持不变外部代码不受影响便于维护和扩展。2私有属性Python中的私有属性并非真正无法访问。在类中定义的私有属性以双下划线__开头类外访问时需加上_类名前缀即可访问。核心要点①命名重整Python会将私有属性__attr自动重命名为_类名__attr以实现“伪私有”。②类外访问方式通过实例._类名__私有属性名可以强行访问。③本质这是一种约定而非强制限制体现了Python“大家都是成年人”的设计哲学。总结私有属性只是被“改名”了知道规则后依然可以访问并不存在真正的私有性。间接访问方法1为了更好的保存属性安全即不能随意修改一般的处理方式为➊将属性定义为私有属性以两个下划线开头➋添加方法间接访问私有变量。说明◎python 私有属性只能在类内部访问类外面访问会出错。◎python 保护属性更多的是一种语法上的标识用来提醒直接修改改对象时候要小心。间接访问方法2 -- property功能property属性内部进行一系列的逻辑计算最终返回计算结果。property属性有两种方式①类属性方式创建值为property对象的类属性②在类的实例方法上应用property装饰器-- property修饰获取的方法getter方法名必须和属性名一样-- XXX.setter修饰设置值的方法setter方法名必须和属性名一样作用在新式类中返回属性值。 新式类继承object的类语法class property([fget[, fset[, fdel[, doc]]]])●fget -- 获取属性值的函数●fset -- 设置属性值的函数●fdel -- 删除属性值函数●doc -- 属性描述信息第一个参数是方法名调用 对象.属性 时自动触发执行方法第二个参数是方法名调用 对象.属性 XXX 时自动触发执行方法第三个参数是方法名调用 del 对象.属性 时自动触发执行方法第四个参数是字符串调用 对象.属性.doc 此参数是该属性的描述信息one、属性方式two、property装饰器方式3私有方法Python默认的成员函数和成员变量都是公开的在变量名或函数名前加上 “_ _两个下划线那么这个函数或变量就会为私有的了。 私有方法不能在类的外部调用但可以在类内部访问私有方法。2、继承面向对象的编程带来的主要好处之一是代码的复用实现这种复用的方法之一是通过继承机制。说明object类是Python中所有类的基类如果定义一个类时没有指定继承哪个类则默认继承object类。 子类可以继承父类的公有成员但不能继承其私有成员。1单继承单继承是指新建的类只继承一个父类class 派生类名(基类名): 类体在继承中基类的构造方法__init__()方法不会被自动调用它需要在其子类的构造方法中专门调用。 如果需要在子类中调用基类的方法可以使用内置函数super()或者通过“基类名.方法名(参数)”的方式来实现。方法一使用super()方法二使用基类名直接调用2多继承类的多重继承通过类的多重继承一个子类就可以继承多个父类并从多个父类中取得所有非私有方法。class 派生类名(基类1, 基类2,...., 基类n): 类体核心规则在Python多继承中若子类未定义某方法则按父类在圆括号中的从左到右顺序依次搜索。即子类自己没有就按父类声明顺序逐个查找。关键要点●搜索路径子类 → 从左到右的父类 → 父类的父类遵循相同顺序。●实际机制Python 通过 MRO方法解析顺序 算法C3 线性化确定精确搜索路径可用类名.__mro__查看。●多继承冲突当多个父类有同名方法时左侧优先。3重载和重写重载在Python中只要方法名相同就认为是同一个方法后定义的同名方法会覆盖先定义的。在多继承中先继承的父类同名方法会覆盖后继承的父类同名方法。Python语法上不支持传统意义上的重载但可通过魔法方法或装饰器实现类似重载的效果。重写子类可以对从父类中继承过来的方法进行重新定义从而使得子类对象表现出与父类对象不同的行为。重载和重写的区别重写发生在子类和父类之间子类会覆盖父类中同名且参数、返回类型都相同的方法也称为方法覆盖。重载发生在同一个类内部指多个同名函数共存但这些函数的参数类型或参数个数不同返回类型也可以不同。Python语法上不支持重载。Python不需要重载的原因Python原生语法已经天然支持参数类型灵活和参数个数灵活所以不需要通过方法重载来手动实现这些效果。3、多态1什么是多态多态同一名字的方法产生了多个不同的行为也就是不同的对象收到相同的消息时产生不同的行为方式。简而言之多态就是一个对象同样的方法在不同场景有不同的行为。多态的体现在python中很多地方都可以提现多态的特性如内置函数len()len函数不仅可以计算字符串的长度还可以计算列表、元组等对象中的数据个数在运行时通过参数类型确定其具体的计算过程正是多态的一种体现。2多态的应用场景①对象所属的类之间没有继承关系②对象所属的类之间有继承关系应用更广3多态的特点●只关心对象的实例方法是否同名不关心对象所属的类型。●对象所属的类之间继承关系可有可无。●多态的好处可以增加代码的外部调用灵活度让代码更加通用兼容性比较强。●多态是调用方法的技巧不会影响到类的内部设计。拓展Java中的多态体现为父类引用指向子类对象表现形式明确。Python虽然也支持多态但由于变量不需要声明类型不存在父类引用指向子类对象这种典型写法所以多态在Python中表现得不那么明显。因此在Python中刻意强调多态的意义并不大。4派生子类可以在继承父类的基础上定义新的属性也可以定义与父类同名的属性来覆盖父类的属性。这些重新定义或新增的属性都属于子类自己子类独有的不会影响父类。当子类定义了与父类同名的属性时调用该属性将以子类自己的定义为准。子类也因此被称为派生类。4、动态性1python的动态性Python是动态语言特点就是可以动态增加和修改类和对象的属性和方法。说明 __slots__只对类的实例起作用。 并不限制通过类来动态添加属性或方法对该类派生出来的子类也不起作用。2使用type()函数动态创建类type() 函数的语法格式有 2 种①type(obj)②type(name, bases, dict)第一种语法格式用来查看某个变量类对象的具体类型。第二种语法格式用来创建类其中 name 表示类的名称bases 表示一个元组其中存储的是该类的父类dict 表示一个字典用于表示类内定义的属性或者方法。3metaclass动态修改类定义metaclass是type的子类通过重写type的__call__方法可以改变类的创建行为。它在Python中功能极其强大但争议也很大有人认为它无所不能也有人认为它容易导致滥用。即使是硅谷一线大厂使用metaclass也需要特批。真正深入理解它的开发者极少在实际工作中应当谨慎使用。四、模块1、模块1什么是模块模块是一个包含所有定义的函数和变量的文件其后缀名是.py。模块可以被别的程序引入以使用该模块中的函数等功能。2模块的分类①内置模块内置模块Python内置标准库中的模块也是Python的官方模块可直接导入程序。在命令行下运行$ pydoc modules即可查看。②第三方模块第三方模块由非官方制作发布供给大众使用的Python模块在使用之前需要先自行安装。在命令行下运行$ pip install SomePackage即可安装第三方模块$ pip list 显示已安装的模块③自定义模块自定义模块是用户在程序编写中自行编写存放功能性代码的.py文件。3模块的使用Python程序通常由一个主程序以及多个模块组成。下图描述了一个由三个程序文件a.py、b.py和c.py.py组成的Python程序其中a.py是主程序b.py和c.py是模块箭头指向代表了程序之间的相互调用关系。模块b.py和c.py一般不能直接执行该程序的执行只能从主程序a.py开始。●导入某个模块○import module1,mudule2...○使用模块中的某个函数 模块名.函数名●导入某个模块中的函数○from 模块名 import 函数名1,函数名2,...○使用模块中的某个函数 函数名●导入某个模块中的所有函数○from 模块名 import *○使用模块中的某个函数 函数名●导入模块并取别名:○import 模块名 as 新名字注意事项4自定义模块示例代码输出结果2、模块的有条件执行1__name__属性●_ _name_ _是python的一个内置类属性它存储模块的名称。●python的模块既可以被调用也可以独立运行。而被调用时_ _name_ _存储的是py文件名(模块名称)独立运行时存储的是“_ _main_ _。●它的作用主要就是用来区分当前模块是独立运行还是被调用。2示例代码if __name__ __main__: 的作用是判断当前脚本是否作为主程序直接运行如果是则执行该代码块如果是被其他模块导入则不执行从而让代码既可以被测试又可以被安全地导入使用。此时main.py为主程序swap模块的if __name__ __main__:条件不符不运行这个分支此时swap.py是主程序swap模块的if __name__ __main__:条件符合运行这个分支3、Python包结构1包的概念如果有两个相同名字的模块应该如何防止命名冲突为了更好地管理多个模块源文件Python 提供了包的概念。 简单来说包就是文件夹但该文件夹下必须存在 _ _init_ _.py 文件。_ _init_ _.py文件内容是空的它的作用是告诉解释器这是一个Python Package。 从逻辑上看包的本质依然是模块。2numpy包Python 安装了 numpy 模块之后可以在 Python 安装目录的 Lib\site-packages 目录下找到一个 numpy 文件夹它就是前面安装的 numpy 模块其实是一个包。numpy 包也是模块下既包含了 matlib.py 等模块源文件也包含了 core 等子包也是模块。这正对应了我们刚刚介绍的包的本质依然是模块因此包又可以包含包。3定义包定义包主要有两步①创建一个文件夹该文件夹的名字就是该包的包名。②在该文件夹内添加一个 _ _init_ _.py 文件即可。●包的本质就是模块因此导入包和导入模块的语法完全相同只是需要在模块前加上包名●包的导入仍使用 import 、 from ... import 语句使用 “圆点模块名” 的结构化模块命名空间。●与模块类似的是包被导入之后会在包目录下生成一个 __pycache__ 文件夹并在该文件夹内为包生成一个 __init__.cpython-36.pyc 文件。4导入包main.py4、常用模块1第三方模块的安装pip 是 Python 包管理工具该工具提供了对Python 包的查找、下载、安装、卸载的功能。可以通过以下命令来判断是否已安装2常用的第三方库安装3示例代码安装第三方库wordcloud4OS库os库提供通用的、基本的操作系统交互功能。os库是Python标准库包含几百个函数 常用路径操作、进程管理、环境参数等几类。①路径操作os.path子库处理文件路径及信息②进程管理启动系统中其他程序③环境参数获得系统软硬件信息等环境参数♞路径操作♞进程管理♞环境参数5random模块random是python的重要标准模块之一用于伪随机数生成所用的算法是梅森旋转算法。(1) random.random() #用于生成一个0到1的随机浮点数0 n 1.0(2) random.uniform(a,b) #用于生成一个指定范围内的随机浮点数(3) random.randint(a, b) #用于生成一个指定范围内的整数。(4) random.randrange([start], stop[, step]) #从指定范围内按指定基数递增的集合中获取一个随机数(5) random.choice(sequence) #从序列中获取一个随机元素(6) random.shuffle(x[, random]) #用于将一个列表中的元素打乱(7) random.sample(sequence, k) #从指定序列中随机获取指定长度的片断并随机排列

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价