Python TypeError: аргумент типа «NoneType» не является итерируемым

Итак, для моего первого большого проекта на Python я создаю текстовую игру. Предполагается, что он будет модульным, поэтому историю, элементы и т. д. можно редактировать и заменять с небольшим редактированием фактического исходного кода. По сути, пользовательская команда хранится в виде строки, которая сразу же разбивается на список. Первый элемент — это действие, такое как «проверить», а второй элемент — это псевдоаргумент для этого действия, например, «местоположение» или «предмет». После того, как команда интерпретирована, она переходит к исполнительному модулю с именем «item_or_loc». Именно здесь я получаю сообщение об ошибке. Кто-нибудь может помочь? Я предоставлю дополнительную информацию или весь исходный код, если это поможет.

Командный модуль:

    def item_or_loc(iolo):
        if iolo in items.items_f():
            print (items.iolo(1))
        elif iolo in locations.locations_f():
            print (locations.iolo(1))
        else:
            print ('Command not recognized, try again.')


    def location(loco):
        plo_l = PlayerClass #(player location object_location)
        if loco == 'location':
            plo_l.player_loc(0)


    def abort(abo):
        sys.exit()


    def inventory(invo):
        pio_i = PlayerClass #(player inventory object_inventory)
        if invo == 'inventory':
            pio_i.player_inv(0)

Модуль предметов:

    patient_gown=('Patient gown', 'A light blue patient\'s gown.')
    wrench=('Wrench','')
    stick=('Stick','')
    prybar=('Prybar','')
    screwdriver=('Screwdriver','')
    scalpel=('Scalpel','')
    broken_tile=('Broken tile','')
    hatchet=('Hatchet','')
    janitor_suit=('Janitor suit','')

Модуль «Местоположения»: в основном такой же, как модуль «Предметы».

Модуль плеера:

    import items
    import locations

    class PlayerClass:
        def player_inv(inv_index):
        pinventory = [items.patient_gown[inv_index]]
        print (pinventory)

    def player_loc(loc_index):
        ploc = [locations.cell[loc_index]]
        print (ploc)

person SciurusDoomus    schedule 13.04.2012    source источник
comment
Было бы очень полезно предоставить больше контекста в виде исходного кода. Трудно помочь вам много с одним только этим.   -  person Nolen Royalty    schedule 14.04.2012
comment
Сколько ты хочешь? Весь модуль command.py?   -  person SciurusDoomus    schedule 14.04.2012
comment
Хотя бы объяснение, откуда берется items.   -  person Nolen Royalty    schedule 14.04.2012
comment
@DavidHeffernan, это многое ясно, но для отладки проблемы необходимо знать, откуда берутся элементы, чтобы мы могли понять, почему это None ...   -  person Nolen Royalty    schedule 14.04.2012
comment
@Nolen ясно для вас и меня, но, возможно, не тот, кто задал вопрос. Если бы это был вопрос, почему items.items_f() возвращает None.   -  person David Heffernan    schedule 14.04.2012
comment
В принципе, Дэвид Хеффернан прав, но тем не менее было бы неплохо увидеть определение items.items_f. Возможно, мы сможем сказать вам, откуда берется ошибка.   -  person senderle    schedule 14.04.2012
comment
Это здесь. И да, я хотел бы получить объяснение, потому что я сценарист. Я начал изучать Python... три дня назад? Ага. У меня есть небольшой опыт в oop, но не большой.   -  person SciurusDoomus    schedule 14.04.2012
comment
Итак, грязный код, ваш items_f() ничего не возвращает.   -  person pylover    schedule 14.04.2012
comment
Не надо грубить, я вообще новичок в программировании.   -  person SciurusDoomus    schedule 14.04.2012
comment
Кстати, этот класс, вероятно, делает не то, что вы думаете. У вас есть все атрибуты как атрибуты класса - это означает, что они являются общими для каждого экземпляра, а не уникальными для одного объекта. Кроме того, если вы используете python2, обязательно сделайте его классом нового стиля (наследуйте от object - class Player(object)). Неясно, как вы написали свои print утверждения.   -  person Daenyth    schedule 14.04.2012
comment
Честно говоря, это было просто то, что я пытался заставить это работать. Класса больше нет, а items.py просто полон списков. Спасибо за вклад, хотя, я ценю это.   -  person SciurusDoomus    schedule 14.04.2012


Ответы (1)


Вы ничего не возвращаете от items.items_f. Вам нужно вернуть контейнер или последовательность. Я бы посоветовал другой подход из приведенных ниже, но это, по крайней мере, начало.

def items_f():
    patient_gown=('Patient gown','A light blue patient\'s gown.')
    wrench=('','')
    stick=('','')
    crowbar=('','')
    screwdriver=('','')
    scalpel=('','')
    broken_tile=('','')
    hatchet=('','')
    janitor_suit=('','')
    return (patient_gown, wrench, stick, crowbar, 
            screwdriver, scalpel, broken_tile, hatchet, janitor_suit)

Чтобы объяснить, items_f - это не сам контейнер, а скорее функция (или, точнее, метод, который вы можете рассматривать просто как функцию, "прикрепленную" к объекту). Функции не должны что-либо возвращать, но когда вы их вызываете, результатом вызова является просто None.

Теперь, когда вы выполняете такой тест, как if x in y:, y должен быть типом последовательности или контейнера; и поскольку вы проверяете результат функции items_f, и поскольку эта функция возвращает None, как вы определили ее выше, тест выдает ошибку.

Лучший способ справиться с этой ситуацией действительно зависит от большей структуры программы. Первый шаг в правильном направлении может быть примерно таким:

def items_f():
    return (('Patient gown', 'A light blue patient\'s gown.'),
            ('Wrench', 'A crescent wrench.'),
            ('Stick', '...'))

Но это, наверное, тоже не лучшее решение. Мое предложение, основанное на том, что вы добавили выше (в котором, кстати, теперь отсутствует функция items_f), будет заключаться в использовании какой-либо структуры данных, которая содержит элементы. Простым подходом будет словарь:

items = {'patient_gown':('Patient gown', 'A light blue patient\'s gown.'),
         'wrench':('Wrench', '...'),
          ...
        }

Это создает словарь, который содержит все возможные элементы. Теперь, когда вам нужен определенный предмет, вы можете получить его так:

item = items['patient_gown']

Таким образом, вам вообще не нужна функция; вы можете просто получить доступ ко всему словарю напрямую.

person senderle    schedule 13.04.2012
comment
Удаляю мой ответ, так как нет особого смысла в том, чтобы двое из нас говорили одно и то же. - person David Heffernan; 14.04.2012
comment
Ну, я имею в виду, что я бы предпочел не вводить все имена списка элементов в кортеж, список или что-то еще. (Я вижу, что кортеж, вероятно, был бы лучше, поскольку он неизменяем.) - person SciurusDoomus; 14.04.2012
comment
@DavidHeffernan, извините, я растоптал ваш ответ; Я просто увидел возможность добавить больше информации и сделал это, не задумываясь. - person senderle; 14.04.2012
comment
@senderle Все в порядке. Вы поддержали это, оставаясь с вопросом и добавляя все больше и больше. Отличная работа. +1. - person David Heffernan; 14.04.2012
comment
Ну, я попытался добавить функцию возврата внизу, но это разрушает команду «инвентарь», которая в основном печатает инвентарь игрока. Этот инвентарь хранится в модуле player.py и наследует списки предметов от items.py. Когда я пробую «инвентарь», он говорит AttributeError: объект «кортеж» не имеет атрибута «patient_gown». По сути, я хочу иметь возможность набирать «инвентарь» и распечатывать список инвентаря игрока. Я одновременно хочу ввести «проверить ‹элемент›» и получить описание (индекс 1) этого элемента. - person SciurusDoomus; 14.04.2012
comment
@SciurusDoomus, я думаю, мне нужно больше понять, что такое items.py. Это просто модуль, содержащий все возможные элементы? - person senderle; 14.04.2012
comment
Да, это так. Вы хотите, чтобы я загрузил тексты для всех задействованных модулей? Это будет включать модуль команд (получает аргументы от command_interpreter), модуль предметов, модуль игрока и модуль местоположения. - person SciurusDoomus; 14.04.2012
comment
Мне нужно 20 повторений, а у меня их нет, хахаха. Извиняюсь. Все есть в исходном посте... - person SciurusDoomus; 14.04.2012
comment
@SciurusDoomus, тогда извини. Я добавил еще некоторые детали. Обратите внимание, что вам, вероятно, следует заменить функцию items_f на items.py, чтобы исходный вопрос не потерял своего значения. - person senderle; 14.04.2012
comment
@senderle Большое спасибо, это действительно полезно. Я рад, что проблема была в структуре моих списков, а не в остальной части программы. Я ценю вашу помощь. - person SciurusDoomus; 14.04.2012