0

I put together a small test code just to demonstrate the error I am getting when trying to enter a class with input. Nothing pretty or good its just to get the specific error across.

Code:

class people(object):
    def deposit():
        print("depositing")
    def withdraw():
        print("withdrawing")
John = people()
selection = input("Type John: ")
selection.deposit

Error:

[evaluate classes.py]
Type John: John
Traceback (most recent call last):
  File "c:\Users\Peter\Desktop\Desktop 2\Python\classes.py", line 9, in module
    selection.deposit
builtins.AttributeError: 'str' object has no attribute 'deposit'
Oleg Sklyar
  • 9,080
  • 4
  • 38
  • 57
  • 1
    what do you mean by `enter a class with input`? This is a classic [XY problem](http://xyproblem.info/). Please describe what you are trying to achieve – Pynchia Oct 27 '15 at 22:41

5 Answers5

1

If it's only for demonstration purposes you could lookup the selection value in the locals() dict:

In [4]: John = 1

In [5]: selection = "John"

In [6]: locals()[selection]
Out[6]: 1

So, your code would look like:

class people(object):
    def deposit(self):
        print("depositing")
    def withdraw(self):
        print("withdrawing")
John = people()
selection = input("Type John: ")
locals()[selection].deposit()

However, please do not use this approach in production code. There are better patterns for dispatching stuff to objects..

tuxtimo
  • 2,631
  • 19
  • 29
  • Did you test the code before posting? The functions should have `self` as the minimum argument and `locals()[selection].deposit` should be `locals()[selection].deposit()` – Swastik Padhi Oct 27 '15 at 22:51
0

Generally, you don't want this kind of direct correspondence between user input and your internal variable names. You'd have some data structure to keep track of your people instances, perhaps a dict:

known_people = {'John': people(), 'Jake': people(), 'Jeffrey', people()}

and you'd process user input to determine what to do with your data:

selected_person = known_people[selection]
selected_person.deposit()

While you technically can access variables dynamically:

John = people()
selected_person = locals()[selection]

you really, really shouldn't. It doesn't scale well to more complex data, and it introduces potential for lots of nasty bugs.

user2357112
  • 235,058
  • 25
  • 372
  • 444
0

<<<<<<answer is here<<>>and here>>>>>>

Community
  • 1
  • 1
  • Alright thank you so much. I have heard from other people in this area that eval is evil I don't know im still learning but this should would for me for now at least. – Lemon Houser Oct 27 '15 at 22:57
  • yeah I tested it and it worked I'm using python 2.4 pretty old, but I'm on the laptop I use for class.. –  Oct 27 '15 at 22:57
  • 1
    @LemonHouser The above code doesn't even run on Python 2. Did you test it before accepting? It gives me a number of errors! Run it and see for yourself. – Swastik Padhi Oct 27 '15 at 22:59
  • 1
    Of course he wants to run the `deposite` method ... on not getting the method object itself ... – tuxtimo Oct 27 '15 at 23:02
  • 2
    @DeliriousMistakes you are not really calling the `deposit` method with this- `selection.deposit`, to call it, you need to write this- `selection.deposit()` and when you write that you encounter another error as you have not specified `self` as the minimum argument in the functions above. – Swastik Padhi Oct 27 '15 at 23:06
  • Oh I see, I'm sorry tuxtimo answer is correct mine is wrong outcome wasn't really paying attention. Gotta do `selection = input("Type John: ")` `locals()[selection].deposit()` instead. Again sorry for not paying attention. –  Oct 27 '15 at 23:08
  • 1
    @DeliriousMistakes Cool! ;) – Swastik Padhi Oct 27 '15 at 23:55
0

You could store the people (like John) in a separate object (like a dictionary).

Consider that approach:

class Man(object):
    # I renamed the `people` class to `Man` since it's representing a single man (like John).
    # You also have to add a required `self` parameter for every function inside of the class!
    def deposit(self):
        print("depositing")

    def withdraw(self):
        print("withdrawing")

# We'll make `people` a dictionary instead.
people = {
    'John': Man()
}

selection = raw_input("Type John: ")

# You have to put parentheses there so the `deposit()` function would call
people[selection].deposit()

eval() is pretty evil, so as locals().

Community
  • 1
  • 1
Igor Hatarist
  • 4,787
  • 2
  • 30
  • 43
-1

input("Type John: ") returns a string, not an object of type people so you can't call the method deposit on it.

Workaround-

class people(object):
    def deposit(self):
        print("depositing")
    def withdraw(self):
        print("withdrawing")
selection = input("Type people(): ")
selection.deposit()

Input-

people()  

Output-

depositing

Screenshot

Swastik Padhi
  • 1,789
  • 14
  • 25