我今天遇到了一个奇怪的问题,这是一些示例代码
from collections import defaultdict
class Counter:
hits = 0
visitors = set()
def addHit(self, ip):
self.hits += 1
self.visitors.add(ip)
d = defaultdict(Counter)
d['a'].addHit('1.1.1')
d['a'].addHit('2.2.2')
d['b'].addHit('3.3.3')
print d['a'].hits, d['a'].visitors
print d['b'].hits, d['b'].visitors
预期结果:
2 set(['1.1.1', '2.2.2'])
1 set(['3.3.3'])
实际结果:
2 set(['1.1.1', '3.3.3', '2.2.2'])
1 set(['1.1.1', '3.3.3', '2.2.2'])
为什么访问者在我认为应该是Counter类的单独实例之间共享数据。每个输入都不应该指向特定的实例吗?
更难以理解的是,点击计数器似乎工作正常并且保持分离。
任何人都可以帮助我了解这里发生了什么或如何解决它?
答案 0 :(得分:4)
我怀疑你的访客集是一个类变量而不是实例变量。
与defaultdicts行为无关。
尝试:
class Counter:
def __init__(self):
self.hits = 0
self.visitors = set()
def addHit(self, ip):
self.hits += 1
self.visitors.add(ip)
编辑: 与您的问题无关,只是如何扩展您的柜台的一些想法:
#! /usr/bin/python3.2
class Counter:
def __init__(self):
self.__hits = 0
self.__visitors = {}
def addHit(self, ip):
self.__hits += 1
if ip not in self.__visitors:
self.__visitors [ip] = 0
self.__visitors [ip] += 1
@property
def hits (self):
return self.__hits
@property
def uniqueHits (self):
return len (self.__visitors)
@property
def ips (self):
return (ip for ip in self.__visitors)
def __getitem__ (self, ip):
return 0 if ip not in self.__visitors else self.__visitors [ip]
c = Counter ()
c.addHit ('1.1.1.1')
c.addHit ('1.1.1.1')
c.addHit ('1.1.1.1')
c.addHit ('1.1.1.1')
c.addHit ('1.1.1.2')
c.addHit ('1.1.1.2')
c.addHit ('1.1.1.3')
print (c.hits)
print (c.uniqueHits)
for ip in c.ips:
print (ip, c [ip] )
答案 1 :(得分:2)
这与Multiple Instances of a Python Object are acting like the same instance
完全相同您正在使用班级变量。将其更改为
class Counter:
def __init__(self):
self.hits = 0
self.visitors = set()
def addHit(self, ip):
self.hits += 1
self.visitors.add(ip)