033.Python面向对象_类补充_生命周期

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈

分隔线

类&补充_生命周期

    • 生命周期
      • 概念
      • 涉及问题
      • 监听对象生命周期
        • `__new__` 方法
        • `__init__` 方法
        • `__del__` 方法
      • 生命周期案例
    • 内存管理机制
      • 存储方面
      • 垃圾回收方面
        • 引用计数机制
        • 垃圾回收机制
          • 主要作用
          • 底层实现原理(了解/难)
          • 垃圾回收时机(掌握&简单)
          • 循环引用解决办法

生命周期

概念

  • 生命周期指的是一个对象从诞生到消亡的过程
  • 当一个对象被创建时,会在内存中分配相应的内存空间进行存储
  • 当这个对象不在使用,为了节约内存,就会把这个对象释放

涉及问题

  • 如何监听一个对象的生命过程?
  • Python是如何掌控一个对象的生命?

监听对象生命周期

__new__ 方法
  • 当我们创建一个实例对象时,用于给这个实例对象分配内存的方法
  • 通过拦截这个方法,可以修改实例对象的创建过程。例如:单例设计模式
    # 对比示例
    class Person1(object):passp1 = Person1()
    print(p1)            # 输出:<__main__.Person object at 0x000001F672F8F5E0># __new__方法示例
    class Person2(object):def __new__(cls, *args, **kwargs):print('新建一个实例对象,被我拦截了')p2 = Person2()
    print(p2)            # 输出:新建一个实例对象,被我拦截了    None
    
__init__ 方法
  • 当实例对象被创建完成之后,会自动调用这个方法,并且将这个对象传递给self
  • 在这个方法中可以给这个创建好的对象增加一个额外的信息(如:属性)
  • 通过__new__方法拦截实例对象创建操作后,该方法也无法执行
    class Person(object):def __init__(self):print('对象初始化')self.name = '失心疯'p = Person()
    print(p.name)# 实例对象创建被拦截后,该方法也无法执行
    class Person(object):def __new__(cls, *args, **kwargs):print('新建实例对象,被拦截了')def __init__(self):print('对象初始化')self.name = '失心疯'p = Person()
    print(p.name)# 输出结果
    # Traceback (most recent call last):
    #   File "E:\StudyCode\Python\13-面向对象\18-生命周期.py", line 28, in <module>
    #     print(p.name)
    # AttributeError: 'NoneType' object has no attribute 'name'
    # 新建实例对象,被拦截了
    
__del__ 方法
  • 当对象被释放时,会自动调用这方法(如:通过del方法删除对象)
    class Person(object):# def __new__(cls, *args, **kwargs):#     print('新建实例对象,被拦截了')def __init__(self):print('对象初始化')self.name = '失心疯'def __del__(self):print('对象被释放了')p = Person()
    print(p.name)
    del p
    

生命周期案例

  • 要求:记录一下,当前这个时刻由Person类产生的实例对象有多少个
  • 实现:创建一个实例对象,计数+1,删除一个实例对象,计数-1
    personCount = 0class Person(object):def __init__(self):global personCountpersonCount += 1# print('创建实例对象 计数+1')def __del__(self):global personCountpersonCount -= 1# print('释放实例对象 计数-1')p1 = Person()
    p2 = Person()
    print('当前实例个数为:', personCount)      # 当前实例个数为: 2
    del p1
    print('当前实例个数为:', personCount)      # 当前实例个数为: 1
    
  • 这一段实现代码中有几个问题
    • 1、每次输出统计数量的时候都要重复写上print('当前实例个数为:', personCount)这一句,代码冗余
    • 2、用于计数的personCount变量是一个全局变量,在外部可以随意改变
    • 3、在类内部使用personCount变量时,都需要使用global关键字指定变量是全局变量
  • 解决方法:
  • 1、将重复性的操作封装成一个方法,每次要用的时候直接调用方法
  • 2、将全局变量定义成类属性(不定义成实例属性,是因为实例属性是分别记录各个实例对象的属性)
  • 示例代码优化
    class Person(object):personCount = 0def __init__(self):Person.personCount += 1# print('创建实例对象 计数+1')def __del__(self):self.__class__.personCount -= 1# print('释放实例对象 计数-1')@staticmethod   # 静态方法def count():print('当前实例个数为:', Person.personCount)p1 = Person()
    p2 = Person()
    Person.count()      # 当前实例个数为: 2Person.personCount = 100
    del p1
    Person.count()      # 当前实例个数为: 99
    
  • 优化后的代码中依然有一些问题
    • 1、这个类属性在外界通过类名.属性的方式依然可以对这个属性进行修改
  • 解决方法
    • 将这个类属性改成私有属性,外界就无法对这个属性进行修改了
  • 示例代码优化
    class Person(object):__personCount = 0def __init__(self):Person.__personCount += 1# print('创建实例对象 计数+1')def __del__(self):self.__class__.__personCount -= 1# print('释放实例对象 计数-1')@staticmethod   # 静态方法def count():print('当前实例个数为:', Person.__personCount)p1 = Person()
    p2 = Person()
    Person.count()      # 当前实例个数为: 2
    del p1
    Person.count()      # 当前实例个数为: 1
    
  • 在这一段代码中,依然可以进行优化
  • 在这个类中的静态方法def count()中用到了这个类,那么我们在定义这个方法的时候,就可以通过参数来接收一个类
  • 那么,就可以通过定义类方法来实现这个操作
    class Person(object):__personCount = 0def __init__(self):Person.__personCount += 1# print('创建实例对象 计数+1')def __del__(self):self.__class__.__personCount -= 1# print('释放实例对象 计数-1')@classmethod   # 类方法def count(cls):print('当前实例个数为:', cls.__personCount)p1 = Person()
    p2 = Person()
    Person.count()      # 当前实例个数为: 2
    del p1
    Person.count()      # 当前实例个数为: 1
    


内存管理机制

  • 在Python中,内存管理机制是引用计数机制和垃圾回收机制两套机制并行的
  • 垃圾回收机制解决循环引用的问题,但是引用计数机制效率更高

存储方面

  • 1、在Python中万物皆对象
    • 其他部分语言中存在基本数据类型和对象
    • Python不存在基本数据类型,int、float、bool、str等都是对象
  • 2、所有对象都会在内存中开辟一块空间进行存储
    • 会根据不同的类型一级内容,开辟不同的空间大小进行存储
    • 返回该控件的地址给外界接收(称为“引用”)没用与后续对这个对象的操作
    • 通过id(对象)函数可以获取指定对象的内存地址(10进制)
    • 通过hex(10进制内存地址)函数可以查看对应的16进制地址
  • 3、对于整数和短小的字符,Python会进行缓存处理,不会创建多个相同的对象
  • 4、容器对象存储的其他对象,仅仅是存储的其他对象的引用,并不是存储的其他对象本身

垃圾回收方面

引用计数机制
  • 概念

    • 一个对象会记录者自身被引用的个数
      • 每增加一个引用,这个对象的引用计数就会自动+1
      • 每减少一个引用,这个对象的引用计数就会自动-1
  • 查看引用计数

    • 可以通过sys模块中的getrefcount(对象)方法获取到指定对象的引用数
    • 调用这个函数的时候,这个对象作为参数被传递的时候就是被引用,所以统计出来的引用数会比实际的引用数大1
      import sysclass Person(object):passp1 = Person()                   # 引用个数:1
      print(sys.getrefcount(p1))      # 2,获取到的引用个数比实际的大1p2 = p1                         # 引用个数:2
      print(sys.getrefcount(p1))      # 3del p2                          # 引用个数:1
      print(sys.getrefcount(p1))      # 2del p1                          # p1对象被删除,后续就无法再通过p1进行查询操作
      print(sys.getrefcount(p1))      # 报错:NameError: name 'p1' is not defined
      
  • 引用计数发生改变的场景举例

  • 引用计数+1场景

    • 对象被创建时 p1 = Person()
    • 对象被引用时 p2 = p1
    • 对象被作为参数传入到一个函数中时 log(p1),引用计数会+2
      • 对象作为参数传入一个函数时,在函数内部会被两个属性引用(__globals__func_globals)
    • 对象作为一个元素存储到容器中时 l = [p1]
  • 引用计数-1场景

    • 对象的别名被现实销毁 del p1
    • 对象的别名被赋予新的对象 p1 = 123
    • 一个对象离开它的作用域
      • 一个函数执行完毕时,内部的局部变量关联的对象,它的引用会被释放
    • 对象所在的容器被销毁或者从容器中删除对象
  • 特殊场景-循环引用问题

  • 内存管理机制:当一个对象 被引用,引用计数+1,删除引用,引用计数-1;引用计数为0时,对象被自动释放

  • 循环引用:

    class Person(object):passclass Dog(object):passp = Person()
    d = Dog()p.pet = d
    d.master = pdel p
    del d
    
    • 在这里插入图片描述
    * 通过 p = Person() 实例化对象的时候,p 引用了 Person 的内存地址, Person 对象的引用计数+1,此时 Person 对象的引用计数=1
    * 通过 d = Dog() 实例化对象的时候, d 引用了 Dog 的内存地址, Dog 对象的引用计数+1,此时 Dog 对象的引用计数=1* 通过 p.pet = d 添加属性赋值, Person 对象的 pet 属性引用了 Dog 的内存地址, Dog 对象的引用计数再+1,此时 Dog 对象的引用计数=2
    * 通过 d.master = p 添加属性赋值, Dog 对象的 master 属性引用了 Person 的内存地址, Person 对象的引用计数再+1,此时 Person 对象的引用计数=2* 通过 del p 语句删除p实例对象,释放 Person 对象的一个引用, Person 对象的引用计数-1,此时 Person 对象的引用计数=1
    * 通过 del d 语句删除d实例对象,释放 Dog 对象的一个引用, Dog 对象的引用计数-1,此时 Dog 对象的引用计数=1* 此时已经没有变量引用 Person和Dog对象了,这两个对象就没办法被使用了,但是他们的引用计数依然保存着1,就不会被释放掉,就造成了内存泄漏
    * 这两个对象之间属于互相引用的关系,就成了循环引用,导致两个对象的引用计数都是1,所以不能被引用计数机制释放
    
  • 由于实例对象被删除之后,无法使用sys.getrefcount获取对象的引用计数,需要通过第三方库objgraphcount方法来查看垃圾回收器,跟踪的对象个数

    • 安装第三方库objgraph
      pip install objgraph
      
    • 使用第三方库跟踪对象个数
      # 没有被循环引用的情况
      import objgraphclass Person(object):passclass Dog(object):passp = Person()
      d = Dog()
      print(objgraph.count('Person'))     # 追踪关于Person这个类的相关对象个数:1(也就是由Person类创建的实例对象个数)
      print(objgraph.count('Dog'))        # 追踪关于Dog这个类的相关对象个数:1(也就是由Dog类创建的实例对象个数)del p
      del d
      print(objgraph.count('Person'))     # p实例对象被删除,Person类相关的对象个数:0
      print(objgraph.count('Dog'))        # d实例对象被删除,Dog类相关的对象个数:0#==================================================# 被循环引用之后的情况
      import objgraphclass Person(object):passclass Dog(object):passp = Person()
      d = Dog()
      print(objgraph.count('Person'))     # 追踪关于Person这个类的相关对象个数:1(也就是由Person类创建的实例对象个数)
      print(objgraph.count('Dog'))        # 追踪关于Dog这个类的相关对象个数:1(也就是由Dog类创建的实例对象个数)p.pet = d
      d.master = pdel p
      del d
      print(objgraph.count('Person'))     # p实例对象被删除,但是被Dog类的master属性引用,Person类相关的对象个数:1
      print(objgraph.count('Dog'))        # d实例对象被删除,但是被Person类的pet属性引用,Dog类相关的对象个数:1
      
垃圾回收机制
  • 垃圾回收机制:是属于引用计数机制的一个补充机制(一般对象完全可以通过引用计数机制进行释放,但是如果对象被循环引用,就无法通过引用计数机制进行释放,所以就产生了垃圾回收机制)
主要作用
  • 从经历过“引用计数机制”仍未被释放的对象中,找到“循环引用”并且干掉相关对象
底层实现原理(了解/难)
  • 怎样找到“循环引用”?

    • 1、收集所有的“容器对象”,通过一个双向链表进行记录引用
      • 容器对象:可以引用其他对象的对象(列表、元组、字典、自定义类对象等可以添加其他对象的东西)
      • 非容器对象:不可以引用其他对象的对象(int、float、bool、str等不能添加其他对象的对象)<非容器对象不能引用其他对象,所以就不会出现循环引用的情况>
      • 双向链表:
    • 2、针对每一个“容器对象”,通过一个变量gc_refs来记录当前对应的引用计数
    • 3、针对每个“容器对象”,找到他引用的“容器对象”,并将这个引用的“容器对象”的引用计数-1
    • 4、经过步骤3之后,如果一个“容器对象”的引用计数为0,就代表这个“容器对象”可以被回收了,肯定是“循环引用”导致他活到现在的
    • 在这里插入图片描述
  • 如何提升查找“循环引用”的性能

  • 上面这种垃圾回收的检测机制需要把所有记录在双向链表中的“容器对象”进行检测一遍,是非常的耗费性能。

  • 基于这个问题,Python就提出了一个假设:命越大,越长寿

    • 假设一个对象经过10次检测都没有被释放掉,那就认定这个对象一定很长寿,就减少对这个对象的“检测频率”
  • 基于这种假设,就设计了一套机制:分代回收

  • 分代回收

    • 1、默认一个对象被创建出来之后,属于0代
    • 2、如果经历过这一代“垃圾回收”之后,依然没有被释放,则划分到下一代
    • 3、“垃圾回收”的周期
      • 0代“垃圾回收”一定次数,会触发0代和1代回收
      • 1代“垃圾回收”一定次数,会触发0代、1代和2代回收
    • 在这里插入图片描述
  • 垃圾回收器当中,新增的对象个数-消亡的对象个数,达到一定的阈值时,才会触发垃圾检测

  • 个人理解:当出现循环引用对象(无法被释放的对象)个数达到一定阈值时候才会触发垃圾检测

  • 查看和设置相关参数

  • 语法

    import gcgc.get_threshold()          # 查看触发机制的阈值
    # 输出 (700, 10, 10)
    # 700   触发垃圾检测的阈值
    # 10    触发0代和1代回收的阈值
    # 10    触发0代、1代和2代回收的阈值gc.set_threshold(触发垃圾检测的阈值,触发0代和1代回收的阈值,触发0代、1代和2代的阈值)
    # 设置触发阈值
    
  • 示例代码

    import gcprint(gc.get_threshold())           # 输出:(700, 10, 10)
    # 700   垃圾回收器中, 新增对象个数 - 消亡对象个数 = 700,触发垃圾检测
    # 10    每经过10次【0代垃圾回收】检测,就触发一次【0代和1代回收】(前面10次仅执行0代回收)
    # 10    每经过10次【0代和1代垃圾回收】检测,就触发一次【0代、1代和2代回收】
    # 10次【0代回收】执行1次【0代和1代回收】,10次【0代和1代回收】执行1次【0代、1代和2代回收】gc.set_threshold(1000, 50, 20)
    # 1000   设置垃圾回收器中, 新增对象个数 - 消亡对象个数 = 1000时,才触发垃圾检测
    # 50     设置每经过50次【0代垃圾回收】检测,就触发一次【0代和1代回收】
    # 20      设置每经过20次【0代和1代垃圾回收】检测,就触发一次【0代、1代和2代回收】print(gc.get_threshold())           # 输出:(1000, 50, 20)
    
垃圾回收时机(掌握&简单)
  • 自动回收
  • 触发条件:开启垃圾回收机制并且达到了垃圾回收的阈值
  • 阈值:垃圾回收器中,新增的对象个数 与 释放的对象个数 之差
  • 垃圾回收机制开启和关闭设置
    import gcgc.enable()         # 开启垃圾回收机制(默认开启)
    gc.disable()        # 关闭垃圾回收机制
    gc.isenabled()      # 判定垃圾回收机制是否开启状态
    
  • 垃圾回收阈值获取和设置
    import gcgc.get_threshold()      # 获取自动回收阈值
    gc.set)threshold()      # 设置自动回收阈值
    
  • 手动回收
  • 语法
    import gcgc.collect(garbage=None)    # 运行垃圾收集器# garbage:可以是一个整数,指定要收集哪一代,默认运行完整收集(0代、1代、2代)# 无论垃圾回收机制是否开启,都可以运行
    
  • 示例(循环引用问题解决)
    # 默认情况,出现循环引用后无法被引用计数机制释放,未达到阈值的情况下也不会被垃圾回收机制释放
    import objgraphclass Person(object):passclass Dog(object):passp = Person()
    d = Dog()p.pet = d
    d.master = pdel p
    del dprint(objgraph.count('Person'))      # 输出:1
    print(objgraph.count('Dog'))         # 输出:1#=============通过手动开启垃圾回收机制进行释放=========================import objgraph
    import gcclass Person(object):passclass Dog(object):passp = Person()
    d = Dog()p.pet = d
    d.master = pdel p
    del dgc.collect()                        # 手动开启垃圾回收机制print(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
循环引用解决办法
  • 可到达引用:可以直接访问真实对象的引用(p 和 d)
  • 不可到达引用:需要通过可到达引用间接的访问真实对象(pet 和 master)
    • 不能直接通过pet和master访问真实对象,必须通过p.pet和d.master间接访问,删除p和d之后,就无法通过pet和master访问到真实对象了
  • 强引用:会影响对象的引用计数的引用
  • 弱引用:与强引用相对,弱引用并不会影响对象的引用计数,也就是说其不影响对象是否被回收的判定(需要使用weakref模块)
  • 基础类型int、list、dict、tuple、str不支持弱引用,对其执行弱引用会报错
  • 可以通过__weakrefoffset__查看类型是否支持弱引用,该变量表示弱引用指针相对对象起始地址的偏移量,>0表示支持弱引用
  • weakref模块
  • 方法
    weakref.ref(obj)                    # 给指定对象创建一个弱引用
    weakref.WeakKeyDictionary(dict)     # 给指定字典的key创建一个弱引用
    weakref.WeakValueDictionary(dict)   # 给指定字典的value创建一个弱引用
    
  • 通过使用弱引用解决循环引用不能自动释放问题
    import objgraph
    import weakrefclass Person(object):passclass Dog(object):passp = Person()
    d = Dog()p.pet = d
    d.master = weakref.ref(p)       # 通过weakref.ref进行弱引用del p
    del dprint(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
    
  • 当一个对象引用多个对象时,可以使用字典的方式
    import objgraph
    import weakrefclass Person(object):passclass Dog(object):passclass Cat(object):passp = Person()
    d = Dog()
    c = Cat()# p.pet = {'Dog': d, 'Cat': c}
    p.pet = weakref.WeakValueDictionary({'Dog': d, 'Cat': c})
    d.master = pdel p
    del d
    del cprint(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
    print(objgraph.count('Cat'))         # 输出:0
    
  • 在释放对象之前打断循环引用
    import objgraphclass Person(object):passclass Dog(object):passp = Person()
    d = Dog()p.pet = d
    d.master = pp.pet = None
    del p
    del dprint(objgraph.count('Person'))      # 输出:0
    print(objgraph.count('Dog'))         # 输出:0
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/218707.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Co-DETR:DETRs与协同混合分配训练代码学习笔记

关于论文的学习笔记&#xff1a;Co-DETR:DETRs与协同混合分配训练论文学习笔记-CSDN博客 作者提出了一种新的协同混合任务训练方案&#xff0c;即Co-DETR&#xff0c;以从多种标签分配方式中学习更高效的基于detr的检测器。这种新的训练方案通过训练ATSS和Faster RCNN等一对多标…

Node.js入门指南(四)

目录 express框架 express介绍 express使用 express路由 express 响应设置 中间件 路由模块化 EJS 模板引擎 express-generator hello&#xff0c;大家好&#xff01;上一篇文章我们介绍了Node.js的模块化以及包管理工具等知识&#xff0c;这篇文章主要给大家分享Nod…

C语言进阶之路-运算符小怪篇

目录 一、学习目标 二、运算符详谈 算术运算符 关系运算符 逻辑运算符 位运算符 特殊运算符 条件运算符 sizeof 运算符 打怪实战 三、控制流 二路分支 多路分支 const while与 do…while循环 语法&#xff1a; for循环 break与continue goto语句&#xff08…

输出后,我悟了!

大家好&#xff0c;我是木川 今天和前同事吃饭聊天&#xff0c;谈到了输出&#xff0c;今天简单谈下关于输出的重要性 一、为什么要输出 1、不输出容易忘&#xff0c;如果不输出很容易就忘记了&#xff0c;如果再遇见一次&#xff0c;还是需要重新学习&#xff0c;实际上是浪费…

Windows系统管理之备份与恢复

本章目录&#xff1a; 一. 本章须知&#xff1a; 前置条件 需要创建一个新的磁盘 前置条件2 给新添加的磁盘分盘 二. 了解开启并学会使用Windows sever backup 如何使用备份与恢复“备份计划”“一次性备份”“恢复” 最后是用命令行“一次性备份命令 ”完成一次备份 话不多说 …

【2023传智杯】第六届传智杯程序设计挑战赛AB组-ABC题解题分析详解【JavaPythonC++解题笔记】

本文仅为第六届传智杯程序设计挑战赛-题目解题分析详解的解题个人笔记,个人解题分析记录。 本文包含:第六届传智杯程序设计挑战赛题目、解题思路分析、解题代码、解题代码详解 文章目录 一.前言二.比赛题目(AB俩组)A题题目B题题目C题题目三.解题代码A题解题思路解题代码【J…

Unity 场景切换

Unity场景切换可使用以下方法&#xff1a; 1、SceneManager.LoadScene()方法&#xff1a; using UnityEngine.SceneManagement;// 切换到Scene2场景 SceneManager.LoadScene("Scene2"); 2、使用SceneManager.LoadSceneAsync()方法异步加载场景&#xff0c;异步加载…

Linux:docker基础操作(3)

docker的介绍 Linux&#xff1a;Docker的介绍&#xff08;1&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/134146721?spm1001.2014.3001.5502 通过yum安装docker Linux&#xff1a;Docker-yum安装&#xff08;2&#xff09;-CSDN博客https://blog.…

pandas根据列正逆序排序

题目&#xff1a;根据 buy_quantity 列进行排名&#xff0c;相同值分配相同的最低排名。 import pandas as pd# 创建一个示例 DataFrame data {item_id: [1, 2, 3, 4, 5, 6, 7], buy_quantity: [1, 2, 2, 3, 3, 4, 5]} df pd.DataFrame(data)# 使用 rank() 函数为 buy_quant…

JMeter 测试脚本编写技巧

JMeter 是一款开源软件&#xff0c;用于进行负载测试、性能测试及功能测试。测试人员可以使用 JMeter 编写测试脚本&#xff0c;模拟多种不同的负载情况&#xff0c;从而评估系统的性能和稳定性。以下是编写 JMeter 测试脚本的步骤。 第 1 步&#xff1a;创建测试计划 在JMet…

Redis分片集群

文章目录 Redis分片集群搭建分片集群散列插槽插槽原理小结 集群伸缩需求分析创建新的redis实例添加新节点到redis转移插槽 故障转移自动故障转移手动故障转移 RedisTemplate访问分片集群 Redis分片集群 搭建分片集群 主从和哨兵可以解决高可用、高并发读的问题。但是依然有两…

MidJourney笔记(3)-Prompts

MidJourney的Prompts介绍 MidJourney的Prompts是MidJourney的核心之一,这也是我们后续使用MidJourney过程中最重要的工作内容,根据生成的图片,不断的优化我们的Prompts内容。 那Prompts的中文意思是提示的意思。 Prompts的提示语有很多,最基础的用法就是: /imagine prompt…