copcin 2021-12-26 15:25 采纳率: 100%
浏览 120
已结题

为什么isinstance(子类实例,父类)结果是False?

问题遇到的现象和发生背景

最近开发了一个图形编程模块,叫RollTk,是基于Tkinter的。然后我用一个五子棋游戏程序测试了一下,在检测传入的img参数是不是图片列表时,用到了isinstance(img,ImageList)方法,最后报错(即是返回了False)

问题相关代码

程序结构图:

img

五子棋主程序(chess.py)部分源码:

......
# 定义常量
MATRIX_WIDTH=30
BLOCK_WIDTH=20
YELLOW=0
BLACK=1
WHITE=2
SPEED=0.01
WIN=1
LOSE=0

# 棋子图像列表
class ChessImageList(image.ImageList):
    def __init__(self):
        image.ImageList.__init__(self,[
            "RollTk/PhotoBase/yellow.gif",
            "RollTk/PhotoBase/black.gif",
            "RollTk/PhotoBase/white.gif"])

    def update(self,color):
        if color in [YELLOW,BLACK,WHITE]:
            self.sprite.canvas.canvas.itemconfig(self.image,image=self.imageList[color])

class Chess(sprite.Sprite):
    def __init__(self,controller,coordinate,color):
        # 出错行
        super().__init__(controller,ChessImageList(),coordinate)
        self.color=color

    def update(self):
        self.img.update(self.color)
        self.getRealCoords(isReturn=False)

# 棋盘控制器,控制键盘输入输出
class ChessController(canvas.Controller):
    def __init__(self,canvas:canvas.Canvas):
        super().__init__(canvas)
        self.canvas.canvas.bind_all("<Button-1>",self.toButton)

    # 按下鼠标事件
    def toButton(self,event):
        global matrix,turn,realPoint
        mousePos=point.Point(event.x,event.y)
        mousePos.update(mousePos.x//BLOCK_WIDTH,mousePos.y//BLOCK_WIDTH)
        matrix[mousePos.x][mousePos.y]=turn
        if turn==BLACK:
            turn=WHITE
        else:
            turn=BLACK
        realPoint=point.Point(mousePos.x,mousePos.y)

    # 得到可渲染的棋盘,程序运行时要用这个键盘来渲染图像
    def getChessRention(self):
        global matrix
        chessRentionList=[]
        for i in range(MATRIX_WIDTH):
            newList=[]
            for j in range(MATRIX_WIDTH):
                # 在此行生成Chess棋子对象时出错
               chess=Chess(self,coords.Coords(i*BLOCK_WIDTH+1,j*BLOCK_WIDTH+1,(i+1)*BLOCK_WIDTH,(j+1)*BLOCK_WIDTH),matrix[i][j])
               newList.append(chess)
            chessRentionList.append(newList)
        return chessRentionList
......

精灵类定义文件(sprite.py)部分源码:

......
class Sprite:

    # 初始化精灵
    def __init__(self,controller,img,coordinate,direction=90):
        self.canvas=controller.canvas
        self.controller=controller
        self.coordinate:coords.Coords=coordinate
        self.direction=direction
        self.img=img
        if not self.canBlit():
            raise ImageCannotBlitException("Image can't blit.")
        if self.isImageList():
            self.img.bind(self)
        self.width=self.coordinate.x2-self.coordinate.x1
        self.height=self.coordinate.y2-self.coordinate.y1
        self.controller.spriteList.load(self)
        self.realx=0
        self.realy=0
        self.current_image=0
        self.last_time=time.time()

    # 设定位置:X1,Y1,X2,Y2
    def _getx1(self):return self.coordinate.x1
    def _setx1(self,x1):self.coordinate.x1=x1
    X1=property(_getx1,_setx1)

    def _gety1(self):return self.coordinate.y1
    def _sety1(self,y1):self.coordinate.y1=y1
    Y1=property(_gety1,_sety1)

    def _getx2(self):return self.coordinate.x2
    def _setx2(self,x2):self.coordinate.x2=x2
    X2=property(_getx2,_setx2)

    def _gety2(self):return self.coordinate.y2
    def _sety2(self,y2):self.coordinate.y2=y2
    Y2=property(_gety2,_sety2)

    def canBlit(self):
        if self.isFigure() or self.isImage() or self.isImageList():
            return True
        return False

    def isFigure(self):
        if isinstance(self.img,image.Figure):
            return True
        return False

    def isImage(self):
        if isinstance(self.img,image.Image):
            return True
        return False

    def isImageList(self):
         # 此行返回False
        if isinstance(self.img,image.ImageList):
            return True
        return False
......

图像类定义文件(image.py)部分源码:

......

class ImageList:
    def __init__(self,imageList):
        self.imageList=[]
        for i in range(len(imageList)):
            self.imageList.append(PhotoImage(imageList[i]))
        self.width=self.imageList[0].width
        self.height=self.imageList[0].height
        self.currentImage=0
        self.currentImageAdd=1

    def bind(self,sprite):
        self.sprite=sprite
        self.canvas=self.sprite.canvas
        self.image=self.canvas.canvas.create_image(self.sprite.coordinate.x1,self.sprite.coordinate.y1,anchor=NW,image=self.imageList[0])

    def update(self,speed=0.1):
        if self.x!=0 and self.y==0:
            if (time.time()-self.sprite.last_time)>speed:
                self.sprite.last_time=time.time()
                self.currentImage+=self.currentImageAdd
                if self.currentImage>=2:
                    self.currentImageAdd=-1
                if self.currentImage<=0:
                    self.currentImageAdd=1
        self.sprite.canvas.itemconfig(self.image,image=self.imageList[self.currentImage])
......
报错内容

报错内容:

Traceback (most recent call last):
  File "e:\Program\Python\chess\chess.py", line 189, in <module>
    rention=controller.getChessRention()
  File "e:\Program\Python\chess\chess.py", line 61, in getChessRention
    chess=Chess(self,coords.Coords(i*BLOCK_WIDTH+1,j*BLOCK_WIDTH+1,(i+1)*BLOCK_WIDTH,(j+1)*BLOCK_WIDTH),matrix[i][j])
  File "e:\Program\Python\chess\chess.py", line 29, in __init__
    super().__init__(controller,ChessImageList(),coordinate)
  File "e:\Program\Python\chess\RollTk\standard\sprite.py", line 16, in __init__
    raise ImageCannotBlitException("Image can't blit.")
RollTk.standard.image.ImageCannotBlitException: Image can't blit.
  • 写回答

1条回答 默认 最新

  • 关注
     def canBlit(self):
            if self.isFigure() or self.isImage() or self.isImageList():
                return True
            return False
    

    这个函数调用的三个函数都返回了False
    所有函数都没有满足要求,你检查一下是否传入数据正确

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月27日
  • 已采纳回答 12月27日
  • 创建了问题 12月26日

悬赏问题

  • ¥15 Jenkins+k8s部署slave节点offline
  • ¥15 微信小游戏反编译后,出现找不到分包的情况
  • ¥15 如何实现从tello无人机上获取实时传输的视频流,然后将获取的视频通过yolov5进行检测
  • ¥15 WPF使用Canvas绘制矢量图问题
  • ¥15 用三极管设计一个单管共射放大电路
  • ¥15 孟德尔随机化r语言运行问题
  • ¥15 pyinstaller编译的时候出现No module named 'imp'
  • ¥15 nirs_kit中打码怎么看(打码文件是csv格式)
  • ¥15 怎么把多于硬盘空间放到根目录下
  • ¥15 Matlab问题解答有两个问题