尝试使用python中的Kaitai Struct读取pcap。
我已经从该js pcap.ksy 文
件创建了python 文件
$ ./bin/kaitai-struct-compiler -t python --outdir xx formats/network/pcap.ksy
$ ls xx
ethernet_frame.py ipv6_packet.py __pycache__
icmp_packet.py packet_ppi.py tcp_segment.py
ipv4_packet.py pcap.py udp_datagram.py
PYTHONPATH设置为xx目录。现在,如果我运行一个简单的单行脚本来检查是否可以加载模块
from pcap import Pcap
我得到这个错误
$ python3 try.py
Traceback (most recent call last):
File "try.py", line 1, in <module>
from pcap import Pcap
File "/spare/tmp/scratch/kaitai-struct-compiler-0.8/xx/pcap.py", line 11, in <module>
from packet_ppi import PacketPpi
File "/spare/tmp/scratch/kaitai-struct-compiler-0.8/xx/packet_ppi.py", line 11, in <module>
from ethernet_frame import EthernetFrame
File "/spare/tmp/scratch/kaitai-struct-compiler-0.8/xx/ethernet_frame.py", line 11, in <module>
from ipv6_packet import Ipv6Packet
File "/spare/tmp/scratch/kaitai-struct-compiler-0.8/xx/ipv6_packet.py", line 12, in <module>
from ipv4_packet import Ipv4Packet
File "/spare/tmp/scratch/kaitai-struct-compiler-0.8/xx/ipv4_packet.py", line 13, in <module>
from ipv6_packet import Ipv6Packet
ImportError: cannot import name 'Ipv6Packet'
我的理解是,python路径尚可,并且python模块正在从pacp到以太网,ipv6到ipv4的整个链中运行。然后,ipv4尝试再次加载ipv6,脚本崩溃了。
我认为代码正在触发导入循环。
有人知道我在做什么错吗?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
你遇到的问题确实是由导入循环引起的。在Python中,当两个或多个模块相互尝试导入对方时,就会发生导入循环。从你的错误信息来看,ipv4_packet.py
试图导入ipv6_packet.py
,而后者又反过来尝试导入ipv4_packet.py
,形成了一个循环依赖。
解决这个问题的一种方法是使用Python中的import
语句的延迟特性,即只在真正需要使用到该类或函数时才进行导入。你可以通过以下方式修改代码来避免直接在模块顶部导入:
ipv4_packet.py
from ipv6_packet import Ipv6Packet
# ... 其他代码
ipv6_packet.py
from ipv4_packet import Ipv4Packet
# ... 其他代码
将直接导入改为在具体使用时导入:
ipv4_packet.py
# ... 其他代码直到实际需要使用Ipv6Packet的地方
class SomeClassInIpv4:
def some_method(self):
from ipv6_packet import Ipv6Packet
# 现在才真正需要Ipv6Packet
# 使用Ipv6Packet...
ipv6_packet.py
# ... 其他代码直到实际需要使用Ipv4Packet的地方
class SomeClassInIpv6:
def some_method(self):
from ipv4_packet import Ipv4Packet
# 现在才真正需要Ipv4Packet
# 使用Ipv4Packet...
这样修改后,每个模块在被其他模块导入时不会立即尝试导入另一个可能还在初始化过程中的模块,从而打破了循环依赖。
另外,如果你发现某些类或函数实际上并不需要直接导入另一个模块的所有内容,而是只需要其中的一部分,可以考虑仅导入所需的那部分(例如,特定的类或函数),这也能帮助减少潜在的循环依赖问题。