IronPython.Runtime.UnboundNameException:未定义名称“str”

Posted

技术标签:

【中文标题】IronPython.Runtime.UnboundNameException:未定义名称“str”【英文标题】:IronPython.Runtime.UnboundNameException: name 'str' is not defined 【发布时间】:2019-06-13 17:46:37 【问题描述】:

我正在尝试在 C# 中运行 IronPython 脚本,但有时当我运行它时会出现以下错误:

IronPython.Runtime.UnboundNameException: name 'str' is not defined

我不知道为什么会这样;它只是偶尔发生;现在,当我在游戏中单击一个行星以查看其能力报告时,就会发生这种情况。

这是我要运行的脚本:

'Mines ' + str(Amount1) + ' minerals each turn (modified by planet value).'

如您所见,我正在尝试连接一些字符串,其中一个是字符串化的 Amount1 变量(我认为 Amount1 是数字 800,但它可能是一个更复杂的表达式,等于 800,我必须检查关于那个),但由于某种原因,我收到一个错误,提示 str 函数未定义,这没有任何意义!

在此脚本运行之前还包含其他脚本;如果你愿意,我可以找到这些并将它们粘贴在这里以防万一……

编辑:这是我正在运行的完整脚本:

import sys, imp;
import __builtin__ as builtins;
builtins_code = """""";
exec builtins_code in builtins.__dict__;
import clr
clr.AddReference('System.Core')
import System
clr.ImportExtensions(System.Linq)
clr.AddReference('FrEee.Core')
import FrEee
import FrEee.Utility
clr.ImportExtensions(FrEee.Utility.Extensions)
from FrEee.Modding import Mod
from FrEee.Game.Objects.Space import Galaxy
from FrEee.Game.Objects.Civilization import Empire
'Mines ' + str(Amount1) + ' minerals each turn (modified by planet value).'

exec builtins_code 行可以删除str 函数吗?如果是这样,我如何确保将 builtins_code 添加到内置函数中而不是替换它?

edit2:不,即使我删除了前四行,当我在单人游戏中处理一个回合然后点击我的家乡时它也会崩溃!

edit3:如果我将脚本放在一个文本文件中并作为手表运行它(见下文),它运行得很好,即使在它崩溃的断点上:

FrEee.Modding.ScriptEngine.EvaluateExpression<string>(System.IO.File.ReadAllText("c:/users/edkol/desktop/test.py")), ac

【问题讨论】:

如果它只是偶尔发生:是否有可能在代码的其他地方调用了变量str 我在任何地方都没有看到我定义了一个名为 str...的变量... 我可以在 CPython 3 中以 NameError: name 'str' is not defined 重现您的消息的唯一方法是尝试 del(str),但该消息失败。但是 IronPython 不是 CPython,所以这可能意义不大。很明显,__builtins__ 的模组中发生了一些奇怪的事情,但这并没有告诉你任何你没有怀疑过的事情。 是的,如果我删除前四行并没有真正做任何事情,那么脚本就可以工作。但是,如果我有实际的代码要导入到内置函数中,那将不起作用...... 嗯,如果我执行以下步骤仍然会损坏:1. 开始一个新的单人游戏,2. 处理一个回合,3. 打开星球报告 - 如果我加载游戏时没有正在转弯! 【参考方案1】:

行:

exec builtins_code in builtins.__dict__

只需将_ 添加到交互式环境中,它就会重复最后一个评估的变量。没有那行,_ 就没有定义。请注意,此功能在脚本中不是很有用,可以删除。这似乎与您的问题无关。

看起来 IronPython 的唯一兴趣是能够轻松地与 Microsoft/C# 的东西交互,但它在 2.7 版本中仍然“稳定”,而且它可能不像官方 python 版本那样没有错误(类似的错误是遇到并没有解决on reddit,并不是说它有帮助,但你知道你不是唯一的......)。

必须是一个错误,因为你不能在没有被覆盖的情况下删除一个内置函数:

>>> str
<type 'str'>
>>> del str
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'str' is not defined

现在让我们务实一点:短期内不可能有人修复这个错误。

因此,您可以尝试通过以下方式“恢复”str 名称:

str = __builtins__.get('str')

我没有对此进行测试,也许一旦您处于这种奇怪的状态,它也不会起作用,但是还有其他解决方法可以使用实例和 __class__ 属性来获取“丢失”的类名:

>>> "".__class__(34)   # "".__class__ is str
'34'
>>> 0 .__class__(1.4)   # note the space to help the parser :)
1

唯一的问题是你的代码看起来很奇怪。不要忘记发表评论!

无论如何,您实际上并不需要 str,您可以通过在格式字符串(位置)上使用 str.format 来解决您的问题:

'Mines  minerals each turn (modified by planet value).'.format(Amount1)

或按关键字:

'Mines Amount1 minerals each turn (modified by planet value).'.format(Amount1=Amount1)

该方法不涉及内置的str。并不是说您不会遇到其他问题,但即使str 可用,这也是格式化字符串的一种首选方式。

通过避免此类错误来解决问题。幸运的是,python 异常是显式的,可以通过很好的回溯来捕获。

【讨论】:

等一下是__builtin__ 还是__builtins__?如果我拼错了,也许这让我搞砸了…… 不,两者都与 python 2.7 有关。见***.com/questions/11181519/…。一个是另一个的dict。但是这些行在不交互时是无用的。 嗯,我尝试从__builtins__ 获取str,但我收到一个错误,提示__builtins__ 未定义!也用__builtin__ 尝试过,得到了类似的错误... 至于 format 调用,这会很棘手,因为我是从字符串插值之类的东西生成脚本的,例如"Mines Amount1 minerals per turn"... 检查我上次的编辑,你可以这样做。感谢您的赏金,这是我的第一个!

以上是关于IronPython.Runtime.UnboundNameException:未定义名称“str”的主要内容,如果未能解决你的问题,请参考以下文章