【问题标题】:Creating a copy of a python list out of class elements从类元素中创建一个 python 列表的副本
【发布时间】:2019-08-22 04:57:20
【问题描述】:

我正在编写一个脚本来处理有限元分析 (FEA) 的多个节点的计算应变/变形。对于不同的正输入扭矩有多种解决方案。我想推断这些数据并模拟负扭矩的结果。在这样做的同时,原始数据会发生变化。

由于我们没有直接更改任何原始值,我认为必须通过推断 FEA 的函数通过引用来访问它。我一直在尝试copy.deepcopy,但通过多个线程发现这不会复制类结构。在other threads it was recommended to inherit,但我正在努力适应我的情况。

以下代码在包含对象相同半径上的所有节点的类中。所有节点都在一个列表self._nodes 中,按它们的角度排序。每个节点都有所有扭矩水平的应变。

class RadialNodeContainer:
    def __init__(self, radius):
        self._r = radius
        self._nodes = []
    def compute_negatives_radial_container(self): # ... see below

class Node:
    def __init__(self, node_id, x, y, z,
                 strain_0nm, strain_100nm, strain_204nm, strain_369nm):
        self._coordinate = Coordinate(x, y, z)
        self._torque_levels = [strain_0nm, strain_100nm,
                               strain_204nm, strain_369nm]
    def get_all_strains_complete(self):
        return copy.deepcopy(self._torque_levels)

class Strain:
    def __init__(self, torque_nm, exx, exy, eyy):
        self._torque = torque_nm
        self._exx = exx
        self._exy = exy
        self._eyy = eyy

导致对原始数据进行不必要更改的函数:

def compute_negatives_radial_container(self):
    points_per_360deg = len(self._nodes)
    jj = points_per_360deg
    corresponding_node_strains = None
    for ii in range(points_per_360deg):
        jj -= 1
        # Mistake is expected below here
        corresponding_node_strains = copy.deepcopy(
                         self._nodes[jj].get_all_strains_complete())                      
        for kk in range(len(corresponding_node_strains)):
            torque = corresponding_node_strains[kk].get_torque_level()
            if torque != 0:
                exx, exy, eyy = corresponding_node_strains[kk].get_raw_strains()
                calculated_negative_strain = Strain(torque_nm=-torque,
                                                    exx=exx,
                                                    exy=-exy,
                                                    eyy=eyy)
                self._nodes[ii].add_torque_level(calculated_negative_strain)

我想创建一个应变元素列表的deepcopy (Node -> self._torque_level)。最初这个列表看起来像[Strain(0Nm), Strain(100Nm), ...]。但是我不知道我必须修改代码的哪些部分才能允许传递类实例的副本。

【问题讨论】:

  • 不能简单的给Strain加个方法来处理负值吗?然后在以后引用时使用类中的开关或不同的方法。

标签: python list class deep-copy


【解决方案1】:

详细说明。如果我有时间,我将对此进行扩展,这正是 OP 正在寻找的。​​p>

我还建议对数组使用 numpy 而不是列表,因为 numpy 更快。

class Strain:
    def __init__(self, torque_nm, exx, exy, eyy):
        self._torque = torque_nm
        self._exx = exx
        self._exy = exy
        self._eyy = eyy
        self._neg = False

    def setNeg(self, neg):
        self._neg = neg

    @propery
    def torque(self):
        return _torque if not self._neg else -self.torque

    @propery
    def exx(self):
        return _exx

    @propery
    def exy(self):
        return _exy if not self._neg else -self._exy

    @propery
    def eyy(self):
        return _eyy

【讨论】:

  • 感谢您的提议。负值是从不同位置的节点应变推断出来的(镜像在 x 轴上),并且不能由同一节点的应变生成。换句话说:我们将self._nodes[jj]-values 用于self._nodes[ii] 的负数。因此,我认为这种方法行不通。感谢您向我介绍@property,非常整洁!
  • 所以做同样的事情,但在数据数组而不是数组点上。有一个“strain_array”类,并让它根据一些开关改变它的输出。创建某个集合类的子类或在您自己的类上使用 __iter__() 特殊方法。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多