Brandon Reale
Brandon Reale

Reputation: 39

Using user input to call a function from a class

I am trying to call a function from a class based on user input. I've tried other examples based on this but keep on getting various errors depending on which direction I try it.

The test code that I am using is

    def one():
         print('one hahah')

    def two():
        print('two hahah')

    def the_count():
        print('I am the count who likes to count')


    dispatcher = {
        'one': one, 'two': two, 'three': the_count
    }

action = input('Option: - ')

jo.dispatcher[action]()

There we have what I want, but once I added the self argument things stopped working properly. Here is my actual code...

import math
class femblem(object):



    def j(self):
    print('hi')
    `data goes here`

...

    def __init__(self,lv,name):
        self.lv = lv
        self.name = name

    dispatcher = {
        'j': j(self)
        }



action = input('Character: - ')        
unit1 = femblem(5,"joshua")
unit1.dispatcher[action]()

returns NameError: name 'self' is not defined if I take out self it gives me an error saying that it needs that for an argument (which it does). Not very experienced in python, any ideas why this isnt working? Thanks

Upvotes: 0

Views: 1236

Answers (4)

Tarifazo
Tarifazo

Reputation: 4343

An alternative answer with getattr inside the class:

class Foo:
    def __init__(self):
        pass

    def bar(self):
        print('this is foo')

    def dispatcher(self):
        att = input('put some input: ')
        getattr(self, att)()

ob = Foo()
ob.dispatcher()

Upvotes: 1

Michael H.
Michael H.

Reputation: 3483

I can only guess what you are trying to do, but this snippet dispatches to the respective functions defined in your dispatcher for the user inputs one, two and three:

class femblem:
    def __init__(self, lv, name):
        self.lv = lv
        self.name = name

    def one(self):
        print('one hahah')

    def two(self):
        print('two hahah')

    def the_count(self):
        print('I am the count who likes to count')

    @property
    def dispatcher(self):
        return {
            'one': self.one, 
            'two': self.two, 
            'three': self.the_count
        }


action = input('Character: - ')        
unit1 = femblem(5, "joshua")
unit1.dispatcher[action]()

Upvotes: 1

David Zemens
David Zemens

Reputation: 53623

There are several ways you could approach this problem, one of which would be to make dispatcher an instance method of the class:

class Foo(object):
     def __init__(self,lv,name):
         self.lv = lv
         self.name = name
     def one(self):
         print('this is one!')
     def dispatcher(self, action):
         d = {'one':self.one}
         return d[action]

Then you get something like:

>>> f = Foo(5, 'Joshua')
>>> action = input()
>>> f.dispatcher(action)()
'this is one!'

Upvotes: 1

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95948

Essentially, your class will act like a dict here, and your instance is the dispatcher so just use getattr and the self magic will work:

>>> class Foo:
...    def bar(self):
...       return 42
...    def baz(self):
...       return 88
...
>>> foo = Foo()
>>> getattr(foo, 'bar')()
42
>>> getattr(foo, 'baz')()
88
>>>

Upvotes: 3

Related Questions