简体   繁体   中英

Python 3: Name 'Class instance' not defined

I've been working on a text-based adventure game and currently I'm working on splitting up one large game script I have into separate modules.

This is the main game module containing the game's logic. Within the main() function I have defined instances of classes

from gameworld import *


def main():

    player = Player("Jeff", 100)
    bag = Bag([])
    location = Location('introd')

    command = '  '
    while command != "":
        command = input('>>> ')
        if command in location.room.exits:
            location.travel(command)
        elif command == 'look':
            location.room_desc()
        elif command == '':
            print('You have to say what it is you want to do!')
            command = '#'
        elif command == 'search':
            location.search_room()
        elif command.split()[0] == 'Take':
            bag.check_take(command.split()[1])
        elif command == 'Inventory':
            bag.check_inv()
        else:
            print('Invalid command')


if __name__ == '__main__':
    main()

Below is an excerpt from the gameworld module. It includes the functions that I'm having difficulty with. The Location.key_check and Bag.check_take functions.

#gameworld.py

class Room:

    def __init__(self, name, description, exits, actions, roominv, roomkey, lock):
        self.name = name
        self.description = description
        self.exits = exits
        self.actions = actions
        self.roominv = roominv
        self.roomkey = roomkey
        self.lock = lock

class Location:

    def __init__(self, room):
        self.room = world[room]

    def key_check(self, new_room_name):
        if world[new_room_name].lock and world[new_room_name].roomkey not in bag.inventory:
            self.no_key()
        else:
            world[new_room_name].lock = False
            self.set_room(new_room_name)
            self.room_desc()
class Bag():

    def __init__(self, inventory):
        self.inventory = inventory

    def add_to_inv(self, key):
        self.inventory.append(location.room.roominv[key])
        del location.room.roominv[key]

    def none_here(self, key):
        print("You can't find a", key)

    def check_take(self, key):
        if location.room.roominv and key in location.room.roominv:
            self.add_to_inv(key)
            print('you take the', key)
        else:
            self.none_here(key)

When I run the game, and attempt to pick up an item, I receive this traceback error:

Traceback (most recent call last):
  File "C:\Users\Daniel\Python 3.6\Scripts\PythonPR\PythonPR\FlubbosModuleTest.py", line 31, in <module>
    main()
  File "C:\Users\Daniel\Python 3.6\Scripts\PythonPR\PythonPR\FlubbosModuleTest.py", line 23, in main
    bag.check_take(command.split()[1])
  File "C:\Users\Daniel\Python 3.6\Scripts\PythonPR\PythonPR\gameworld.py", line 81, in check_take
    if location.room.roominv and key in location.room.roominv:
NameError: name 'location' is not defined

I receive a similar error when attempting to move to a locked room and the key_check method runs. When the code is all contained in the same script, it runs fine with no problem accessing these class instances.

You need to pass the location variable when you are calling bag.check_take as an argument as location is not defined and is not in scope inside the Bag class. You need to pass the variable represent other object when you call a class member function.

In the case that you've designed your Bag to have an inventory attribute which you update.

def add_to_inv(self, key):
   self.inventory.append(location.room.roominv[key])
   del location.room.roominv[key]

Nitpick : move the mutation of the room inventory for a location to a manager function. See rest of answer below to get an idea.

You can make check_take into a function that take a key, bag and location. This function can be imported and passed key, bag and location accordingly.

def check_take(key, bag, location=None):
    if location.room.roominv and key in location.room.roominv:
        bag.add_to_inv(key)
    else:
        bag.none_here(key)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM