1

Let's say we have two classes Basket and Item. Each basket contains a list of items. I can store in the basket the ids of the items, or directly the items objects. Which is the best solution, and why (in terms of memory usage, covenience, etc...)?

CASE A

class Basket(object):

    def __init__(self, basket_name):
        self._name = basket_name
        self._items = []


    def add_item(self, item_id)
        self._items.append(item_id)


class Item(object):

    def __init__(self, item_id):
        self._id= item_id

>>> b = Basket('My_Basket')
>>> i1 = Item(1)
>>> i2 = Item(2)
>>> b.add_item(1)
>>> b.add_item(2)

CASE B

class Basket(object):

    def __init__(self, basket_name):
        self._name = basket_name
        self._items = []


    def add_item(self, item)
        self._items.append(item)


class Item(object):

    def __init__(self, item_id):
        self._id= item_id


>>> b = Basket('My_Basket')
>>> i1 = Item(1)
>>> i2 = Item(2)
>>> b.add_item(i1)
>>> b.add_item(i2)
4
  • 2
    I would prefer Case B. Otherwise who's job is it to keep track of id's? Do you want to have to maintain some other class that acts as a database for you to look up objects by their ids? It makes more sense semantically to pass around objects as objects. In this case putting an Item in a Basket is more "object oriented" than adding another level of indirection. Commented Oct 5, 2016 at 12:18
  • 2
    Your code samples are not equivalent. There is no way to access Item instances having Basket instance in snippet A, but it's possible in snippet B. Commented Oct 5, 2016 at 12:20
  • 2
    Every variable in python is a reference, therefore you can store objects directly without worries about space usage. About convinience, it's all about your needs. Commented Oct 5, 2016 at 12:21
  • @ŁukaszRogalski of course a additional methods would be necessary to make the samples work. I did not code them to go straight to the point. Commented Oct 5, 2016 at 13:18

4 Answers 4

3

You should store the items directly. As previously mentioned there is no resource issue with doing it and then it provides the basket with direct access to the items. Say you wanted to know how much the basket weighs? well if you add a .weight method to your items class then you can have your basket iterate through all of the items it contains and return the weight of them.

Sign up to request clarification or add additional context in comments.

Comments

1

I would prefer storing objects, not IDs. Because each time you would have to do something with your Items you would have to first somehow get/load this object by ID. But this is a general case.

In case of you will have tons of Items and no operations with full list (e.g. basket will only perform actions on a single object, not on full collection) you might want to store only IDs.

Comments

1

Option B is usually the best option because this is how Object Oriented Programming works. Because you are using the objects directly you can also access them directly in you code. If you use the link option then in order to access a given Item later you would have to do some sort of query to find that object. When you use the object directly what python essentially does is creates that link for you. The object is not copied twice but instead it is referenced in the _items list inside your Basket object.

Also, the self._id= item_id in

def __init__(self, item_id):
    self._id= item_id

would not be required because you would have no need to find that id, and hence:

>>>i1 = Item(1)
>>>i2 = Item(2)

Would simply become:

>>> i1 = Item()
>>> i2 = Item()

Comments

1

everything in python is an object, including integers used as IDs for other objects. So in both Case A and Case B you are appending references to objects to the Basket._items list.

So what is the difference between A and B? If you only store the IDs then how will you reference the original objects? It is harder to guarantee that they will exist in the namespace. Any code that looks up properties from item instances may fall into that trap.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.