【问题标题】:How to use classes derived from Python's list class如何使用派生自 Python 列表类的类
【发布时间】:2010-10-29 14:40:11
【问题描述】:

这是问题 912526 - How do I pass lots of variables to and from a function in 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']]

【问题讨论】:

  • 你真的需要一个继承自listLayers 类吗?只需使用列表即可。

标签: python class


【解决方案1】:

您的代码中有几个问题:

1.如果您进行任何列表操作,结果将是一个原生列表:

layers1 = Layers()
layers2 = Layers()
layers1 + layers2 -> the result will be a native list

2.当可以覆盖__repr____str__时为什么还要定义input_string

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

【讨论】:

  • @hopatcong:您可以通过实现 add 方法来解决第一个问题。见docs.python.org/reference/…
  • 这里只是一个补充,repr 是 input_string 的正确替换。 str 应该用于非正式/简单的解释 - 不是对象的完整表示。
  • 你的代码有问题:可变默认值,见stackoverflow.com/q/1132941/13543
猜你喜欢
  • 1970-01-01
  • 2020-04-18
  • 2013-04-19
  • 1970-01-01
  • 2012-05-29
  • 2020-05-23
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多