我想使用一个类变量作为同一类中另一个变量的定义的一部分,如下所示:
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中同一类的另一个类变量中是否有使用类变量的明智方法?
答案 0 :(得分:0)
根据使用变量 class 而不是 instance 变量的方式,您还可以在构造函数中更改现有的类变量。这样,您的变量仍然是该类的所有实例共享的类变量。
class Message:
BYTE_ORDER = "<"
STRUCTS = {}
def __init__(self):
STRUCTS = self.SomethingDependantOn(self.BYTE_ORDER)
但是,如果不先实例化对象,就无法访问变量。
答案 1 :(得分:0)
您可以使用 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()}
或仅设置变量全局变量并按您的班级进行访问
# protocol
BYTE_ORDER = "<"
class foo():
def something():
print(BYTE_ORDER)
class bar():
def something():
print(BYTE_ORDER)