Начнем с того, что я переименую 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__
и __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
или type(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
и т. Д.