【问题标题】:KeyError on Linux but not WindowsLinux 上的 KeyError,但 Windows 上没有
【发布时间】:2018-08-03 10:43:03
【问题描述】:

我有一个奇怪的情况:

class SomeClass(object):
    def __init__(self, data):
        self.data = {}
        self.data = data
        old_data_name = "SOURCE" # self.data[old_data_name] = a list of values
        try:
           self.data[old_data_name] = [1,2,3,4]
        except Exception as e:
           print(str(e))
        new_data_name = "NEW" # a name
        self.data[new_data_name] = numpy.mean(self.data[old_data_name])

所以这段代码在 Windows 上完美运行 - 我已经逐条调试了这条语句并验证了它。 当我将代码部署到 linux 服务器上时。它给我一个KeyError: old_data_name

我确信数据正在进入不应该发生关键错误的地步。 为什么 python 在 Linux 和 Windows 上的行为如此不同?

【问题讨论】:

  • 你确定操作系统有这个问题吗?你在两台机器上使用的 python 版本是什么?
  • 两个版本都是 3.6 - linux 完全跳过了 try 代码。没有任何例外。它在 Windows 中运行良好。我正在使用 Ubuntu 16.04 pip3 python3。 Windows 环境为 10
  • 您也可以在 try-catch 块中检查 old_data_name,但之后您只需在 numpy.mean(self.data[old_data_name]) 中获取它。
  • @LevZakharov 问题不在于检查。问题是在 Ubuntu 中它完全跳过了 try: 代码(我认为这是一个特定于平台的错误)
  • KeyError: old_data_name 意味着您的代码正在执行与self.data["old_data_name"] 等效的操作。 KeyError 给出了无法找到的键的值,不是它存储的变量的名称。

标签: python python-3.x windows-10 ubuntu-16.04 keyerror


【解决方案1】:

您不应该在 try-catch 块之外从 self.data 获取 old_data_name 的值,因为如果没有这样的键,您会打印错误,而不是尝试通过该键获取某些内容。这是错的。你应该这样写:

class SomeClass(object):
    def __init__(self, data):
        self.data = {}
        self.data = data
        old_data_name = "SOURCE" # self.data[old_data_name] = a list of values
        try:
            self.data[old_data_name] = [1,2,3,4]
            new_data_name = "NEW" # a name
            self.data[new_data_name] = numpy.mean(self.data[old_data_name])
        except Exception as e:
            print(str(e))

【讨论】:

  • 我按照你的建议做了,但在 Ubuntu(我的部署)上仍然得到 KeyError,但在 Windows 上没有
  • 好的,你将data 传递给你的构造方法吗?
  • 它是一个字典 {old_data_name: [1,2,3]} - 有趣的是我在 Visual Studio 上调试,我可以看到数据进来。但 Linux 仍然抛出一个 KeyError。也许我应该尝试在 Linux 中调试数据源
  • 是的,尝试在你的 Linux 服务器上调试它。我确定您错过了平台以外的某些内容和问题。
【解决方案2】:

我的第一印象是版本不匹配:

@Basic 感谢 Basic 这个问题确实是版本不匹配。视觉的 Windows 上的 Studio 默认为 3.6,而 Ubuntu 强制使用 3.5.2 不是 知道有如此巨大的突破性变化只是从一个小修改 来自蟒蛇。看起来很乱。

但经过进一步调查。它显示,与 3.6.6 相比,python 3.5.2 版本读取 json 文件的方式很奇怪 本质上,我加载数据的方式意味着它会自我引用曾经加载过的属性。例如:

{properties: {"stuff": "do this", "stuff2": "do another with @stuff" }}

我的代码在 stuff2 中寻找东西,但从未加载过东西

Python 3.5.2 版没有将 json 数据加载到字典的特定顺序,这会导致问题。

Python 3.6.6 修复了这个问题。

【讨论】:

  • 只有在出现错误时才应该跳过 Try。您可以将 try/except 取出并强制 python 在此时失败,但是您打印出来的错误消息应该告诉您确切的问题是什么。您也可以在尝试为其分配值之前尝试打印出 self.data 行。最后,您确定在两个环境中运行相同版本的 Python 吗?他们是否安装了所有相同的软件包?
  • 我现在正在检查它。 Visual Studio 通过 3.6 强制执行,而 linux 默认为 3.5.2。也许这可能是罪魁祸首。不,没有错误或异常
猜你喜欢
  • 1970-01-01
  • 2019-02-23
  • 2022-01-23
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多