3

I am creating a text adventure engine, the engine itself is working great but I am trying to implement custom events for game creators with callbacks. I have a main.py file that implements all of the game objects and builds the game. The problem is that I seem to be having trouble accessing the objects after I have instantiated them. have a look at this pseudo example code,

import engine

def build():
    # create new item objects
    key = engine.Item()
    door = engine.Item(a = 0)

    # set state of door
    door.locked(requirement = key)

    # CALLBACK FUNCTION
    def on_door_unlock():
        # ACCESSING THE ATTRIBUTE `a` IN `door` WORKS FINE
        door.a = 1
        # ACCESSING THE `key` OBJECT THROWS UnboundLocalError
        del key

    # assign callback to unlock event
    door.on_unlock(on_door_unlock)

build()
engine.run()

My file is obviously much larger than this but it is just as simple and this code isolates my problem. I am able to access the attributes of any object, but when I try to use del keyword on an object itself I get UnboundLocalError: local variable 'key' referenced before assignment

  • my callback function is written after the creation of the key object
  • my callback is assigned to an event after the function is written
  • I can access object attributes but can't access object itself.

everything seems to be placed in order. So what is the problem? How can i write callback functions that can access instances of the objects I create?

7
  • key is not local (and del is not that idiomatic in Python because most people would ratter use a shared object or collection as a container instead of a function's namespace). Commented Jan 11, 2019 at 16:59
  • Then why am I able to access the attributes of door because it is not local either. Commented Jan 11, 2019 at 17:01
  • 3
    You can access it because scope in Python resolves according to the LEGB Rule (local, enclosing, global, builtin) but del is concerned only with the local scope. Commented Jan 11, 2019 at 17:03
  • 1
    del key means no more or less than "remove the name key from the local scope". But this symbol has never been brought into the local scope of on_door_unlock and even if it had, removing it from there would not do anything to the scope of build. Commented Jan 11, 2019 at 17:09
  • 2
    If you're attempting to say "this key has been used, destroy it" you may need to this more in terms of a property of player, or the player's inventory, and reduce the "key count" to 0. Commented Jan 11, 2019 at 17:11

1 Answer 1

2

del key means no more or less than "remove the name key from the local scope". But this symbol has never been brought into the local scope of on_door_unlock and even if it had, removing it from there would not do anything to the scope of build.

One of many better approaches would be to create an explicitly-named registry of objects, for example as a dict called all_objects. Create the key inside it. Remove key from it by referring to it by name in your function.

ALL_OBJECTS = {}

def build():
    ALL_OBJECTS[ 'copperKey' ] = engine.Item()

    ...

    def on_door_unlock():

        del ALL_OBJECTS[ 'copperKey' ]
        ...
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.