访问内部类变量assignmen中的类变量

2024-09-27 21:25:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用一个类变量作为同一类中另一个变量定义的一部分,如下所示:

import enum, struct

class Message:
    """ExtendedIO related message IDs and `Struct.struct`s."""

    # protocol
    BYTE_ORDER = "<"

    # Message ID's
    class ID(enum.IntEnum):
        """Message ID's definitions."""
        EX_IO = 0x01
        ALIVE = 0x02
        RESETCOMPONENT = 0x03

    STRUCTS = {
        ID[message_id]: struct.Struct(
            ''.join((BYTE_ORDER, format)))
        for message_id, format in {
            'EX_IO': "B",          # command
            'ALIVE': "HH",         # version, version
            'RESETCOMPONENT': ""}  #
        .items()}

这就产生了NameError: name 'BYTE_ORDER' is not defined。你知道吗

我能做到:

import enum, struct

class Message:
    """ExtendedIO related message IDs and `Struct.struct`s."""

    # protocol
    BYTE_ORDER = "<"

    # Message ID's
    class ID(enum.IntEnum):
        """Message ID's definitions."""
        EX_IO = 0x01
        ALIVE = 0x02
        RESETCOMPONENT = 0x03

class Message(Message):

    STRUCTS = {
        Message.ID[message_id]: struct.Struct(
            ''.join((Message.BYTE_ORDER, format)))
        for message_id, format in {
            'EX_IO': "B",          # command, *
            'ALIVE': "HH",         # version, version
            'RESETCOMPONENT': ""}  #
        .items()}

它可以工作,但是额外的class Message(Message):看起来很难看,pylint用一个E0102来抱怨。你知道吗

分配Message.STRUCT的好处是它使用了一个非常可读的表。(我正在编写的实际代码要复杂一些。)

根据这些评论,我尝试了以下代码,这些代码很有效:

import enum, struct

class Message:
    """ExtendedIO related LWF message IDs and `Struct.struct`s."""

    # protocol
    BYTE_ORDER = "<"

    # Message ID's
    class ID(enum.IntEnum):
        """Message ID's definitions."""
        EX_IO = 0x01
        ALIVE = 0x02
        RESETCOMPONENT = 0x03

    EXAMPLE = ''.join((BYTE_ORDER, '1'))

    STRUCTS = lambda ID, BYTE_ORDER: {
        ID[message_id]: struct.Struct(
            ''.join((BYTE_ORDER, format)))
        for message_id, format in {
            'EX_IO': "B",          # command
            'ALIVE': "HH",         # version, version
            'RESETCOMPONENT': ""}  #
        .items()}(ID, BYTE_ORDER)

所以:

  • 直接使用类变量工作。你知道吗
  • 使用lambda将变量插入到理解中也是可行的。你知道吗
  • 使用额外的class Message(Message):工作。 (并且importlib.reload()对第一个代码示例有效,但是结果是错误的…)

在Python中,在同一类中的另一个类变量中使用类变量是否有一种合理的方法?你知道吗


Tags: ioidformatmessageorderenumbytestruct
2条回答

根据使用变量而不是实例变量的方式,还可以更改构造函数中现有的类变量。这样,您的变量仍然是一个由类的所有实例共享的类变量。你知道吗

class Message:
    BYTE_ORDER = "<"
    STRUCTS = {}

    def __init__(self):
        STRUCTS = self.SomethingDependantOn(self.BYTE_ORDER)    

但是,如果不先实例化对象,就无法访问变量。你知道吗

您可以使用self

class Message:
    """ExtendedIO related message IDs and `Struct.struct`s."""

    # protocol
    BYTE_ORDER = "<"

    # Message ID's
    class ID(self, enum.IntEnum):
        """Message ID's definitions."""
        EX_IO = 0x01
        ALIVE = 0x02
        RESETCOMPONENT = 0x03

    def something(self):
        STRUCTS = {
            ID[message_id]: struct.Struct(
                ''.join((self.BYTE_ORDER, format)))
            for message_id, format in {
                'EX_IO': "B",          # command
                'ALIVE': "HH",         # version, version
                'RESETCOMPONENT': ""}  #
            .items()}

或者只需设置变量global并通过类访问它

# protocol
BYTE_ORDER = "<"

class foo():
    def something():
        print(BYTE_ORDER)

class bar():
     def something():
        print(BYTE_ORDER)

相关问题 更多 >

    热门问题