简体   繁体   English

如何使用collections.defaultdict以确保在Python中直接比较值

[英]How to use collections.defaultdict, to ensure a straightforward comparison of values in Python

Basically this is a code modification of a previous question i saw on stack-overflow & I found it interesting to pursue which deals with port scanning . 基本上,这是对我在堆栈溢出中看到的上一个问题的代码修改,我发现进行端口扫描处理很有趣。 In this code I am trying to compare 2 pickle files which hold the scan result of 2 scans performed one after another. 在这段代码中,我试图比较2个腌制文件,这些文件包含一个接一个执行的2个扫描的扫描结果。 I am interested in finding 我有兴趣寻找

3 operations on the set of ports 端口组上的3个操作

 & (intersection): to see which ports have remained constant across scans (same ports) old - new: to see which ports were in the old scan but no longer in the new (deleted ports) new - old: to see which ports are in the new scan but were not in the old (added ports) 
def comp_ports(self,filename):
  try:
        f = open(filename)
        self.prev_report = pickle.load(f) # NmapReport

        for s in self.prev_report.hosts:
            self.old_port_dict[s.address] = collections.defaultdict(set())
            for x in s.get_open_ports():
                self.old_port_dict[s.address].add(x)

        for s in self.report.hosts:
            self.new_port_dict[s.address] = collections.defaultdict(set())
            for x in s.get_open_ports():
               self.new_port_dict[s.address].add(x)

        hosts = sorted(set(self.prev_report.hosts.keys() + self.report.hosts.keys()))

        for host in hosts:
                scan_same[host] = self.prev_report.hosts[host] & self.report.hosts[host]
                scan_new[host]  = self.report.hosts[host] - self.prev_report.hosts[host]
                scan_del[host]  = self.prev_report.hosts[host] - self.report.hosts[host]

        print()
        print('-' * 10, 'Same')
        for host, ports in scan_same.items():
            print(host, ':')
            for port in ports:
                 print(':::', port[0], '/', port[1])

        print()
        print('*' * 10, 'Added')
        for host, ports in scan_new.items():
            print(host, ':')
            for port in ports:
                  print(':::', port[0], '/', port[1])

        print()
        print('=' * 10, 'Deleted')
        for host, ports in scan_del.items():
            print(host, ':')
            for port in ports:
                   print(':::', port[0], '/', port[1])

  except Exception as l:
         print l

But the code throws : 但是代码抛出:

first argument must be callable

Help me to use collection efficiently. 帮助我有效地使用收藏集。

PS : Trying to improve this way How to compare dictionaries and see what changed? PS:尝试通过这种方式进行改进如何比较字典,看看有什么变化?

You need to pass a callable (function / class / method) which will return a default value, not a default value itself. 您需要传递一个可调用的(函数/类/方法),该可调用的函数将返回默认值,而不是默认值本身。

Follow expression: 遵循表达式:

collections.defaultdict(set())

should be replaced with: 应替换为:

collections.defaultdict(set)

UPDATE UPDATE

You need to create defaultdict s outside of the for loops: 您需要在for循环之外创建defaultdict

self.old_port_dict = collections.defaultdict(set)
for s in self.prev_report.hosts:
    for x in s.get_open_ports():
        self.old_port_dict[s.address].add(x)

self.new_port_dict = collections.defaultdict(set)
for s in self.report.hosts:
    for x in s.get_open_ports():
        self.new_port_dict[s.address].add(x)

To answer the question in your title, you need to do 要回答标题中的问题,您需要做

collections.defaultdict(set)

You need to pass in something that can be instantiated. 您需要传递一些可以实例化的东西。 Passing in collections.defaultdict(set()) is passing in something that already is instantiated. 传入collections.defaultdict(set())传入实例化的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM