【问题标题】:How to change a class attribute inside __init__?如何更改 __init__ 中的类属性?
【发布时间】:2017-02-06 11:48:58
【问题描述】:
class Ant:
    count = 0

    def __init__(self):
        if count == 0:
            self.real = True
        else:
            self.real = False
        count += 1

所以基本上我想要实现的是我只希望这个类的第一个实例具有“真实”属性为True,后续属性为False。我现在知道这会给我count 的 unboundlocal 错误。我该如何完成这项工作?

【问题讨论】:

  • count inside __init__ 只是一个普通的局部变量。您需要Ant.count 才能访问类级别变量

标签: python class attributes


【解决方案1】:

count更改为Ant.count

由于count是一个类成员(在Ant类的所有实例之间共享)并且不属于特定的实例,所以你应该使用它与类名的前缀。

class Ant:
    count = 0

    def __init__(self):
        if Ant.count == 0:
            self.real = True
        else:
            self.real = False
        Ant.count += 1

【讨论】:

  • self.count 也可以工作,并且不需要将类名硬编码到函数中(因此,如果类名发生更改,则不需要修复)。
  • @martineau 不,self.count 将是一个实例变量 - 这非常具体 不是 OP 想要的。他们想要一个类变量,所以 Ant.count 是(也许是唯一的)正确引用它的方法。
  • 哎呀,是的,你是对的。 self 仅适用于读取类变量值,而不适用于更改它,这将创建一个实例变量作为副作用(并在此后隐藏类属性)。也就是说,仍然可以通过使用self.__class__ 来避免在代码中到处对类名进行硬编码。如果太长,可以在方法的开头使用cls = self.__class__ 创建一个局部变量,并在其中使用。
【解决方案2】:

首选使用self.__class__.variable - 除非您希望所有子类共享同一个变量。

在这样的代码中:

class Ant:
    count = 0

“计数”值存储在类的__dict__ 属性中。 如果您执行以下操作:

class Ant:
    count = 0
    def __init__(self):
         print(self.count)

Python 的数据模型中定义的属性访问机制将看到实例“self”中没有count 的实例,并从其类中检索值。因此,如果您正在读取类变量中的值,则可以像使用普通实例一样使用它。

但是,如果您的代码如下:

def __init__(self):
    self.count += 1

在完全不同的情况下会发生什么:Python 从上面的类中读取属性,将其加 1,并将新结果存储在实例中。

因此,无论何时您想要访问类值,您都可以硬编码类名 - (因为在运行方法代码时,该类已经创建并且是“已知的”):

class Ant:
    count = 0
    def __init__(self):
         Ant.count += 1

或者,更好的是,使用实例的 __class__ 属性 - 这样您将始终获得正确子类的变量值

class Ant:
     count = 0
     def __init__(self):
         self.__class__.count += 1

class FireAnt(Ant):
     count = 0

(注意,和上面的第二个例子一样,如果子类不包含自己的count变量,则将读取来自超类'count的值,第一次将在子类上创建一个新的此代码已运行)

【讨论】:

    猜你喜欢
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多