基于 Python list 类派生的类

67 阅读2分钟

在 Python 中,需要处理大量变量传递的问题,例如在一个薄膜计算程序中,需要跟踪多个层的不同光学特性,如折射率、吸收率、厚度等。为了方便管理和传递这些变量,可以使用基于 Python list 类派生的类来封装这些变量。

huake_00257_.jpg

2. 解决方案

2.1 创建 Layers 和 OneLayer 类

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

2.2 使用 Layers 和 OneLayer 类

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

2.3 代码改进建议

1. 避免使用本机列表:

if you make any list operation the result will be a native list:
layers1 = Layers()
layers2 = Layers()
layers1 + layers2 -> the result will be a native list

建议修改为:

def __add__(self, other):
    if not isinstance(other, Layers):
        return NotImplemented
    return Layers(self.container + other.container)

2. 使用 __repr____str__ 方法替代 input_string 方法:

Why define input_string when you can override __repr__ or __str__

建议修改为:

def __repr__(self):
    return str(self.container)

3. 可选地从 list 类派生:

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.

在这种情况下,不需要从 list 类派生也可以实现类似的功能。例如:

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

总之,基于 Python list 类派生的类可以为需要处理大量相关变量的情况提供一种方便且高效的管理和传递方式。通过对代码的改进,可以进一步提高代码的效率和易用性。