如何在python中为类和子类添加单独的id



我有两个类:继承Ancestor类的Child类。我的目标是在不覆盖的情况下为每个实例添加id属性

代码示例:

class Ancestor(tensorflow.Module):
_id = 0
def __init__(self, some_list=):
super(Ancestor, self).__init__()
self.id = Ancestor._id + 1
Ancestor._id += 1

class Child(Ancestor):
_id = 0
def __init__(self):
self.id = Child._id + 1
Child._id += 1
some_list = [char + self.id for char in ["a", "b", "c"] ]
super(Child, self).__init__(some_list)

a1 = Ancestor()
a2 = Ancestor()
c1 = Child()
c2 = Child()

print(a1.id, a2.id, c1.id, c2.id)
>>> 1 2 3 4

我希望打印此设置:1 2 1 2

如何做到这一点?

在Child构造函数中编辑"some_list"只是为了强调Child在调用Ancestor的超级方法之前必须接收其id

Python3用户:请参阅底部,了解使用__init_subclass__的更好解决方案。


不要硬编码类名。使用type(self)可以访问每个实例的相应类。

class Ancestor(object):
_id = 0
def __init__(self):
type(self)._id += 1
self.id = self._id

class Child(Ancestor):
_id = 0
def __init__(self):
super(Child, self).__init__()
# Actual class-specific stuff here.
# If there is none, you don't even need to override __init__

a1 = Ancestor()
a2 = Ancestor()
c1 = Child()
c2 = Child()
assert (a1.id, a2.id, c1.id, c2.id) == (1,2,1,2)

或者更干净,使属性成为生成器,而不是要更新的值。请注意,由于count实例保持其自己的状态,因此不需要将back的任何内容分配给class属性,因此您可以通过实例而不是其类型访问_id

from itertools import count
class Ancestor(object):
_id = count(1)
def __init__(self, **kwargs):
super(Ancestor, self).__init__(**kwargs)
self.id = next(self._id)

class Child(Ancestor):
_id = count(1)

Python 3

您可以使用__init_subclass__来确保Ancestor的每个子代都有自己的ID生成器,而不必在类定义中显式添加它。

from itertools import count

class CountedInstance:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls._id = count(1)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.id = next(self._id)

class Ancestor(CountedInstance):
pass
class Child(Ancestor):
pass

使用type(self)而不是类名。

class Ancestor(object):
_id = 0
def __init__(self):
type(self)._id += 1
self.id = self._id
class Child(Ancestor):
_id = 0
a1 = Ancestor()
a2 = Ancestor()
c1 = Child()
c2 = Child()
print(a1.id, a2.id, c1.id, c2.id)  # -> 1 2 1 2

注意,您可以使用self.__class__来完成同样的事情,但它可以被覆盖,所以type(self)更好。

最新更新