如何处理 Python 中的 NoneType 错误?

How to deal with NoneType error in Python?

我在过去一周才学习编码和 Python,所以这个问题看起来很明显。

我正在尝试制作纸牌游戏。我已经创建了我的一副纸牌,现在我正在尝试创建一个函数来从一副纸牌中取出一张纸牌并测试我是否正在打印一副纸牌。

但是,当我从牌组中随机取出一张牌,然后尝试打印出牌组中剩余牌的属性时,我收到错误消息。 我创建了一个名为 Card 的 class 属性 name、value、suit 我删除了部分很长且不完全相关的代码。 我有一个名为 the_deck 的所有卡片列表 我试图用

来解释错误

"如果 the_deck[i] 是 None:continue:"

但这似乎不起作用。 这是我的代码,然后是错误。

def pick_a_card():
    a = random.choice(the_deck)
    print(a.name + " of " + a.suit)
    the_deck = the_deck.remove(a)
    i = 0
    while i <= 51:
        if the_deck[i] is None:
            continue
        else:
            print(the_deck[i].name + " of " + the_deck[i].suit)
        i+=1
pick_a_card() 

我得到的错误是

类型错误:'NoneType' 对象不可订阅

此错误来自于从牌组中取出一张牌。函数的其余部分没有错误。

我该如何解决这个问题? 谢谢

每个问题的解决方案:

  1. remove() 视为一个动作,而不是解析器
  2. 使用 fstrings 连接字符串数据
  3. 将游戏逻辑与诊断分开
  4. 给事物命名
  5. 使用 for 循环来迭代牌组,这样您就不必担心有多少张牌了

下面的脚本是如何实现解决方案列表的示例

from collections import namedtuple
import random

#a simple deck generator so this example is complete
Card = namedtuple('Card', 'face suit')

def deck_generator():
    faces = [*list(map(str, range(2,11))), 'J', 'Q', 'K', 'A']
    suits = ['♠', '♥', '♦', '♣']
    deck  = []

    for s in suits:
        for f in faces:
            deck.append(Card(f, s))
            
    return deck
    
Deck = deck_generator()
#end deck generator

the_deck = Deck[:] #unique copy so you don't have to keep making the deck

#game logic
def pick_a_card():
    card = random.choice(the_deck)
    the_deck.remove(card) #action not parser
    return card #not 'a'

#diagnostic separated from game logic       
def viewdeck():
    deck = ''
    for card in the_deck: #number of remaining cards is irrelevant
        deck = f'{deck}{card.face}{card.suit}, ' #fstring
    print(deck)
    
        
card = pick_a_card() 
print(f'{card.face}{card.suit}') #fstring
#5♣

viewdeck()  
#2♠, 3♠, 4♠, 5♠, 6♠, 7♠, 8♠, 9♠, 10♠, J♠, Q♠, K♠, A♠, 
#2♥, 3♥, 4♥, 5♥, 6♥, 7♥, 8♥, 9♥, 10♥, J♥, Q♥, K♥, A♥, 
#2♦, 3♦, 4♦, 5♦, 6♦, 7♦, 8♦, 9♦, 10♦, J♦, Q♦, K♦, A♦, 
#2♣, 3♣, 4♣, 6♣, 7♣, 8♣, 9♣, 10♣, J♣, Q♣, K♣, A♣,     

一边

大多数容器类型都有直接作用于容器的内联方法。这些方法可能 return 什么都没有。您可以将此视为告诉容器自行执行的操作。了解内联方法是否具有 return 需要经验或快速浏览一些文档。例如,考虑 remove()append()insert()pop()。所有这些都是内联方法,但只有 pop() returns 数据。

我不确定您的数据是什么样的,但这是一个如何从列表中删除随机数的示例,可能会有帮助。

the_deck = [*range(1, 53, 1)]

def remove_val(the_deck):
    a = random.choice(the_deck)
    the_deck.remove(a)
    print('Value removed:', a)
    print('New deck:', the_deck)

您的示例中的一个注意点是,@alaniwi 指出,不应该重新分配 the_deck = the_deck.remove(a),而是应该读取 the_deck.remove(a)。此外,您没有处理每次移除卡时 len(the_deck) 减少 1 的事实。

remove列表方法通过修改列表删除传递给的元素。也就是说,它只是修改列表名称引用的列表。然而它 returns None。如果function/method中没有return语句,Python解释器returns None.

要检查 remove 方法 returns None,运行 以下代码在 Python 解释器:

>>> a = [1, 2 ,3]
>>> if a.remove(1) == None:
...     print('Returns None')
...

if块将被执行。

如果您尝试索引和 intNone 对象,您还可以检查 Python 将 return 的错误类型。

>>> a = None
>>> a[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable