为什么 `x += a + d[x]` 工作正常但 `x +=a; x += d[x]` 失败?
Why `x += a + d[x]` works fine but `x +=a; x += d[x]` fails?
我最近重构了这段代码,但我弄坏了它:
if from_mac in self.announces:
from_mac += '\nAnnounces: ' + ',\n'.join(self.announces[from_mac])
if to_mac in self.announces:
to_mac += '\nAnnounces: ' + ',\n'.join(self.announces[to_mac])
经过我的重构,为了让行更短,它看起来像这样:
if from_mac in self.announces:
from_mac += '\nAnnounces: '
from_mac += ',\n'.join(self.announces[from_mac])
if to_mac in self.announces:
to_mac += '\nAnnounces: '
to_mac += ',\n'.join(self.announces[to_mac])
变量的类型是:
to_mac, from_mac -> string
self.announces = defaultdict(list) # of strings
这种重构的不良影响是我得到这样的字符串:
"\nAnnounces: \nAnnounces: \nAnnounces: "
这可能是什么原因?
上下文
这是整个函数及其输出:
def print_report(self, skip_broadcast=False):
"""
Prints out a DOT file based on the gathered information.
"""
sys.stderr.write("%s\n" % repr(self.announces))
print("strict digraph {")
for from_mac in self.seen:
sys.stderr.write("k1=%s\n" % from_mac)
for to_mac in self.seen[from_mac]:
sys.stderr.write("k2=%s\n" % to_mac)
if skip_broadcast and (from_mac == '?' or to_mac == '?'):
continue
if from_mac in self.announces:
from_mac += '\nAnnounces: '
from_mac += ',\n'.join(self.announces[from_mac])
if to_mac in self.announces:
to_mac += '\nAnnounces: '
to_mac += ',\n'.join(self.announces[to_mac])
print('"%s" -> "%s";' % (from_mac, to_mac))
print("}")
并且输出:
defaultdict(<type 'list'>, {'Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)': ['FajnaSiec']})
strict digraph {
k1=Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)
k2=IPv6mcast_01\n(33:33:00:00:00:01)
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: " -> "IPv6mcast_01\n(33:33:00:00:00:01)";
k2=IPv4mcast_01\n(01:00:5e:00:00:01)
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: \nAnnounces: " -> "IPv4mcast_01\n(01:00:5e:00:00:01)";
k2=Tp-LinkT_20:74:8b\n(e8:94:f6:20:74:8b)
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: \nAnnounces: \nAnnounces: " -> "Tp-LinkT_20:74:8b\n(e8:94:f6:20:74:8b)";
k2=?
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: \nAnnounces: \nAnnounces: \nAnnounces: " -> "?";
k1=SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)
k2=Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)
"SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)" -> "Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: ";
k1=?
k2=Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)
"?" -> "Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: ";
k2=SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)
"?" -> "SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)";
k2=?
"?" -> "?";
}
正如用户 lurker
在他的评论中所说,这是因为第一个表达式更改了 from_mac
的内容,然后字典中的查找失败。一种解决方案是引入一个仅用于显示的新变量。
我最近重构了这段代码,但我弄坏了它:
if from_mac in self.announces:
from_mac += '\nAnnounces: ' + ',\n'.join(self.announces[from_mac])
if to_mac in self.announces:
to_mac += '\nAnnounces: ' + ',\n'.join(self.announces[to_mac])
经过我的重构,为了让行更短,它看起来像这样:
if from_mac in self.announces:
from_mac += '\nAnnounces: '
from_mac += ',\n'.join(self.announces[from_mac])
if to_mac in self.announces:
to_mac += '\nAnnounces: '
to_mac += ',\n'.join(self.announces[to_mac])
变量的类型是:
to_mac, from_mac -> string
self.announces = defaultdict(list) # of strings
这种重构的不良影响是我得到这样的字符串:
"\nAnnounces: \nAnnounces: \nAnnounces: "
这可能是什么原因?
上下文
这是整个函数及其输出:
def print_report(self, skip_broadcast=False):
"""
Prints out a DOT file based on the gathered information.
"""
sys.stderr.write("%s\n" % repr(self.announces))
print("strict digraph {")
for from_mac in self.seen:
sys.stderr.write("k1=%s\n" % from_mac)
for to_mac in self.seen[from_mac]:
sys.stderr.write("k2=%s\n" % to_mac)
if skip_broadcast and (from_mac == '?' or to_mac == '?'):
continue
if from_mac in self.announces:
from_mac += '\nAnnounces: '
from_mac += ',\n'.join(self.announces[from_mac])
if to_mac in self.announces:
to_mac += '\nAnnounces: '
to_mac += ',\n'.join(self.announces[to_mac])
print('"%s" -> "%s";' % (from_mac, to_mac))
print("}")
并且输出:
defaultdict(<type 'list'>, {'Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)': ['FajnaSiec']})
strict digraph {
k1=Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)
k2=IPv6mcast_01\n(33:33:00:00:00:01)
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: " -> "IPv6mcast_01\n(33:33:00:00:00:01)";
k2=IPv4mcast_01\n(01:00:5e:00:00:01)
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: \nAnnounces: " -> "IPv4mcast_01\n(01:00:5e:00:00:01)";
k2=Tp-LinkT_20:74:8b\n(e8:94:f6:20:74:8b)
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: \nAnnounces: \nAnnounces: " -> "Tp-LinkT_20:74:8b\n(e8:94:f6:20:74:8b)";
k2=?
"Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: \nAnnounces: \nAnnounces: \nAnnounces: " -> "?";
k1=SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)
k2=Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)
"SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)" -> "Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: ";
k1=?
k2=Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)
"?" -> "Cisco-Li_99:13:54\n(58:6d:8f:99:13:54)\nAnnounces: ";
k2=SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)
"?" -> "SamsungE_05:50:0e\n(00:e3:b2:05:50:0e)";
k2=?
"?" -> "?";
}
正如用户 lurker
在他的评论中所说,这是因为第一个表达式更改了 from_mac
的内容,然后字典中的查找失败。一种解决方案是引入一个仅用于显示的新变量。