这篇文章实际上是对一篇旧文章的编辑,因为上一篇文章根本不清楚我的问题。
我想当你创建从另一个类继承并共享相同属性的类的实例时,我对真正发生的事情有疑问。
我有一段代码,它使用了scapy.packets中的包库。它的目的是创建一个报头,一个数据层,将这两者结合起来形成一个数据包。
我决定创建两个类Header和Layer,它们都继承自Packet,因此共享类属性fields_desc. 在这两个类中,我添加了两个类方法为了在我即将生成的包中添加一些字段。然后,我创建了一个header实例,一个layer实例,并将这两个包组合成最终的包:
class Init:
class Header(Packet):
name = "RESM_header"
fields_desc = []
@classmethod
def add_IntField(cls, name, value):
cls.fields_desc.append(IntField(name, value))
@classmethod
def reset(cls):
"""
Allows for the fields_desc to be set to []
"""
cls.fields_desc=[]
class Layer(Packet):
name = "DATA"
fields_desc = []
@classmethod
def add_IntField(cls, name, value):
cls.fields_desc.append(IntField(name, value))
@classmethod
def reset(cls):
"""
Allows for the fields_desc to be set to []
"""
cls.fields_desc = []
如果我想创建一个标题字段"id"我将使用:
if __name__ == '__main__':
Init.Header.add_IntField("id",4) # adds the requested field with its value
a = Init.Header() # creates the packet with the fields_desc already filled
如果我显示包,我有结果:
a.show()
###[ RESM_header ]###
id = 4
然而,在我的整个项目中,我必须创建几个不同的头。例如,我想用python a.reset()
重置我的头的fields_desc,然后用python Init.Header.add_IntField("id",6)
添加一个新字段和一个新值。
然而,我的id的值仍然是前一个值。下面的代码两次返回相同的数据包:
if __name__ == '__main__':
Init.Header.add_IntField("id",4)
a = Init.Header()
a.show()
a.reset()
Init.Header.add_IntField("id",5)
a = Init.Header()
a.show()
a.reset()
更奇怪的是,如果我决定创建另一个与前一个不同的字段,代码会出错,并出现几个错误:
if __name__ == '__main__':
Init.Header.add_IntField("id",4)
a = Init.Header()
a.show()
a.reset()
Init.Header.add_IntField("another_field",5) # try to create another field
a = Init.Header()
a.show()
a.reset()
返回错误:
Traceback (most recent call last):
File "F:/IVS_NG/Tests/DebugTest.py", line 46, in <module>
a.show()
File "D:UsersT0267246-AAppDataRoamingPythonPython37site-packagesscapypacket.py", line 1464, in show
return self._show_or_dump(dump, indent, lvl, label_lvl)
File "D:UsersT0267246-AAppDataRoamingPythonPython37site-packagesscapypacket.py", line 1414, in _show_or_dump
fvalue = self.getfieldval(f.name)
File "D:UsersT0267246-AAppDataRoamingPythonPython37site-packagesscapypacket.py", line 411, in getfieldval
return self.payload.getfieldval(attr)
File "D:UsersT0267246-AAppDataRoamingPythonPython37site-packagesscapypacket.py", line 1824, in getfieldval
raise AttributeError(attr)
AttributeError: another_field
如果有人知道是怎么回事,我将非常感激!欢呼声
我将把这个作为一个答案,因为它不适合在评论中。我不是scapy方面的专家,所以我不知道这是否能满足您的需要,但是在浏览了文档之后,在我看来,它的设计并不是像您试图做的那样动态更改字段。相反,您应该预先定义所有字段,然后可以为每个实例设置值。例如,您的Header
类可能看起来像这样:
class Header(Packet):
name = "RESM_header"
fields_desc = [ IntField("id", 0) ] # define a field called "id" with default 0
就是这样,真的。现在您可以创建具有任意id的Header
实例,如下所示:
header = Header(id = 12345) # pass the desired id to the constructor here
header.show()
# ###[ RESM_header ]###
# id = 12345
如果您需要Header
有另一个字段,只需静态地将其添加到fields_desc
列表:
class Header(Packet):
name = "RESM_header"
fields_desc = [ IntField("id", 0),
IntField("another_field", 0) ]
并像前面那样创建实例:
header = Header(id = 12345, another_field = 69)
header.show()
# ###[ RESM_header ]###
# id = 12345
# another_field= 69
在你的子类中试试
def __init__(self):
super().__init__()
https://realpython.com/python-super/