python - 可变类变量和 super().__init__ 的行为
问题描述
我试图理解为什么我的代码的行为方式是这样的。基本上,我以两种方式创建了父类和子类。我想要发生的是,在为两个类创建的每个实例上,init方法将更新每个相应类的 num_of_emps 计数。所以如果我有类似的东西:
class Employee:
num_of_emps = 0
def __init__(self, first, last, pay, division):
self.first = first
self.last = last
self.pay = pay
self.division = division
Employee.num_of_emps += 1
class Manager(Employee):
num_of_emps = 0
def __init__(self, first, last, pay, division):
self.first = first
self.last = last
self.pay = pay
self.division = division
Manager.num_of_emps += 1
emp1 = Employee("Dallas", "Mat", 100000, "Sales")
emp2 = Employee("Mark", "Doe", 50000, "Marketing")
emp3 = Employee("Jane", "Doe", 50000, "Advertisement")
man1 = Manager("Bob", "Ben", 200000, "Marketing")
man2 = Manager("Ryan", "DS", 200000, "Advertisement")
# Employee.num_of_emps returns 3
# Manager.num_of_emps returns 2
这就是我要的。但是,如果我添加一个超级。init () 方法而不是硬编码 Manager 类的属性,会发生其他事情:
class Employee:
num_of_emps = 0
def __init__(self, first, last, pay, division):
self.first = first
self.last = last
self.pay = pay
self.division = division
Employee.num_of_emps += 1
class Manager(Employee):
num_of_emps = 0
def __init__(self, first, last, pay, division):
super().__init__(first, last, pay, division)
Manager.num_of_emps += 1
emp1 = Employee("Dallas", "Mat", 100000, "Sales")
emp2 = Employee("Mark", "Doe", 50000, "Marketing")
emp3 = Employee("Jane", "Doe", 50000, "Advertisement")
man1 = Manager("Bob", "Ben", 200000, "Marketing")
man2 = Manager("Ryan", "DS", 200000, "Advertisement")
# Employee.num_of_emps returns 5
# Manager.num_of_emps returns 2
让我感到困惑的是,每次创建管理器实例时,父类的 num_of_emps 也会更新。我知道超级()。init方法导致了这种情况,但有人可以解释为什么吗?
解决方案
这是因为 super(). init () 调用超级初始化方法。在这种方法中,您可以增加 Manager 计数。这是继承的问题。更好的方法可能是更好地细分您的课程。
此外,在另一个答案中给出了另外两个建议,这些建议比我给出的代码示例结构更好,试图展示如何尽可能简单地划分您的问题。
class Person:
def __init__(self):
# Some stuff
pass
class Employee(Person):
counter = 0
def __init__(self):
super().__init__()
# Some stuff
Employee.counter += 1
pass
class Manager(Person):
counter = 0
def __init__(self):
super().__init__()
# Some stuff
Manager.counter += 1
pass
这将避免多次触发基类上的计数器属性。
推荐阅读
- debian - 构建一个没有 tarball 的 Debian 软件包
- flutter - Flutter 更改验证错误消息位置
- html - 与媒体查询相关的 HTML 和 css
- php - exec() 中的 php 变量
- ios - 如果我没有 iPad,如何在 Mac 上使用 AR 测试 swift-playground?
- typescript - 如何从我在打字稿中创建的类型中获取密钥
- node.js - 使用 superagent 测试经过身份验证的快速端点不起作用?
- html - 有没有一种方法可以在焦点处于焦点时向选择标签添加样式并且还可以查看下拉菜单
- swagger - 如何将 Swagger 与 Nest.js API 和 SPA 之间共享的 DTO 一起使用?
- sql - 按名称分组的连续日期范围内的最小和最大日期