首页 > 编程问答 >setattr 设置多级属性时似乎没有效果

setattr 设置多级属性时似乎没有效果

时间:2024-07-21 01:15:17浏览次数:9  
标签:python setattr renpy

我正在为 Ren'Py 游戏编写一个 mod,其中包含编辑游戏变量值的可能性(“作弊”)。游戏中的变量包括从简单布尔值到相当复杂的变量(例如 simple_variable、obj.attr、obj.attr_a("some_id").attr_b)。这是我用来为变量/属性设置新值的函数(var_name 是变量的字符串名称,new_val 是我尝试设置的值):

def icmod_set_var_val(var_name, new_val): # e.g var_name is avatar.skills["combat"].level
    _list = var_name.split('.')
    o = globals()[_list[0]] # e.g <store.Avatar object at 0x0000000029388880>
    if len(_list) == 1:
        o = new_val
    elif len(_list) == 2:
        setattr(o, _list[1], new_val)
    elif len(_list) == 3:
        between_quotes = _list[1].split('"')[1::2][0] # e.g combat
        first_attr = _list[1].split('[')[0] # e.g skills
        _x = getattr(o, first_attr)[between_quotes] # e.g <store.Skill object at 0x00000000293883a0>
        setattr(_x, _list[2], new_val) # e.g _list[2] is level
    else:
        msgs.show('Something went wrong')

它不起作用。当我使用类似的函数来显示修改的值(使用 getattr)时,它们显示正确。但是当我使用控制台或保存游戏并再次打开它时,我可以看到这些值实际上没有改变。我什至尝试使用 exec 来更改值,但这似乎也没有永久效果。那么我在这里做错或遗漏了什么?

e:这似乎是一个 Ren'Py 问题,脚本本身按预期工作(除了 len(_list) == 1 c 部分)。当我打开控制台而不退出 mod 屏幕时,值会发生更改。当我退出模组时,屏幕变化就消失了。


问题出在 Ren'Py 如何处理游戏变量及其与 Python 作用域的交互。

当你修改 store 对象上的属性时,实际上是在修改一个代理对象,而不是实际的游戏变量。这些代理对象在 Ren'Py 引擎更新游戏状态时会被同步。因此,当你退出 mod 屏幕时,Ren'Py 引擎会用之前保存的游戏状态覆盖你的更改。

要解决此问题,你需要使用 Ren'Py 提供的 API 来修改游戏变量。 renpy.store 模块提供了访问和修改游戏变量的功能。

以下是如何使用 renpy.store 模块修改游戏变量的修改后的代码:

import renpy

def icmod_set_var_val(var_name, new_val):
    try:
        # 获取变量名对应的 Python 对象路径
        parts = var_name.split('.')
        obj = renpy.store
        for part in parts[:-1]:
            if '[' in part:
                # 处理字典或列表索引
                key = part.split('[')[0]
                index = int(part.split('[')[1][:-1])  # 提取索引
                obj = getattr(obj, key)[index]
            else:
                obj = getattr(obj, part)

        # 设置变量值
        setattr(obj, parts[-1], new_val)

    except Exception as e:
        msgs.show(f'Error setting variable: {e}')

代码解释:

  1. 导入 renpy 模块。
  2. 使用 renpy.store 访问游戏变量的根对象。
  3. 逐级解析变量名,并使用 getattr 获取对应的属性。
  4. 如果遇到 [] ,则表示访问字典或列表元素,使用相应的索引进行访问。
  5. 最后,使用 setattr 设置最终属性的值。

通过使用 renpy.store 模块,你的更改将直接应用于游戏变量,并将在游戏保存和加载时持久化。

注意:

  • 确保你的 mod 在 Ren'Py 游戏启动后加载。
  • 某些游戏变量可能受到游戏逻辑的保护,无法直接修改。

标签:python,setattr,renpy
From: 78757365

相关文章

  • Python/Flask mysql 游标:为什么它不起作用?
    fromflaskimportFlaskfromflask_mysqldbimportMySQLapp=Flask(__name__)app.config['MYSQL_HOST']='localhost'app.config['MYSQL_USER']='root'app.config['MYSQL_PASSWORD']='password'a......
  • Python pandas to_csv 导致 OSError: [Errno 22] 参数无效
    我的代码如下:importpandasaspdimportnumpyasnpdf=pd.read_csv("path/to/my/infile.csv")df=df.sort_values(['distance','time'])df.to_csv("path/to/my/outfile.csv")此代码成功从infile.csv(一个3GBcsv文件)读取数据,对其进行排......
  • 从 python 中的字符串列表中提取 def 定义函数的标签
    我想使用Python中的正常def过程创建函数,并将标签分配给从字符串列表中提取的命名空间。如何实现这一点?这个问题的动机:我正在创建一个与sympy兼容的python函数库,供数学家用于符号计算实验。许多函数需要初始化具有相关标签的多个对象的系统,这些标签分别由用户提供的字......
  • 在 Raspberry Pi 4 上使用 Python 从具有 SPI 连接的 MT6816 磁性编码器读取
    我对这个领域完全陌生,并不真正知道自己在做什么并且需要帮助。我正在尝试使用MT681614位磁性编码器通过RaspberryPi的SPI连接读取绝对角度。我有以下问题:在硬件方面,是否只是简单地连接必要的连接(3.3V、MOSI、MISO、SCK、GND、CE01)?对于编码......
  • PythonW 不运行脚本。严重地
    因此,使用Windows10和Python3.6。我创建了一个.py脚本,它可以使用命令pythonmyscript.py在命令提示符下正常运行,但是当我制作该脚本的精确副本并为其赋予扩展名.pyw,并尝试使用pythonw运行它时命令pythonwmyscript.pyw,什么也没有发生......
  • 如何使用Python和Selenium模拟产品购买以获取库存信息
    我正在开发一项网络抓取服务,主要针对时尚行业。我的目标是提供有关产品的全面数据,包括库存水平。为了实现这一目标,我需要模拟购买以确定每种尺寸的产品的最大可用数量。我一直在使用Python和Selenium进行网络抓取部分,但在准确模拟购买方面面临着挑战检索股票信息的过程。......
  • 连接Python套接字的问题
    当我写“关闭”时,我试图让我的电报机器人关闭计算机。我不想将机器人连接到网站上的托管。我选择我的手机(AndroidRedmiNote10)作为托管。我在上面安装了Termux和Pydroid。我写了两个文件:main到我的电脑,client到我的手机。通过在计算机上运行这两个文件,一切正常。但是,当我在......
  • 如何修复导入 Numexpr Python 时的错误
    在Windows10Python3.7.9(IDLE)上,我成功安装了“pipinstallnumexpr”,但在“importnumexprasne”时出现错误:Traceback(最近一次调用):文件“<pyshell#21>”,第267行,位于将numexpr导入为ne文件“C:\Python379\lib\site-packages\numexpr_init_.py”......
  • 让 cpython 优化恒定条件
    我正在用Python编写需要尽可能高效运行的代码,但有时我需要深入挖掘调试语句。不要注释这些输入或输出(或者使用外部预处理器来处理代码,就像这里建议的那样Python相当于#ifdefDEBUG或这里如何在python中实现“#ifdef”?|||)我想在模块的开头定义一个变量......
  • 如何使用 for 循环在 python jupyter 笔记本中创建动态图?
    我正在学习本课关于用Python求解热方程。该课程指出,在求解热方程后,我们可以通过在循环中简单地调用pyplot.plot()来可视化解的动画图,其中下面的代码将动态绘制每次每个点的温度,从而得到一个动画情节(课程帖子中提供了动画情节的示例)。importnumpyfrommatplotlibi......