Python类如何计算对象存在的数量;而不是对象被创建的数量。

huangapple go评论61阅读模式
英文:

Python class how to count object exists; not object created

问题

    # 尝试计算存在的员工数量
    class Employee:

        num_employee=0
        def __init__(self, n, a, g, s):
            self.name = n
            self.age = a
            self.gender = g
            self.pay = s

            Employee.num_employee+=1

    emp_1 = Employee('Lucifer', 27, 'male', 50000)
    emp_2 = Employee('Chloe', 23, 'female', 60000)
    emp_2 = Employee('Dan', 27, 'male', 40000)
    # emp_2 被重写

    print(Employee.num_employee)
    # 需要 2 但输出为 3
英文:

> I need to count object exists those are created by specific class.
> I am aware of adding counter in init. But what if I overwrite an object later.
> For say
>
> emp_1 = Employee('Lucifer', 'male')
> emp_2 = Employee('Chloe', 'female')
> emp_2 = Employee('Dan', 'male')
>
> Here I called init method thrice but created only two objects. i.e I overwrite emp_2
>
> Can anyone help me this out

    #Trying to count employee exists
    class Employee:

        num_employee=0
        def __init__(self, n, a, g, s):
            self.name = n
            self.age = a
            self.gender = g
            self.pay = s

            Employee.num_employee+=1

    emp_1 = Employee('Lucifer', 27, 'male', 50000)
    emp_2 = Employee('Chloe', 23, 'female', 60000)
    emp_2 = Employee('Dan', 27, 'male', 40000)
    # emp_2 overwrote

    print(Employee.num_employee)
    # needed 2 getting 3 as output`

答案1

得分: 0

当对象销毁时,会调用其 __del__ 方法。你可以在那里递减你的计数器:

class Employee:
   def __del__(self):
      Employee.num_employee -= 1

但这将是一个非常脆弱的解决方案。你不知道垃圾收集器何时运行。对象可能比预期更晚销毁。你可以强制执行垃圾回收算法,但这不是一个良好的做法。

我不知道你试图做什么,但相当确定一个更好的解决方案是使用一个保存员工计数的容器。

如果你复制你的实例,这个解决方案会变得棘手。假设你实现了建议的 __del__ 方法。看一下这段代码:

import copy

emp_1 = Employee('Lucifer', 27, 'male', 50000)  # Employee.num_employee = 1
emp_2 = copy.deepcopy(emp_1)  # Employee.num_employee = 1
emp_3 = copy.deepcopy(emp_1)  # Employee.num_employee = 1

emp_1 = None  # Employee.num_employee = 0
emp_2 = None  # Employee.num_employee = -1
emp_3 = None  # Employee.num_employee = -2

# 打印结果为 -2
print(Employee.num_employee)

要解决这个问题,你应该在每次创建新对象时递增计数器。也就是说,在 __new__ 方法中。这将得到如下代码:

class Employee:

    num_employee = 0
    
    def __new__(cls, *args, **kwargs):
        Employee.num_employee += 1
        return super().__new__(cls)
        
    def __init__(self, n, a, g, s):
        self.name = n
        self.age = a
        self.gender = g
        self.pay = s
        
    def __del__(self):
        Employee.num_employee -= 1
英文:

When an object dies its __del__ method is called. You can decrement your counter there:

class Employee:
   def __del__(self):
      Employee.num_employee -= 1

But this would be a very fragile solution. You don't know when the garbage collector will run. Objects could die later than expected. You can force the garbage collection algorithm to run but it is not a good practice.

I don't know what are you trying to do, but pretty sure a better solution would be a container that keeps your employee count.

This solution gets tricky if you copy your instances. Let's say you implement the proposed __del__ method. Take a look at this code:

import copy

emp_1 = Employee('Lucifer', 27, 'male', 50000) # Employee.num_employee = 1
emp_2 = copy.deepcopy(emp_1)  # Employee.num_employee = 1
emp_3 = copy.deepcopy(emp_1)  # Employee.num_employee = 1

emp_1 = None  # Employee.num_employee = 0
emp_2 = None  # Employee.num_employee = -1
emp_3 = None  # Employee.num_employee = -2

# Prints -2
print(Employee.num_employee)

To solve this you should increment your counter every time a new object is created. That is: in the __new__ method. This will give a code like this:

class Employee:

    num_employee = 0
    
    def __new__(cls, *args, **kwargs):
        Employee.num_employee += 1
        return super().__new__(cls)
        
    def __init__(self, n, a, g, s):
        self.name = n
        self.age = a
        self.gender = g
        self.pay = s
        
    def __del__(self):
        Employee.num_employee -= 1

huangapple
  • 本文由 发表于 2023年2月8日 19:52:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385423.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定