我正在尝试设计一个允许访问特定文件格式内容的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本机库中的一个例子,它会使用这种方法并且具有与我需要的类似的行为(这可以证明他们眼中的这种方法)。
答案 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