![]() |
Call a def from a string - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Call a def from a string (/thread-11104.html) |
Call a def from a string - DreamingInsanity - Jun-22-2018 I have a variable called "current" which is the name of the current def you are in. If you lose a life a new def is called. Since rooms are picked at random, I cant just use 'roomname()' to get back to the original room you were in before you lost a life. I need something that assignes current the as the current def name, then calls that variable in the death function like 'current()'. I have tried this: import inspect #this a test def main(): room1() def room1(): global current current = inspect.stack()[0].function dead() def dead(): current() main()but I get an error saying 'TypeError: 'str' object is not callable' Any help on this would be appreciated! Thanks, Dream. RE: Call a def from a string - buran - Jun-22-2018 would you elaborate what you want to do? Maybe show more of your actual code... This sounds really weird... It sounds like really wrong design - e.g. you can always keep the room name you are in (the one picked at random) RE: Call a def from a string - Larz60+ - Jun-22-2018 FYI def has a name it's 'function' or 'method' if part of a class. This is best done by creating a class named Room. Then when you want a room, you instantiate a new class. Dumb Example (but gets the point across (I hope): class Room: def __init__(self): self.current = None def dead(self): self.current = 'Dead' def alive(self): self.current = 'Alive' class MyGame: def __init__(self): self.den = Room() self.den.alive() self.kitchen = Room() self.kitchen.alive() def display_rooms(self): print('\nden is {}'.format(self.den.current)) print('kitchen is {}'.format(self.kitchen.current)) def play(self): print('In the beginning') self.display_rooms() self.den.dead() print('A while later') self.display_rooms() self.den.alive() self.kitchen.dead() print('\nIn the end: ') self.display_rooms() if __name__ == '__main__': game = MyGame() game.play()results:
RE: Call a def from a string - ljmetzger - Jun-22-2018 Python types are dynamically assigned at runtime. You can change the type of a variable many times (not recommended) (e.g. from 'int', to 'float', to 'str', to 'float', ...). However current() is a function call. The Python interpreter in context knows current as type 'str', and you are trying to access current as a function, which is exactly the error message that you see. We probably need a little more detail to give you a definitive answer to your question. Lewis RE: Call a def from a string - volcano63 - Jun-22-2018 Small experiment reveals it all. You get a function name - not a function object. I am not sure that inspect module (have not touched it for a long time) is intended to pass function referencesPS there's a way to use current as you intended - though I would not either call it healthy or recommend it I was not about to get my machine into endless mutual recursion (well, in 3.6 recursion stack depth is about 3000, so what the heck ![]() globals()[current] would have called the function room1
RE: Call a def from a string - nilamo - Jun-22-2018 What about a dict of rooms, and you pick one from there? import random rooms = {} def get_next_room_from(current_room): next_room = None while not next_room or next_room == current_room: next_room = random.choice(list(rooms.keys())) return next_room def entryway(): print("Welcome to the entryway. Bye!") next_room = get_next_room_from("entryway") return next_room def conservatory(): print("This is the conservatory. There's plants and wicker couches here.") next_room = get_next_room_from("conservatory") return next_room rooms["entryway"] = entryway rooms["conservatory"] = conservatory running = True current_room = "entryway" while running: current_room = rooms[current_room]() running = "q" != input("Type 'q' to stop.").lower() RE: Call a def from a string - DreamingInsanity - Jun-23-2018 So it makes more sense, I will post all my code here: **I know that it is messy, (maybe)inefficient, and the use of certain aspects is bad.** import random import time import sys import inspect Answer1 = ["Push Walls", "PUSH WALLS", "push walls", "Push walls", "push Walls"] #Array of all possible answers. Answer2 = ["Red Green Yellow", "Red, Green, Yellow", "red green yellow", "Red green yellow", "red Green yellow", "red green Yellow", "red, green, yellow", "Red, green, yellow", "red, Green, yellow", "red, green, Yellow", "RED GREEN YELLOW", "RED, GREEN, YELLOW"] #Array of all possible answers. Answer3 = ["Look Up", "look Up", "LOOK UP", "look up"] #Array of all possible answers. lives = 3 a = 0 # b = 0 #used to see if a room has already been picked. 0 is 'not picked' and 1 is 'is picked' c = 0 # #introduction def intro(): env = """ """ print(env) time.sleep(0.5) print(""" """) time.sleep(0.5) #main story def main(): intro() #introduction ###### random.choice([room1,room2,room3])() #pick random room def room1(): global currentFuncName global a global lives #making lives global so it can be accessed from outoflives() a = 1 currentFuncName = current = inspect.stack()[0].function #print(currentFuncName) time.sleep(0.5) print(""" """) correct1 = input("") if correct1 in Answer1: print("") else: lives = 2 outoflives() def room2(): global b b = 1 print("") def room3(): global c c = 1 print("") #called if you lose def lose(): print("") time.sleep(2) main() #called if you win def win(): print("") time.sleep(2) main() def outoflives(): global lives while lives != 0: time.sleep(0.3) print("") time.sleep(0.5) print("", str(lives), "") time.sleep(1) print("") currentFuncName() break while lives == 0: print("") lose() break def roompick(): if a == 1: random.choice([room2,room3])() elif b == 1: random.choice([room1,room3])() elif c == 1: random.choice([room1,room2])() main()As a brief overview, a random room is picked. a / b / c is set to 1. If you lose a life you go to outoflifes(). Then it uses currentFuncName() to call the previous function you were just in - room1() for instance. IF you pass taht room roompick() is called. depending on what room is set to 1 means you wont get that room again. Nevermind I got this to work after lots of experimenting! import inspect #this a test def main(): room1() def room1(): global current current = inspect.stack()[0].function dead() def dead(): print("dd") eval(current + '()') main()I know eval() should be avoided at all times but I have no user inputs in that area of my code. Thanks for all the help! RE: Call a def from a string - nilamo - Jun-25-2018 (Jun-23-2018, 08:21 AM)DreamingInsanity Wrote: I know eval() should be avoided at all times but I have no user inputs in that area of my code. Why thank us, if you're ignoring almost every bit of advice that was sent your way? lol |