Python中的同类列表

时间:2014-11-28 10:43:19

标签: python python-2.7

我正在尝试设计一个允许访问特定文件格式内容的python模块。该文件本质上是一个层列表(可变),每个层都是一个相对复杂的对象,具有自己的内部结构(与此问题无关)。但是,此文件格式的严格限制是它不允许“共享”图层(即,两个不同图层对象引用的相同数据),并且同质< /强>

我正在尝试设计一个Python API来表示此文件的内容,并保持它所代表的概念不变。我希望它能够像pythonic一样让用户更容易使用我的库。

有没有办法在Python中实现这一点而不提供非直观的API? (即,与列表明显不同的东西)

Python库中是否有这样的示例?

以下是一个简单的例子。

图层类

# an example layer class
class Layer:
    def __init__(self, content):
        self.value = content
    def __repr__(self):
        return "Layer(" + str(self.value) + ")"

# make a list of layer classes (as if it was loaded from a file)
layers = []
layers.append(Layer(0.0))
layers.append(Layer(2.0))

我希望能够做的操作

# altering an element
l0 = layers[0]
l0.value = 3.0

# adding an element and altering it later
l1 = Layer(3.0)
layers.append(l1)
l1.value = 5.0

# removing an element
layers.pop(0)

# iterating over elements
for i in layers:
    print i

我不想做的操作

我不确定抛出异常是否是在Python中处理此类错误的有效方法。

# the layers list should be heterogeneous, inserting anything else than a Layer
#   should not be allowed
layers.append(dict())

# there should never be two instances of the same Layer object in any
#   instance of the layers array (there *can* be two instances with 
#   the same data, but they should not be shared)
l2 = Layer(10.0)
layers.append(l2)
layers.append(l2)
l2.value = 300.0

l3 = Layer(13.0)
layers2 = [];
layers.append(l3)
layers2.append(l3)

最后的注释:我是一名擅长进入Python领域的C ++程序员。最后的实现将在Python中包装C ++类,我试图避免使用共享指针和/或以无法存储在文件中的方式表示文件的数据。我知道使用gettattr and setattr的可能性,但这似乎是Python程序员不赞成的,我找不到Python本机库中的一个例子,它会使用这种方法并且具有与我需要的类似的行为(这可以证明他们眼中的这种方法)。

1 个答案:

答案 0 :(得分:0)

这可以通过创建覆盖append方法的list子类来实现。例如:

class LayerList(list):

    def __init__(self, id):
        self.id=id
        return super(LayerList, self).__init__() 


    def append(self, item):
        #test if the item is a Layer
        if not isinstance(item,Layer):
            #do whathever treatment you wanna do
            raise Exception("Not a Layer object")              

        #test if the item is already in the list
        if item in self:
            #do whathever treatment you wanna do
            raise Exception("Item already in list")

        #check if the layer has the attr "layer_id"
        if not hasattr(item,"layer_id"):
            setattr(item,"layer_id",None)
        item.layer_id=self.id

        #call the parents 'append'
        super(LayerList, self).append(item) 

    def pop(self, i=None):
        item = super(LayerList, self).pop(i)
        item.layer_id=None
        return item