首先,我将重命名UserClass
为User
(我们知道它是一个类)和UserID
(id
它在User
类中,因此无需重复“用户”位,Python 风格推荐小写)和__user_id_counter
(__id_counter
同上)。阅读PEP 8了解 Python 风格指南。
那么,我们的出发点是:
class User(object):
__id_counter = 0
def __init__(self, id=None) :
self.id = self.__id_counter if id is None else id
__id_counter += 1
myuser = User()
myuser2 = User()
myuser3 = User()
现在,双前导下划线(没有像__init__
and之类的双尾下划线__metaclass__
)是特殊的,用于实现类私有变量 - 请阅读Python 手册中的私有变量以获取更多信息。它触发了所谓的“名称修改”。它最终__id_counter
被重命名为_User__id_counter
整个班级。这既有用又危险。在这种情况下,我认为这可能只是没有必要。
这可能导致子类出现问题。
class SpecialUser(User):
def __init__(self):
self.__id_counter
现在,SpecialUser()
将触发AttributeError: 'SpecialUser' object has no attribute '_SpecialUser__id_counter'
.
那么问题来了,您希望子类具有相同的ID 计数器,还是它们自己的ID 计数器?
如果您希望它们具有相同的ID 计数器,请使用User.__id_counter
. 不要将self.__class__.__id_counter
ortype(self).__id_counter
与 一起使用+= 1
,例如,这将SpecialUser
设置SpecialUser._User__id_counter
为User._User__id_counter + 1
,然后从此时开始SpecialUser
使用它自己的,这与您想要的相去甚远。 _User__id_counter
如果您希望他们拥有自己的ID 计数器,请从使用_id_counter
而不是开始__id_counter
,因为名称修改会将您带到您不想去的方向。
您可以采取以下几种方法:
使用元类为每个类提供自己的计数器变量(这是一个比我目前无法写的更高级的主题,如果您愿意,请询问更多详细信息)。
_id_counter = 0
在每个类定义中加入一行。(如果你不这样做,你会在 ID 起点遇到麻烦 - 制作很多它们,例如User(), User(), SpecialUser(), User(), SpecialUser(), SpecialUser(), User()
,它们将具有(分别)0, 1, 2, 2, 3, 4, 3
而不是0, 1, 0, 2, 1, 2
.
在这里使用名称修饰方法会产生的另一个低效率是子类将有多个计数器 - _User__id_counter
,_SpecialUser__id_counter
等。