class MyClass(object):
    next_number = 0

    def __init__(self):
        self.number = self.next_number
        MyClass.next_number += 1

class MyClassA(MyClass):
    pass

上面显示的是,在更新第6行的类变量时,我被迫硬编码类名,因为:
self.__class__.next_number += 1

在任何派生类中生成新的类变量除了硬编码类名,还有别的选择吗?
我也应该在第5行写下:
self.number = self.__class__.next_number

下一个数显然是一个类变量。

最佳答案

避免重新绑定类变量问题的一种方法是用包含其内部数字的可变对象替换不可变整数值然后可以在适当的地方对对象进行变异。
一个简单的版本是将数字放在一个元素列表中:

class MyClass(object):
    next_number = [0]

    def __init__(self):
        self.number = self.next_number[0]
        self.next_number[0] += 1

很好,但不太优雅。
一个更好的方法是用itertools.count函数返回的迭代器替换整型类变量,每次调用next函数时,迭代器将连续产生更高的整数(永远是一个无限迭代器)在较高的级别上,这仍然像列表代码一样工作,因为next会对迭代器进行变异,但确切的细节隐藏在迭代器协议(以及itertools.count的实现)后面。
class MyClass(object):
    number_iter = itertools.count()

    def __init__(self):
        self.number = next(self.number_iter) # this mutates number_iter by consuming a value

如果您需要一些更复杂的东西,比如itertools没有提供正确的序列,您可以编写自己的生成器函数并将其返回值赋给类变量。例如,这里有一个fibonacci序列的生成器:
def fib():
    a, b = 0, 1
    while True:
        a, b = b, a+b
        yield a

10-06 08:40