簡體   English   中英

python AttributeError: 'mHID' 對象沒有屬性 'dict'

[英]python AttributeError: 'mHID' object has no attribute 'dict'

我正在嘗試使用 python 進行 makeblock mblock 實現,我在 github 上找到了這個 api,但它使用的是 python 2.7,我使用的是 python 3.8,所以我正在嘗試配置代碼以便它可以在 python 3.8 上運行,但我遇到了錯誤這是 init mBot bot

<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])]

測試文件

這是我正在使用的測試文件

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)

我相信你的麻煩在這里:

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 在這種情況下,如果start()從未被調用過, close()應該怎么做? 為簡單起見,我只是讓它什么都不做,但您可以考慮引發異常。

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.dictself.dictself.dct 雖然以前的名字可能因為self.而在技術上是允許的self. 命名空間, dict實際上是一個內置類。 在各種情況下,您可能會處理陰影。 至少,總是不得不提醒自己“這不是內置的dict ,而是一個實例變量,這是令人困惑的。

(除了可能:您不想從初始化程序中調用start()是否有特殊原因?)

警告:這不是“復制並粘貼答案”的簡單案例。 我在這里說明了一些設計原則,您應該將它們合並到您的代碼的其余部分中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM