如何使用从Python的列表类派生的类

时间:2022-11-19 10:37:11

This is a followup to question 912526 - How do I pass lots of variables to and from a function in Python?.

这是问题912526的后续内容 - 如何在Python中向函数传递大量变量?

There are lots of variables that need to get passed around in the program I'm writing, and from my previous question I understand that I should put these variables into classes, and then pass around the classes.

在我正在编写的程序中需要传递很多变量,从我之前的问题中我理解我应该将这些变量放入类中,然后传递类。

Some of these variables come in repetetive sets - for a thin film calculation I need to track the optical properties (index of refraction, absorption, thickness, etc) for a number of layers.

其中一些变量来自重复集 - 对于薄膜计算,我需要跟踪多个层的光学性质(折射率,吸收,厚度等)。

Is the best way to store variables like this to create a class derived from a Python list to store the set of classes which each hold the variables for a single layer? And then put the functions that deal with the set of layers in class derived from the list, and the functions that deal with a specific layer in that class? Is there a better way to do this with a single class?

存储这样的变量的最佳方法是创建一个派生自Python列表的类来存储每组保存单个层变量的类集合吗?然后把处理从列表中派生的图层集的函数和处理该类中特定图层的函数放在一起?有没有更好的方法来完成单一课程?

Using the two class approach in the following example, I'm able to set things up so that I can access variables using statments like

在下面的例子中使用两类方法,我能够进行设置,以便我可以使用类似的语句访问变量

n1 = layers[5].n

This is the best way to do this, right?

这是最好的方法,对吗?

#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()

I get the following output from this test program:

我从这个测试程序得到以下输出:

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 个解决方案

#1


There are several issues in your code:

您的代码中存在以下几个问题:

1.If you make any list operation the result will be a native list:

1.如果您进行任何列表操作,结果将是本机列表:

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

2.Why define input_string when you can override __repr__ or __str__

2.当你可以覆盖__repr__或__str__时,为什么定义input_string

3.Why do you even have to derive from list in this case? You only need to derive from list if you want your class to behave exactly like a list. But in your case you seem to be looking for a container. All you need to do to get your class to behave similar to a list is to override some special python methods http://docs.python.org/reference/datamodel.html#emulating-container-types

你为什么要在这种情况下从列表中得出?如果您希望类的行为与列表完全相同,则只需从列表派生。但在你的情况下,你似乎在寻找一个容器。要使类与列表类似,您需要做的就是覆盖一些特殊的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

#1


There are several issues in your code:

您的代码中存在以下几个问题:

1.If you make any list operation the result will be a native list:

1.如果您进行任何列表操作,结果将是本机列表:

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

2.Why define input_string when you can override __repr__ or __str__

2.当你可以覆盖__repr__或__str__时,为什么定义input_string

3.Why do you even have to derive from list in this case? You only need to derive from list if you want your class to behave exactly like a list. But in your case you seem to be looking for a container. All you need to do to get your class to behave similar to a list is to override some special python methods http://docs.python.org/reference/datamodel.html#emulating-container-types

你为什么要在这种情况下从列表中得出?如果您希望类的行为与列表完全相同,则只需从列表派生。但在你的情况下,你似乎在寻找一个容器。要使类与列表类似,您需要做的就是覆盖一些特殊的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