如何使用从Python的list类派生的类
这是对问题912526的后续讨论 - 在Python中如何传递很多变量到函数中并从函数中返回?.
在我写的程序中,有很多变量需要传来传去。根据我之前的问题,我明白了应该把这些变量放到类里面,然后把类传来传去。
其中一些变量是重复的,比如在薄膜计算中,我需要跟踪多个层的光学特性(折射率、吸收、厚度等)。
存储这些变量的最好方法是创建一个从Python列表派生的类,用来存储每个层的变量的类集合吗?然后把处理这些层的函数放在从列表派生的类里面,把处理特定层的函数放在那个类里面?还是说有更好的方法用一个类来实现这个?
在下面的例子中,我使用了两个类的方法,这样我可以通过类似下面的语句来访问变量:
n1 = layers[5].n
这样做是最好的方法,对吧?
#Test passing values to and from functions
class Layers(list):
def add(self,n,k,comment):
self.append( OneLayer(n,k,comment) )
def input_string(self):
input_string = []
for layer in self:
vars = layer.input_string()
for var in vars:
input_string.append( var )
return input_string
def set_layers(self,results):
for layer,i in enumerate(self):
j = i*layer.num_var
layer.set_layer( *results[j:j+2] )
class OneLayer(object):
def __init__(self,n,k,comment):
self.n = n
self.k = k
self.comment = comment
def input_string(self):
return [['f','Index of Refraction',self.n], ['f','Absorption',self.k],['s','Comment',self.comment]]
def set_layer(self,n,k,comment):
self.n = n; self.k=k; self.comment = comment
def num_var(self):
return 3
if __name__ == '__main__':
layers = Layers()
layers.add(1.0,0.0,'This vacuum sucks')
layers.add(1.5,0.0,'BK 7 Glass')
print layers[0].n
print layers.input_string()
layers[1].set_layer(1.77,0.0,'Sapphire')
print layers.input_string()
我从这个测试程序得到了以下输出:
1.0
[['f', 'Index of Refraction', 1.0], ['f', 'Absorption', 0.0], ['s', 'Comment', 'This vacuum sucks'], ['f', 'Index of Refraction', 1.5], ['f', 'Absorption', 0.0], ['s', 'Comment', 'BK 7 Glass']]
[['f', 'Index of Refraction', 1.0], ['f', 'Absorption', 0.0], ['s', 'Comment', 'This vacuum sucks'], ['f', 'Index of Refraction', 1.77], ['f', 'Absorption', 0.0], ['s', 'Comment', 'Sapphire']]
1 个回答
9
你的代码有几个问题:
1. 如果你对列表进行任何操作,结果会是一个普通的列表:
layers1 = Layers()
layers2 = Layers()
layers1 + layers2 -> the result will be a native list
2. 为什么要定义 input_string 呢?你可以直接重写 __repr__
或者 __str__
。
3. 在这种情况下,为什么要从列表派生呢?只有当你希望你的类完全像列表一样工作时,才需要从列表派生。但在你的例子中,你似乎只是想要一个容器。要让你的类表现得像列表,只需要重写一些特殊的 Python 方法就可以了,具体可以参考这个链接 http://docs.python.org/reference/datamodel.html#emulating-container-types。
class Layers(object):
def __init__(self, container=None):
if container is None:
container = []
self.container = container
def add(self,n,k,comment):
self.container.append([n,k,comment])
def __str__(self):
return str(self.container)
def __repr__(self):
return str(self.container)
def __getitem__(self, key):
return Layers(self.container[key])
def __len__(self):
return len(self.container)
>>> l = Layers()
>>> l.add(1, 2, 'test')
>>> l.add(1, 2, 'test')
>>> l
[[1, 2, 'test'], [1, 2, 'test']]
>>> l[0]
[1, 2, 'test']
>>> len(l)
2