【问题标题】:Python3 inherit class variable without inheriting valuePython3继承类变量而不继承值
【发布时间】:2018-08-13 02:57:14
【问题描述】:

我有一组类,它们都应该跟踪它们是哪个实例。为此,我在父类中有一个类变量,它在每个对象初始化时被复制和递增。这是一个似乎可以正常工作的最小示例:

class Parent:
    counter = 0
    def __init__(self):
        self.name = self.__class__.__name__ + "_" + str(self.__class__.counter)
        self.__class__.counter += 1

    def __repr__(self):
        return self.name

mother = Parent()
father = Parent()
print(mother)
print(father)

父母_0

父母_1

到目前为止一切顺利。现在我想使用一些具有相同行为的子类而不重写代码。所以我这样做:

class Child(Parent):
    # counter = 0
    pass

son = Child()
daughter = Child()
stepfather = Parent()

print(son)
print(daughter)
print(stepfather)

孩子_2

Child_3

父母_2

这种行为不是我想要的。当创建子对象的第一个实例时,它会继承父计数器当时具有的任何值,但是在此之后,每个类都维护自己的计数器。我可以通过将counter = 0 放入每个子类来避免这种情况,但这让我觉得多余。有没有更优雅的方法可以从父级继承行为,而不必每次都重新声明相同的变量?

【问题讨论】:

  • 不确定我的理解是否正确 - 您是希望每个子类都有自己的基于 0 的计数器,还是希望在所有基类/派生类上运行计数器?
  • 您的预期输出是什么?是所有对象共享一个柜台,还是为孩子和父母提供一个单独的柜台?
  • 抱歉不清楚。我希望每个类和子类都有自己的计数器,从 0 开始。取消注释我的代码示例中的单个注释行给出了我想要的行为。
  • 添加代码示例

标签: python-3.x inheritance class-variables


【解决方案1】:

不知道你为什么想要这种行为,但是......而不是计数器int,在Parent 中创建一个计数器dict:str->int。使用self.__class__.__name__ 的键来访问其中每个单独类的运行计数器。使用dict.setdefault(self.__class__.__name__,0) 分配它并在__init__ 内增加它。

 class Parent:
    counter = dict()

    def __init__(self):
        Parent.counter.setdefault(self.__class__.__name__,0)
        self.name = f'{self.__class__.__name__}_{Parent.counter[self.__class__.__name__]}' 
        Parent.counter[self.__class__.__name__] += 1

    def __repr__(self):
        return self.name

mother = Parent()
father = Parent()
print(mother)
print(father)

class Child(Parent):
    # counter = 0
    pass

son = Child()
daughter = Child()
stepfather = Parent()

print(son)
print(daughter)
print(stepfather)

输出:

Parent_0
Parent_1
Child_0
Child_1
Parent_2

【讨论】:

  • 这似乎完成了我正在寻找的东西。我已将 0 更改为空字典,将 init 更改为 cl = self.__class__self.name = cl.__name__ + "_" + str(cl.counter.setdefault(cl.__name__, 0)) ; cl.counter[cl.__name__] += 1 。您能否详细说明为什么这种行为对您来说很奇怪/出乎意料?
  • 我从不需要自动命名和“计算”我的类的“实例”:) 所以不需要这样做。我不太明白为什么你需要一个字典来保存计数器(或者你说的是 your 代码,而不是我添加的代码?)我的使用f''{} 格式语法。 @詹姆斯
  • 基本上我想要一个描述每个对象的唯一字符串,因为对象是 tensorflow 子图的包装器,而 tensorflow 允许您以 python 字符串的形式给变量名称。这就是为什么我想自动提供易于解释的默认值。计数器在那里,所以它不会意外地将不同的物体混在一起。我知道的 {} 格式,有时我只是忘记了它的规则 :) - 无论如何感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2015-12-09
  • 2018-01-21
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 2013-04-19
  • 2012-05-16
  • 2023-02-09
相关资源
最近更新 更多