我有一个具有类属性的类的多构想问题
这篇文章实际上是对旧帖子的编辑,因为上一篇文章在我的问题上根本不清楚。
我认为我在创建从另一个课程中遗传并共享相同属性的课程实例时有什么问题。
我有一个代码,它使用scapy.packet的库数据包。它的实力是创建一个标题,数据层,将这两个组合形成数据包。
我决定创建两个类标题和图层,它们都来自数据包,因此共享类属性 fields_desc 。在这两个类中,我添加了两个 classMethods ,以便在我即将到来的数据包中添加一些字段。然后,我创建一个标题的实例,我的图层实例,然后组合这两个数据包以形成最终数据包:
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()
将标题的字段_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:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 1464, in show
return self._show_or_dump(dump, indent, lvl, label_lvl)
File "D:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 1414, in _show_or_dump
fvalue = self.getfieldval(f.name)
File "D:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 411, in getfieldval
return self.payload.getfieldval(attr)
File "D:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 1824, in getfieldval
raise AttributeError(attr)
AttributeError: another_field
如果有人知道发生了什么,我会成为非常感谢! 干杯
This post is actually an edit of an old post because the previous one wasn't clear at all on my issue.
I think I have issues regarding what's really going on when you create instances of classes that heritates from another class and share a same attribute.
I have a piece of code, which uses the library Packet from scapy.packets. Its prupose is to create a header, a data layer, combine those two to form a packet.
I decided to create two classes Header and Layer which both heritate from Packet and therefor share the class attribute fields_desc. In these two classes I added two classmethods in order to add some fields to my soon-to-be packet. I then create an instance of my header, an instance of my layer and combine these two packets to form the final packet :
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 = []
If I then want to create a header with the field "id" I will use :
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
If I show the packet I have the result :
a.show()
###[ RESM_header ]###
id = 4
However, in my overall project, I have to create several different headers. I would like for instance to reset the fields_desc of my header with python a.reset()
and then add a new field with python Init.Header.add_IntField("id",6)
with a new value.
However the value of my id is still the previous value. The following code returns the same packet twice :
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()
Even weirder, if i decide to create another field different than the previous one, the code goes brrrr with several errors :
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()
returns the error :
Traceback (most recent call last):
File "F:/IVS_NG/Tests/DebugTest.py", line 46, in <module>
a.show()
File "D:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 1464, in show
return self._show_or_dump(dump, indent, lvl, label_lvl)
File "D:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 1414, in _show_or_dump
fvalue = self.getfieldval(f.name)
File "D:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 411, in getfieldval
return self.payload.getfieldval(attr)
File "D:\Users\T0267246-A\AppData\Roaming\Python\Python37\site-packages\scapy\packet.py", line 1824, in getfieldval
raise AttributeError(attr)
AttributeError: another_field
If anyone has an idea of what's going on I'd be very grateful !
Cheers
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我要将其作为答案,因为它不适合评论。我不是Scapy的专家,所以我不知道这是否会做您需要的事情,但是在浏览了文档之后,我似乎并没有像您试图动态地改变领域做。相反,您应该在前定义所有字段,然后可以设置每个实例的值。例如,您的
标题
类看起来像这样:确实如此。现在,您可以创建
header
实例,其中您想要的任何ID:如果需要
标头
具有另一个字段,只需将其添加到fields_desc 静态列表:
并像以前一样创建您的实例:
I'm gonna post this as an answer because it wouldn't fit in the comments. I'm no expert on scapy, so I don't know if this'll do what you need, but after having skimmed the docs it appears to me that it isn't designed to dynamically change the fields like you're trying to do. Instead, you should define all the fields up front, and then you can set the values per instance. For example, your
Header
class might look like this:And that's it, really. Now you can create a
Header
instance with any id you want like this:If you need
Header
to have another field, just add it to thefields_desc
list statically:And create your instance like before:
在您的孩子班上尝试一下
https://realpython.com/python.com/python-super/
try this in your child class
https://realpython.com/python-super/