【问题标题】:How to implement a list of objects as an instance attribute in Python?如何在 Python 中将对象列表实现为实例属性?
【发布时间】:2018-09-04 09:33:38
【问题描述】:

我是 Python 的 OOP 新手。到目前为止,我一直在使用 C++、C# 和 Java 等 OOP 语言。由于我必须将 C# 模块翻译成 Python,因此我遇到了概念上的差异。

我有这个 C# 类关系:

 internal class ChirpMeasDataClass
  {
     public ChirpMeasDataClass(List<AntennaLevelDataClass> AntennaLevelData, List<DiffphaseDataClass> DiffphaseData)
     {
        this.AntennaLevelData = AntennaLevelData;
        this.DiffphaseData = DiffphaseData;
     }
     internal List<AntennaLevelDataClass> AntennaLevelData = new List<AntennaLevelDataClass>();
     internal List<DiffphaseDataClass> DiffphaseData = new List<DiffphaseDataClass>();
  }
  internal class AntennaLevelDataClass
  {
     internal double dLevel =  -10000;          // [dB]
     internal double dVarianzLevel = -10000;  // [dB^2]
  }
  internal class DiffphaseDataClass
  {
     internal double dDiffPhase = -10000;         // [°] 
     internal double dVarianzDiffPhase = -10000; // [°^2] 
  }

在 python 中直观地想到的是有这样的东西:

class AntennaLevelDataClass:
    def __init__(self):
        self.dLevel = -10000  # [dB]
        self.dVarianzLevel = -10000  # [dB ^ 2]

class DiffPhaseDataClass:
    def __init__(self):
        self.dDiffPhase = -10000 # [°]
        self.dVarianzDiffPhase = -10000 # [° ^ 2]

class ChirpMeasDataClass:
    def __init__(self,AntennaLevelDataClass,DiffPhaseDataClass):
       self.antennaLevelDataList=AntennaLevelDataClass
       self.diffPhaseDataList=DiffPhaseDataClass

或类似的东西:

   class ChirpMeasDataClass:
        def __init__(self,antennaLevelDataClass,diffPhaseDataClass):
           self.antennaLevelDataList=[]
           self.diffPhaseDataList=[]

将对象列表作为类中的属性(Python 中的实例属性)的常用方法是什么?

【问题讨论】:

  • Python 没有类型(脚注,星号,它现在有可选的类型注释......),所以你唯一要做的就是在构造函数中获取一个参数并将其分配给一个属性。就是这样。该参数应该是一个仅包含特定类型实例的列表,但所有这些都是相当不相关的,不需要以任何特定方式声明。所以,def __init__(self, a, b): self.a = a; self.b = b 真的是你所需要的。

标签: python list class oop relationship


【解决方案1】:

C# 构造函数唯一要做的就是将两个参数(对象列表)分配给两个实例属性。剩下的大部分是类型注释,在 Python 中是完全可选的。所以,你想要的基本东西就是:

class ChirpMeasData:
    def __init__(self, antenna_level_data, diff_phase_data):
       self.antenna_level_data = antenna_level_data
       self.diff_phase_data = diff_phase_data

您可以添加类型注释:

from typing import List

class ChirpMeasData:
    def __init__(self, antenna_level_data: List[AntennaLevelData],
                 diff_phase_data: List[DiffphaseData]):
       self.antenna_level_data = antenna_level_data
       self.diff_phase_data = diff_phase_data

(请注意,我在此之前在类名中重复使用了“Class”。)

【讨论】:

    【解决方案2】:

    如果你这样做

    self.antennaLevelDataList=AntennaLevelDataClass
    

    那么self.antennaLevelDataList是一个实例变量,它的值就是那个类定义。这似乎不是很有用。

    此外,您将两个类定义传递给构造函数。

    使用列表(其中的内容恰好是这些类的实例)更简洁,C++ 也使用列表,因此它主要是直接等效的。唯一的区别是,在 C++ 中,您必须声明列表内容的类型,而在 Python 中则不能。

    在构造函数中,复制传入的列表的内容可能很有用,例如:

    class ChirpMeasDataClass:
        def __init__(self, antennaLevelData, diffPhaseData):
            self.antennaLevelDataList = anntennaLevelData[:]
            self.diffPhaseDataList = diffPhaseData[:]
    

    [:] 表示整个列表的一部分,实际上是浅拷贝)

    关键是,否则实例属性引用与传入的相同的列表对象,如果复制一个可能会导致意外;在 Python 中没有任何内容是隐式复制的。

    【讨论】:

    • “它的值是那个类定义” – OP 正在用参数隐藏名称 AntennaLevelDataClass...
    • “而在 Python 中你不能” – ......在 Python 中它是可选的 [并且不由运行时强制执行]。
    • “Python 中没有任何东西是隐式复制的” – 是的,这就是为什么在构造函数中隐式复制列表是令人惊讶的行为。
    猜你喜欢
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    相关资源
    最近更新 更多