Python静态变量分辨率

bio*_*ffe 0 python static static-variables

我正在尝试创建为特定类创建的所有实例的计数器.很明显,我的代码不会self.__class__.counter超过1.我做错了什么?

 class Feature(object):
    counter = 0
    def __init__(self, line):
        self.id = self.__class__.counter
        self.__class__.counter = self.__class__.counter + 1
    def __repr__(self):
        return "Feature: id=%d name=%s" % (self.id,self.name,)
Run Code Online (Sandbox Code Playgroud)

更新: 此代码实际上按预期工作.聪明的人留下了一些非常详细的解释,说明如何在python中处理静态.我投票决定关闭我的问题,但讨厌答案是否会消失.

Ben*_*Ben 5

这是我将如何做到这一点(虽然你的代码对我来说很好,所以我怀疑它不是你实际运行的代码来观察问题).

class Feature(object):
    counter = 0

    def __init__(self):
        self.id = Feature.counter
        Feature.counter += 1
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以替换Featuretype(self)(或self.__class__同样的东西),但请注意,在存在子类时它们的行为会有所不同(实际上这可能是您的问题).

在Python中使用类/实例变量的规则非常简单,它有助于牢记它们:

  1. 如果不直接包含名为的属性,self.name则读取属性的值将返回到类的类self,然后返回到基类层次结构.selfname
  2. 写入属性的值self.name = ... 始终name直接绑定self.

特别是,在写入值时,在赋值之前读取同一属性的位置无关紧要.

所以,如果你的实际程序你实例化一个子类Feature,我会打电话给Sub那么这行:

self.__class__.counter = self.__class__.counter + 1
Run Code Online (Sandbox Code Playgroud)

可能不会做你期望的.它会读取来自Feature.counter(您创建实例的第一次Sub),但Sub.counter.此后读取将进入Sub.counter(因为它现在存在),因此Sub实例将获得增加的ID,但它们不会增加值Feature.counter,因此其他子类的实例Feature可以获得重复的ID.

因此,Feature.counter如果我将其counter视为生成在Feature命名空间中的全局变量,我会使用它,并且我希望所有子类Feature共享相同的计数器.我会使用,type(self).counter如果我希望每个子类Feature都有自己独立的计数器(但是你需要做一些事情来初始化它们).