Reputation: 3218
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
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
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