尝试理解一个错误 - wintypes.Structure

0 投票
1 回答
1398 浏览
提问于 2025-04-17 21:32

我需要帮助来搞清楚这件事。
昨天我在我的Win7 64位笔记本上安装了Spyder 2.3的测试版,准备使用Anaconda Python 3.3。
打开一个内部控制台窗口时,我注意到每秒都会出现一个错误,

Traceback (most recent call last):
File "C:\Miniconda3\lib\site-packages\spyderlib\widgets\status.py", line 80, in update_label
  self.label.setText('%d %%' % self.get_value())
File "C:\Miniconda3\lib\site-packages\spyderlib\widgets\status.py", line 93, in get_value
  return memory_usage()
File "C:\Miniconda3\lib\site-packages\spyderlib\utils\system.py", line 20, in windows_memory_usage
  class MemoryStatus(wintypes.Structure):
AttributeError: 'module' object has no attribute 'Structure'

这个错误似乎是因为system.py试图使用"wintype.Structure",而我的电脑上没有安装psutil。我在wintypes.py里也找不到什么叫Structure的类(或者模块)……甚至c_uint64里也没有。

我用简单的方法解决了这个问题——我直接安装了psutil,问题就解决了。但事实是,有好几个脚本似乎都在使用wintypes.Structure(可以在Google上查到)。而我真的看不到它……我到底漏掉了什么呢?
谢谢!

1 个回答

0

我在编辑我的回答。

这里的问题似乎是,Python 2.7版本的wintypes.py(来自ctypes 1.1.0包)是以
from ctypes import * 开头的。

而Python 3.3版本的wintypes.py则使用:
import ctypes

所以基本上,wintypes.Structure.c_uint64.sizeof.byref这些都是来自ctypes的。它们在中并没有被改变——至少在这个1.1.0版本之前是这样的。因此,对Spyder(2.3.0beta3)的status.py进行这样的修改,应该可以让它在Python 2.7和Python 3.3中都能正常工作,没有错误:

def windows_memory_usage():
    """Return physical memory usage (float)
    Works on Windows platforms only"""
    from ctypes import windll, Structure, c_uint64, sizeof, byref
    from ctypes.wintypes import DWORD
    class MemoryStatus(Structure):
        _fields_ = [('dwLength', DWORD),
                    ('dwMemoryLoad',DWORD),
                    ('ullTotalPhys', c_uint64),
                    ('ullAvailPhys', c_uint64),
                    ('ullTotalPageFile', c_uint64),
                    ('ullAvailPageFile', c_uint64),
                    ('ullTotalVirtual', c_uint64),
                    ('ullAvailVirtual', c_uint64),
                    ('ullAvailExtendedVirtual', c_uint64),]
    memorystatus = MemoryStatus()
    # MSDN documetation states that dwLength must be set to MemoryStatus
    # size before calling GlobalMemoryStatusEx
    # http://msdn.microsoft.com/en-us/library/aa366770(v=vs.85)
    memorystatus.dwLength = sizeof(memorystatus)
    windll.kernel32.GlobalMemoryStatusEx(byref(memorystatus))
    return float(memorystatus.dwMemoryLoad)

撰写回答