首先,我将重命名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_counterortype(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等。