python AttributeError:“ mHID”对象没有属性“ dict”

时间:2019-12-17 19:53:55

标签: python

我正在尝试使用python创建makeblock mblock实现,但我在github上找到了此api,但它使用的是python 2.7,而我使用的是python 3.8,所以我尝试配置代码,使其可以在python 3.8上运行,但我运行了变成一个错误     初始化程序     机器人

<lib.mBot.mSerial object at 0x02CE9898>
start with serial


<lib.mBot.mHID object at 0x02E2B310>
self.device = mHID()


'mHID' object has no attribute 'dict'
Exception in thread Thread-2:
self.start()

Traceback (most recent call last):

File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
start with HID


--------------------

    n = self.device.inWaiting()
<lib.mBot.mBot object at 0x002FF640>
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
--------------------

Error in sys.excepthook:
    buf = self.dict.device.read(64)
Traceback (most recent call last):
AttributeError: 'mHID' object has no attribute 'dict'
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 134, in excepthook

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
    self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
    self.device.close()
    self.run()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
    self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'

Original exception was:
Traceback (most recent call last):
File "c:/Users/abdsak11/OneDrive - Lärande/Dokument/GitHub/python-for-mbot/test.py", line 15, in <module>
    self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
    bot.doMove(50,50)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 179, in doMove
    self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
    self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 278, in short2bytes
    self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
    return [ord(val[0]),ord(val[1])]
TypeError: ord() expected string of length 1, but int found
    self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'
'mHID' object has no attribute 'dict'
Exception in thread Thread-1:
Traceback (most recent call last):
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 154, in __onRead
    n = self.device.inWaiting()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 96, in inWaiting
    buf = self.dict.device.read(64)
AttributeError: 'mHID' object has no attribute 'dict'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
File "C:\Users\abdsak11\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 163, in __onRead
    self.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 142, in close
    self.device.close()
File "c:\Users\abdsak11\OneDrive - Lärande\Dokument\GitHub\python-for-mbot\lib\mBot.py", line 106, in close
    self.dict.device.close()
AttributeError: 'mHID' object has no attribute 'dict'

所以我想做的是通过USB COM3串行控制代码并将其上传到我的mbot,这就是我得到的错误,我尝试了一切,但均无法正常工作,而且我似乎无法找出错误的原因

mbot.py

这是我发现的主要api

import serial
import sys,time
import signal
from time import ctime,sleep
import glob,struct
from multiprocessing import Process,Manager,Array
import threading
import hid

class mSerial():
    ser = None
    def __init__(self):
        print (self)

    def start(self, port):
        self.ser = serial.Serial(port,115200)

    def device(self):
        return self.ser

    def serialPorts(self):
        if sys.platform.startswith('win'):
            ports = ['COM%s' % (i + 1) for i in range(256)]
        elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
            ports = glob.glob('/dev/tty[A-Za-z]*')
        elif sys.platform.startswith('darwin'):
            ports = glob.glob('/dev/tty.*')
        else:
            raise EnvironmentError('Unsupported platform')
        result = []
        for port in ports:
            s = serial.Serial()
            s.port = port
            s.close()
            result.append(port)
        return result

    def writePackage(self,package):
        self.ser.write(package)
        sleep(0.01)

    def read(self):
        return self.ser.read()

    def isOpen(self):
        return self.ser.isOpen()

    def inWaiting(self):
        return self.ser.inWaiting()

    def close(self):
        self.ser.close()

class mHID():
    def __init__(self):
        print (self)

    def start(self):
        print ("starting start \n\n")
        self.manager = Manager()
        print("manager pass \n\n")
        self.dict = self.manager.dict()
        print("dict pass \n\n")
        self.dict.device = hid.device()
        print("dict device pass \n\n")
        self.dict.device.open(0x0416, 0xffff)
        print("dict device open pass \n\n")
        self.dict.device.hid_set_nonblocking(self.device,1)
        print ("start")
        self.buffer = []
        self.bufferIndex = 0

    def enumerate(self):
        print ("enumerate")
        for dev in self.dict.device.enumerate():
            print ('------------------------------------------------------------')
            print (dev.description())

    def writePackage(self,package):
        buf = []
        buf += [0, len(package)]
        for i in range(len(package)):
            buf += [package[i]]
        n = self.dict.device.write(buf)
        sleep(0.01)

    def read(self):
        c = self.buffer[0]
        self.buffer = self.buffer[1:]
        return chr(c)

    def isOpen(self):
        return True

    def inWaiting(self):
        buf = self.dict.device.read(64)
        l = 0
        if len(buf)>0:
            l = buf[0]
        if l>0:
            for i in range(0,l):
                self.buffer += [buf[i+1]]
        return len(self.buffer)

    def close(self):
        self.dict.device.close()

class mBot():
    def __init__(self):
        print ("init mBot")
        signal.signal(signal.SIGINT, self.exit)
        self.manager = Manager()
        self.__selectors = self.manager.dict()
        self.buffer = []
        self.bufferIndex = 0
        self.isParseStart = False
        self.exiting = False
        self.isParseStartIndex = 0

    def startWithSerial(self, port):
        self.device = mSerial()
        self.device.start(port)
        self.start()

    def startWithHID(self):
        self.device = mHID()
        print ("self.device = mHID()\n \n")
        self.device.start()
        print ("self.device.start()\n \n")
        self.start()
        print ("self.start()\n \n")

    def excepthook(self, exctype, value, traceback):
        self.close()

    def start(self):
        sys.excepthook = self.excepthook
        th = threading.Thread(target=self.__onRead,args=(self.onParse,))
        th.start()

    def close(self):
        self.device.close()

    def exit(self, signal, frame):
        self.exiting = True
        sys.exit(0)

    def __onRead(self,callback):
        while 1:
            if(self.exiting==True):
                break
            try:    
                if self.device.isOpen()==True:
                    n = self.device.inWaiting()
                    for i in range(n):
                        r = ord(self.device.read())
                        callback(r)
                    sleep(0.01)
                else:   
                    sleep(0.5)
            except Exception as ex:
                print (str(ex))
                self.close()
                sleep(1)

    def __writePackage(self,pack):
        self.device.writePackage(pack)

    def doRGBLed(self,port,slot,index,red,green,blue):
        self.__writePackage(bytearray([0xff,0x55,0x9,0x0,0x2,0x8,port,slot,index,red,green,blue]))

    def doRGBLedOnBoard(self,index,red,green,blue):
        self.doRGBLed(0x7,0x2,index,red,green,blue)

    def doMotor(self,port,speed):
        self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xa,port]+self.short2bytes(speed)))

    def doMove(self,leftSpeed,rightSpeed):
        self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x5]+self.short2bytes(-leftSpeed)+self.short2bytes(rightSpeed)))

    def doServo(self,port,slot,angle):
        self.__writePackage(bytearray([0xff,0x55,0x6,0x0,0x2,0xb,port,slot,angle]))

    def doBuzzer(self,buzzer,time=0):
        self.__writePackage(bytearray([0xff,0x55,0x7,0x0,0x2,0x22]+self.short2bytes(buzzer)+self.short2bytes(time)))

    def doSevSegDisplay(self,port,display):
        self.__writePackage(bytearray([0xff,0x55,0x8,0x0,0x2,0x9,port]+self.float2bytes(display)))

    def doIROnBoard(self,message):
        self.__writePackage(bytearray([0xff,0x55,len(message)+3,0x0,0x2,0xd,message]))

    def requestLightOnBoard(self,extID,callback):
        self.requestLight(extID,8,callback)

    def requestLight(self,extID,port,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x3,port]))

    def requestButtonOnBoard(self,extID,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1f,0x7]))

    def requestIROnBoard(self,extID,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x3,extID,0x1,0xd]))

    def requestUltrasonicSensor(self,extID,port,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x1,port]))

    def requestLineFollower(self,extID,port,callback):
        self.__doCallback(extID,callback)
        self.__writePackage(bytearray([0xff,0x55,0x4,extID,0x1,0x11,port]))

    def onParse(self, byte):
        position = 0
        value = 0   
        self.buffer+=[byte]
        bufferLength = len(self.buffer)
        if bufferLength >= 2:
            if (self.buffer[bufferLength-1]==0x55 and self.buffer[bufferLength-2]==0xff):
                self.isParseStart = True
                self.isParseStartIndex = bufferLength-2 
            if (self.buffer[bufferLength-1]==0xa and self.buffer[bufferLength-2]==0xd and self.isParseStart==True):         
                self.isParseStart = False
                position = self.isParseStartIndex+2
                extID = self.buffer[position]
                position+=1
                type = self.buffer[position]
                position+=1
                # 1 byte 2 float 3 short 4 len+string 5 double
                if type == 1:
                    value = self.buffer[position]
                if type == 2:
                    value = self.readFloat(position)
                    if(value<-255 or value>1023):
                        value = 0
                if type == 3:
                    value = self.readShort(position)
                if type == 4:
                    value = self.readString(position)
                if type == 5:
                    value = self.readDouble(position)
                if(type<=5):
                    self.responseValue(extID,value)
                self.buffer = []

    def readFloat(self, position):
        v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
        return struct.unpack('<f', struct.pack('4B', *v))[0]
    def readShort(self, position):
        v = [self.buffer[position], self.buffer[position+1]]
        return struct.unpack('<h', struct.pack('2B', *v))[0]
    def readString(self, position):
        l = self.buffer[position]
        position+=1
        s = ""
        for i in Range(l):
            s += self.buffer[position+i].charAt(0)
        return s
    def readDouble(self, position):
        v = [self.buffer[position], self.buffer[position+1],self.buffer[position+2],self.buffer[position+3]]
        return struct.unpack('<f', struct.pack('4B', *v))[0]

    def responseValue(self, extID, value):
        self.__selectors["callback_"+str(extID)](value)

    def __doCallback(self, extID, callback):
        self.__selectors["callback_"+str(extID)] = callback

    def float2bytes(self,fval):
        val = struct.pack("f",fval)
        return [ord(val[0]),ord(val[1]),ord(val[2]),ord(val[3])]

    def short2bytes(self,sval):
        val = struct.pack("h",sval)
        return [ord(val[0]),ord(val[1])]

test.py

这是我正在使用的测试文件

from lib.mBot import *

if __name__ == "__main__":
    bot = mBot()
    print ("bot \n\n")
    bot.startWithSerial("COM3")
    print ("start with serial\n\n")
    bot.startWithHID()
    print ("start with HID \n\n")

    print(f'--------------------\n')
    print (bot)
    print(f'--------------------\n')

    bot.doMove(50,50)

1 个答案:

答案 0 :(得分:0)

我相信您的麻烦就在这里

class mHID():
    def __init__(self):
        print (self)

    def start(self):
        # ...
        self.dict = self.manager.dict()
        # ...

    def close(self):
        self.dict.device.close()

即使计划以后再更改它们,也应始终在__init__()中定义实例属性,至少以初始值None定义。

此外,每当遇到必须在A之前调用“ B”的情况时,应编写代码以正确处理在没有B的情况下调用A的情况。 。在这种情况下,如果从未调用过close()start()应该怎么做?为简单起见,我只是不执行任何操作,但您可以考虑引发异常。

class mHID():
    def __init__(self):
        print (self)
        self.dct = None

    def start(self):
        # ...
        self.dct = self.manager.dict()
        # ...

    def close(self):
        if self.dct:
            self.dct.device.close()

您会发现我也将self.dict重命名为self.dct。尽管由于self.命名空间,从技术上来说,前一个名称可能是允许的,但dict实际上是一个内置类。在各种情况下,您都可以处理阴影。至少,总是不得不提醒自己“这不是内置的dict,而是一个实例变量,这让人感到困惑。

(可能的原因:您是否不想从初始化程序调用{​​{1}}的特定原因?)

  

警告:这不是“复制并粘贴答案”的简单情况。我在这里说明了一些设计原则,您应该将它们纳入其余的代码中。