TypeError:调用键函数时“NoneType”对象不可迭代

Posted

技术标签:

【中文标题】TypeError:调用键函数时“NoneType”对象不可迭代【英文标题】:TypeError: 'NoneType' object is not iterable when calling keys function 【发布时间】:2015-08-02 12:10:06 【问题描述】:

我收到错误 xShift, yShift = Manager.movementKeys(self, xShift, yShift) TypeError: 'NoneType' object is not iterable 当我运行我的代码时,我不知道为什么。我不应该得到任何回报,因为 None 并且我的论点都不是 None。对于任何缩进错误,我深表歉意。

import pygame, sys, time, os
from pygame.constants import QUIT, KEYDOWN, K_LEFT, K_RIGHT, K_RETURN,            

FULLSCREEN, K_w, K_s, K_a, K_d

global screenWidth, screenHeight

surface = pygame.display.set_mode((0,0),pygame.FULLSCREEN)
width = pygame.display.Info().current_w
height = pygame.display.Info().current_h
screenWidth = width - (width % 25)
screenHeight = height - (height % 25)

class Manager:
    def update(self, startTime):
        curTime = time.time()
        if curTime - float(startTime) >= 1/60:
            pygame.display.update()
        return time.time()
    def render(self, images):
        rendered = []
        for i in images:
            rendered.append(pygame.image.load(i))
        return rendered
    def draw(self, renderedImages, positions):
        for i in range(len(renderedImages)):
            surface.blit(renderedImages[i], (positions[0][i],positions[1]    
[i]))
    def __init__(self):
        state = MenuState()
    def getLevel(self):
        saves = open("save.txt", "r")
        level = saves.readline()
        saves.close()
        return level
    def movementKeys(self, vx, vy):
        if pygame.key.get_pressed()[K_w]:
            xShift, yShift = Manager.movement(self, "w", vx, vy)
            return xShift, yShift
        elif pygame.key.get_pressed()[K_a]:
            xShift, yShift = Manager.movement(self, "a", vx, vy)
            return xShift, yShift
        elif pygame.key.get_pressed()[K_s]:
            xShift, yShift = Manager.movement(self, "s", vx, vy)
            return xShift, yShift
        elif pygame.key.get_pressed()[K_d]:
            xShift, yShift = Manager.movement(self, "d", vx, vy)
            return xShift, yShift
    def movement(self, pressedKey, vx, vy):
        if pressedKey == "w":
            dy = -0.01
            if vy > -1:
                vy += dy
        elif pressedKey == "s":
            dy = 0.01
            if vy < 1:
                vy += dy
        else: 
            dy = 0
        if pressedKey == "d":
            dx = 0.01
            if vx > -1:
                vx += dx
        elif pressedKey == "a":
            dx = -0.01
            if vx < 1:
                vx -= dx
        else:
            dy = 0
        if dy == 0:
            if vy > 0:
                vy -= dy
            elif vy < 0:
                vy += dy
        if dx == 0:
            if vx > 0:
                vx -= dy
            elif vx < 0:
                vx += dy
        return vx, vy
class TileMap:
    def getLevelMap(self, level):
        map = []
        levelFile = level + ".txt"
        file = open(levelFile, "r")
        x = file.readline() 
        y = file.readline()
        for i in range(int(y)):
            line = file.readline()
            curLine = list(line)
            if i != (int(y)-1):
                curLine.pop()
            map.append(curLine)
        file.close()
        return map
    def drawMap(self, map, tiles, xShift, yShift):
        for i in range(len(map)):
            for j in range(len(map[0])):
                surface.blit(tiles[int(map[i][j])], (j * 25 + xShift,i * 25  
+ yShift))
class MenuState:
    global surface
    if surface.get_flags() & FULLSCREEN:
        os.environ["SDL_VIDEO_CENTERED"] = "1"
        surface = pygame.display.set_mode((800,600), pygame.NOFRAME)
    def focusedButton(self, curButton):
        if curButton:
            curButton = False
        else:
            curButton = True
        return curButton
    def __init__(self):
        images = ["MenuBackground.png", "MenuBackgroundOverlay.png", 
"MenuButton1.png", "MenuButton1Focused.png", "MenuButton2.png", 
"MenuButton2Focused.png","MenuTitle.png"]
        renderedImages = Manager.render(self, images)
        endTime = time.time()
        button1Focused = True
        inMenu = True
        x = 0
        x2 = -2400
        while inMenu:
            imagesToDraw = [renderedImages[0], renderedImages[1], 
renderedImages[1], renderedImages[3], renderedImages[4], renderedImages[6]]
            if button1Focused:
                imagesToDraw[3] = renderedImages[2]
                imagesToDraw[4] = renderedImages[5]
            else:
                imagesToDraw[3] = renderedImages[3]
                imagesToDraw[4] = renderedImages[4]
            positions = [[0,x,x2,180,460,50],[0,0,0,350,350,75]]
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == KEYDOWN:
                    if event.key == K_LEFT or event.key == K_RIGHT:
                        button1Focused = MenuState.focusedButton(self, 
button1Focused)
                    elif event.key == K_RETURN:
                        if button1Focused:
                            state = GameState()
                        else:
                            pygame.quit()
                            sys.exit()
            x += 10
            x2 += 10
            if x >= 800:
                x = x2 - 2400
            if x2 >= 800:
                x2 = x - 2400
            Manager.draw(self, imagesToDraw, positions)
            endTime = Manager.update(self, endTime)
class GameState:
    def __init__(self):
        level = Manager.getLevel(self)
        levelMap = TileMap.getLevelMap(self, level)
        tileImages = ["tile1.png", "tile2.png"]
        tileImages = Manager.render(self, tileImages)
        surface = pygame.display.set_mode((screenWidth, screenHeight), 
pygame.FULLSCREEN)
        endTime = time.time()
        xShift = 0
        yShift = 0
        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
                xShift, yShift = Manager.movementKeys(self, xShift, yShift)
                TileMap.drawMap(self, levelMap, tileImages, xShift, yShift)
                endTime = Manager.update(self, endTime)
start = Manager()

【问题讨论】:

【参考方案1】:

问题出现在您尝试像这样“解包”NoneType 时:

>>> x, y = None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable

所以我们可以得出结论,这个Manager.movementKeys(self, xShift, yShift) 返回None

我猜如果没有按键被按下,你的movementKeys(self, vx, vy) 函数不会返回任何东西,因此返回None

def movementKeys(self, vx, vy):
    if pygame.key.get_pressed()[K_w]:
        xShift, yShift = Manager.movement(self, "w", vx, vy)
        return xShift, yShift
    elif pygame.key.get_pressed()[K_a]:
        xShift, yShift = Manager.movement(self, "a", vx, vy)
        return xShift, yShift
    elif pygame.key.get_pressed()[K_s]:
        xShift, yShift = Manager.movement(self, "s", vx, vy)
        return xShift, yShift
    elif pygame.key.get_pressed()[K_d]:
        xShift, yShift = Manager.movement(self, "d", vx, vy)
        return xShift, yShift

    # try adding this
    return (0, 0)  # when nothing is pressed the shift is 0

【讨论】:

我什至没有从 moveKeys 获得回报。我正在做一些跟踪,当我调用移动函数时它似乎得到了错误。作为参考,我在每个函数(movement 和 movementKeys)的顶部放置了一个 print,并且只有 moveKeys 中的 print 出现了。 嘿,这正是我的帖子所说的。您的 movementKeys 函数中只有 ifelif。因此,如果没有按下任何按钮,该函数不会返回任何内容,这意味着它返回“None”。请参阅我更新的答案以及可能的修复。但请记住,我并没有真正检查您的游戏逻辑。 你说得对,我错过了一些非常重要的东西,但感谢您的帮助【参考方案2】:

问题似乎是在函数内部使用 pygame.key.get_pressed() 而不是直接在主循环中。这是 pygame 的小事,不是吗?

【讨论】:

以上是关于TypeError:调用键函数时“NoneType”对象不可迭代的主要内容,如果未能解决你的问题,请参考以下文章

pycharm 使用 pyside2 TypeError:'NoneType' 对象不可调用

Pandas df.mean() 抛出 TypeError:'NoneType' 对象不可调用或返回空系列

python beautifulsoup4突然TypeError:'NoneType'对象不可调用,但它不是None

Anvil 错误:TypeError:“NoneType”对象不可下标

python"TypeError: 'NoneType' object is not iterable"错误解析

TypeError:“NoneType”对象在函数中不可下标