2015-10-15 41 views
0

我开始使用Python 3进行OOP,我发现property的概念确实很有趣。在Python中创建列表属性

我需要封装一个私人列表,但我怎么能用这个范例的列表?

这里是我的幼稚的尝试:

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) 

预期这并不表现甚至让蟒蛇崩溃,当我尝试下面的代码。这是我想Foo展示的虚拟行为:

>>> 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] 
+0

是'print's重要? –

+0

@AnandSKumar是的,因为它们实际上代表了我使用'i'和'new'的值执行的其他类成员的进一步更新。 –

回答

2
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) 

然后捉迷藏这样的:

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

输出:

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

所以我*需要一个新的类和重写'[]'操作符。现在这很有道理。谢谢! ^^ –

+0

是的,你的代码只检查是否可以访问'list'属性,而不是对该属性返回的对象的任何操作。 – ojii

1

您的代码中存在一些问题。他们可能不是唯一的问题,但修复他们会带给你更多的:

  • 属性是新的风格类。他们是从object得出:

    class Foo(object):

  • 吸气剂(以property的第一个参数将被称为无参数,所以_get_list不能有第二个参数i这同样适用于_set_list它只能有。 。一个参数,而不是两个(self是隐含的,这里不计。)

+0

非常真实。这就是为什么我打电话给我的尝试“天真”;) –