Reputation: 13
I have multiple classes and I have instances from each class e.g: Student class. every instance (a student) has their own courses. Now when a user signs in (by input) I want to print their list of courses. Or even just their age to show that I have the correct object.
Is there a better way than eval()
to get an object from class based on input
like the following example:
class Student:
def __init__(self, name, age):
self._name = name
self._age = age
blablue = Student('bla blue', '23')
name = input('enter your name')
name = name.split(' ')
stundent = eval(name[0] + name[1])
print(student)
print(student.age)
output:
enter your name: bla blue
<__main__.Foo object at 0x000001B2978C73C8>
23
Upvotes: 1
Views: 177
Reputation: 77912
I assume this is for educational purpose (production code would use a SQL database and some ORM):
try:
# python 2.x
input = raw_input
except NameError:
# python 3.x
pass
class AlreadyExists(ValueError):
pass
class DoesNotExist(LookupError):
pass
class FooCollection(object):
def __init__(self):
self._foos = {}
def add(self, foo):
if foo.name in self._foos:
raise AlreadyExists("Foo with name '{}' already exists".format(foo.name))
self.update(foo)
def update(self, foo):
self._foos[foo.name] = foo
def get(self, name):
try:
return self._foos[name]
except KeyError:
raise DoesNotExist("no Foo named '{}'".format(name))
class Foo(object):
def __init__(self, name, age):
self._name = name
self._age = age
# we at least need to be able to read the name
@property
def name(self):
return self._name
def __repr__(self):
return "Foo({}, {})".format(self._name, self._age)
def main():
foos = FooCollection()
blablue = Foo('bla blue', '23')
foos.add(blablue)
name = input('enter your name: ').strip()
try:
print("found {}".format(foos.get(name)))
except DoesNotExist as e:
print(e)
if ___name__ == "__main__":
main()
The principle here is to have a storage for your instances. I chose a dict
for fast lookup with the Foo.name
as key, in real life you'd probably want an opaque unique identifier for each instance and multiple indexes (i.e. one by id, one by name etc) - but actually in real life you would use a SQL database that already provide all those features in a much more optimized way ;-)
Also, I wrapped the dict
in a dedicated class with its own interface. This allows to decouple the interface from the implementation (if you later decide you want more indexes than just name
for example), and encapsulate domain logic too (i.e. checking you don't accidentally overwrite an existing Foo
).
Upvotes: 2