内部类不能互相引用,有没有更Pythonic的方式?

问题描述 投票:0回答:1

我想使用内部类(主要是数据类和枚举)来封装事物。它们保存仅与主类相关的数据和定义,因此我想将它们保留在其中。我感觉这不是最 Pythonic 的做事方式,但我不知道如何让它变得更好。

真正的问题是我需要其中一些内部类来包含使用其他内部类类型的变量,而Python似乎不允许这样做。

这就是我想做的(这只是一个简化的例子)。这使得所有内容都成为

DataPacket
的一部分,这样当您引用内部类时,您可以使用
DataPacket
来访问它。 IE。
DataPacket.DataStatus.GOOD
等等,并且很清楚这个“定义”来自哪里。但是,除非将其移出
DataStatus
类,否则找不到
SensorData
中的
DataPacket
引用。

from dataclasses import dataclass
from typing import List
from enum import IntEnum

class DataPacket:

    class DataStatus(IntEnum):
        GOOD = 0
        ERROR = 1
        UNKNOWN = 255

    @dataclass
    class SensorData():
        sensor_name: int = 0
        sensor_type: int = 0
        unit_type: int = 0
        status: DataStatus = DataStatus.UNKNOWN
        value: float = 0

    @dataclass
    class Sensors():
        data: List[SensorData]
        count: int = 0


    def build_packet(self):
        
        sensors = self.Sensors([])
        
        # Read data from device to fill in sensor values

        sensors.count = 1

        data = self.SensorData()
        data.sensor_name = 1
        data.sensor_type = 2
        data.unit_type = 3
        data.status = self.DataStatus.GOOD
        data.value = 100

        sensors.data.append(data)

        return sensors


packet = DataPacket()

sensors = packet.build_packet()

if sensors.data[0].status == DataPacket.DataStatus.GOOD:
    print(sensors.data[0].value)
else:
    print("Sensors data error")

这是让它工作的方法,但我不喜欢这种结构:

from dataclasses import dataclass
from typing import List
from enum import IntEnum

class DataStatus(IntEnum):
    GOOD = 0
    ERROR = 1
    UNKNOWN = 255

@dataclass
class SensorData():
    sensor_name: int = 0
    sensor_type: int = 0
    unit_type: int = 0
    status: DataStatus = DataStatus.UNKNOWN
    value: float = 0

@dataclass
class Sensors():
    data: List[SensorData]
    count: int = 0

class DataPacket:  

    def build_packet(self):
        
        sensors = Sensors([])
        
        # Read data from device to fill in sensor values

        sensors.count = 1

        data = SensorData()
        data.sensor_name = 1
        data.sensor_type = 2
        data.unit_type = 3
        data.status = DataStatus.GOOD
        data.value = 100

        sensors.data.append(data)

        return sensors


packet = DataPacket()

sensors = packet.build_packet()

if sensors.data[0].status == DataStatus.GOOD:
    print(sensors.data[0].value)
else:
    print("Sensors data error")

感谢您的帮助/建议!

python inner-classes python-dataclasses
1个回答
0
投票

您遇到的问题是因为类体不创建封闭范围。嵌套类定义在 Python 中并不常见。您将需要针对该语言进行工作才能使其正常工作。这是您的问题的最小示例

>>> class Foo:
...     class Bar:
...         pass
...     class Baz:
...         bar = Bar()
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in Foo
  File "<stdin>", line 5, in Baz
NameError: name 'Bar' is not defined

这里有一个绕过它的方法,参考

Bar
它在范围内的位置,并在类定义之后分配给类属性:

>>> class Foo:
...     class Bar:
...         pass
...     class Baz:
...         pass
...     Baz.bar = Bar()
...

但实际上,你应该保留已有的解决方案,这是完美的 Pythonic。

© www.soinside.com 2019 - 2024. All rights reserved.