我正在查看Stack Overflow问题Counting instances of a class?,我不确定为什么该解决方案有效,而且使用简单添加的问题并不存在。我想这更像是一个关于如何存储和访问类与实例变量的问题。
以下是我认为应该有效的代码,而是为每个4
生成id
:
class foo():
num = 3 # trying 3 instead of 0 or 1 to make sure the add is working
def __init__(self):
self.num += 1
self.id = self.num
f = foo()
g = foo()
print f.id # 4
print g.id # 4
self.num +=1
语句有些工作(添加正在进行,但不是分配)。
在此处发生此任务失败的情况下发生了什么,而itertools.count
任务在另一个问题的解决方案中成功了?
答案 0 :(得分:5)
整数不会实现__iadd__
(就地添加,+=
),因为它们是不可变的。解释器回退到标准作业而不是__add__
,所以行:
self.num += 1
变为:
self.num = self.num + 1
在右侧,您可以通过foo.num
获得3
(即self.num
),但正如您所料,这里有趣的是分配给实例属性num
阴影类属性。所以该行实际上相当于:
self.num = foo.num + 1 # instance attribute equals class attribute plus one
所有实例最终都是self.num == 4
,类仍为foo.num == 3
。相反,我怀疑你想要的是:
foo.num += 1 # explicitly update the class attribute
或者,您可以将其实现为@classmethod
,更明确地处理该类:
class Foo(): # note naming convention
num = 3
def __init__(self):
self.increment()
self.id = self.num # now you're still accessing the class attribute
@classmethod
def increment(cls):
cls.num += 1
答案 1 :(得分:4)
if (!s.toString().isEmpty()) {
try {
List<Address> addresses = geocoder.getFromLocationName(s.toString(), 4);
if (addresses.size() > 0) {
Address userAddress = addresses.get(0);
double latitude = userAddress.getLatitude();
double longitude = userAddress.getLongitude();
mRestaurantLatLng = new LatLng(latitude, longitude);
if (userAddress != null) {
mPin.setVisibility(View.VISIBLE);
} else {
mPin.setVisibility(View.GONE);
mRestaurantLatLng = null;
}
} else {
mPin.setVisibility(View.GONE);
mRestaurantLatLng = null;
}
} catch (Exception e) {
e.printStackTrace();
}
基本上意味着'获取self.num += 1
的值,递增它,并分配给self.num
。
如果没有相应的实例变量,在self.num
上查找属性将找到类变量。但是,分配将始终写入实例变量。因此,这会尝试查找实例var,失败,回退到类var,获取值,递增它,然后将分配给实例var 。
链接问题的答案起作用的原因是因为没有分配正在进行;他们直接在类变量上调用self
,它的值被改变但名称没有重新分配。
答案 2 :(得分:2)
增强赋值不会更新类变量。它这样做:
tmp = self.num
self.num = tmp.__iadd__(1)
注意在那里分配回self.num
!因此,您的类属性保持不变。整数的object.__iadd__()
method不能就地改变数字,因为整数是不可变的,所以foo.num
永远不会改变。
您需要显式引用类变量:
foo.num += 1
或
self.__class__.num += 1