Reputation: 335
I'm not sure if this is best done with a class or if there's a neater way to do this.
I am writing a module, and in it I would like certain lists to be pre-defined and easily accessible, but also changeable. There will be a lot of these lists, maybe 20-30.
So example of these lists:
fruits = ['apple','pear','peach']
nuts = ['peanuts','cashew','almonds']
I also want to have two functions that allow people to add or remove items from this list:
my_mod.add(nuts, ['macademia','brazil'])
my_mod.remove(fruits, ['apple'])
So I was thinking of writing a class:
class Food:
def __init__ (self):
self.fruits = ['apple','pear','peach']
self.nuts = ['peanuts','cashew','almonds']
def add(self, add_items):
self.<????> += add_items
But as you can see where I have the question marks, if I do it this way, I don't know how to add it to the list name supplied by the user.
Am I going about this there right way or is there a better way to achieve what I'd like?
The other idea I had was to use a dict
and define it in the __init__
file of the Module
But I'm less keen on this idea, as I think it could be confusing.
Upvotes: 1
Views: 81
Reputation: 961
1 - With lists and "eval" function: This one works; but is not adviseable, beacause using "eval" if you don't know what your doing a user can inject malicious code.
class User:
fruits = ['apple','pear','peach']
nuts = ['peanuts','cashew','almonds']
def add(self, _list, new_items=[]):
l = eval('self.%s' % _list)
l += new_items
def remove(self, _list, item):
l = eval('self.%s' % _list)
l.remove(item)
if __name__ == '__main__':
user1 = User()
user1.add('fruits', ['orange', 'lemon'])
print user1.fruits
user1.remove('nuts', 'cashew')
print user1.nuts
2 - Using python dictionaries.
class User:
products = {
'fruits': ['apple','pear','peach'],
'nuts': ['peanuts','cashew','almonds'],
}
def add(self, _list, new_items=[]):
try:
self.products[_list] += new_items
except KeyError:
print 'The product list entered does not exist'
def remove(self, _list, item):
try:
self.products[_list].remove(item)
except KeyError:
print 'The product list entered does not exist'
if __name__ == '__main__':
user1 = User()
user1.add('fruits', ['orange', 'lemon'])
print user1.products['fruits']
user1.remove('nuts', 'cashew')
print user1.products['nuts']
# When the user enters a nonexisting list
user1.add('vegetables', ['onion'])
class Mylist(list):
def add(self, item):
self.append(item)
class User:
fruits = Mylist(['apple','pear','peach'])
nuts = Mylist(['peanuts','cashew','almonds'])
if __name__ == '__main__':
user1 = User()
# TO ADD AN ITEM
user1.fruits.add('orange')
print user1.fruits
# TO REMOVE AN ITEM, (list name must match name of list attribute inside)
user1.nuts.remove('cashew')
print user1.nuts
Upvotes: 1
Reputation: 1327
My suggestion would be to use an .xml
or .json
to define the contents of this list, like a sort of config. That way you can in your python code, simply read the root
level tree
and drill down programmatically, without the need to hard code anything, yet give the end users flexibility to add/remove. This can also mean that the end user changing this config
file doesn't need to modify any python objects
.
Let me illustrate. We have a config of user defined lists, say udl_config.xml
which looks like:
<main>
<fruits>
<elem>apple</elem>
.....
</fruits>
<nuts>
.....
</nuts>
.....
</main>
Then in your python code you will have:
import xml.etree.ElementTree as ET
main_tree = ET.parse('udl_config.xml')
main_root = main_tree.getroot()
Use the find()
and text()
functions of xml parse library to drill down dynamically and perform necessary actions on them.
Upvotes: 0