iago-lito
iago-lito

Reputation: 3218

Create a list property in Python

I am starting OOP with Python 3 and I find the concept of property really interesting.

I need to encapsulate a private list, but how could I use this paradigm for lists?

Here's my naive try:

class Foo:
    """ Naive try to create a list property.. and obvious fail """

    def __init__(self, list):
        self._list = list

    def _get_list(self, i):
        print("Accessed element {}".format(i))
        return self._list[i]

    def _set_list(self, i, new):
        print("Set element {} to {}".format(i, new))
        self._list[i] = new

    list = property(_get_list, _set_list)

This doesn't behave as expected and even makes python crash when I try the following code. This is the fictive behavior I would like Foo to exhibit:

>>> f = Foo([1, 2, 3])
>>> f.list
[1, 2, 3]
>>> f.list[1]
Accessed element 1
2
>>> f.list[1] = 12
Set element 1 to 12
>>> f.list
[1, 12, 3]

Upvotes: 2

Views: 1901

Answers (2)

ojii
ojii

Reputation: 4781

import collections


class PrivateList(collections.MutableSequence):
    def __init__(self, initial=None):
        self._list = initial or []

    def __repr__(self):
        return repr(self._list)

    def __getitem__(self, item):
        print("Accessed element {}".format(item))
        return self._list[item]

    def __setitem__(self, key, value):
        print("Set element {} to {}".format(key, value))
        self._list[key] = value

    def __delitem__(self, key):
        print("Deleting element {}".format(key))
        del self._list[key]

    def __len__(self):
        print("Getting length")
        return len(self._list)

    def insert(self, index, item):
        print("Inserting item {} at {}".format(item, index))
        self._list.insert(index, item)


class Foo(object):
    def __init__(self, a_list):
        self.list = PrivateList(a_list)

Then runnning this:

foo = Foo([1,2,3])
print(foo.list)
print(foo.list[1])
foo.list[1] = 12
print(foo.list)

Outputs:

[1, 2, 3]
Accessed element 1
2
Set element 1 to 12
[1, 12, 3]

Upvotes: 4

Klaus D.
Klaus D.

Reputation: 14369

There are some problems in your code. They might not be the only problems but fixing them would bring you further:

  • Properties are for new style classes. They are derived from object:

    class Foo(object):

  • The getter (the first argument to property will be called without argument. So _get_list can't have the second argument i. The same applies to _set_list it can only have one argument, not two. (self is implicit and does not count here.)

Upvotes: 1

Related Questions