Создать список objectA внутри objectA

Когда я пытаюсь append() сам объект в список внутри объекта, это не работает, я не понимаю, почему.

class PLayer:

    CLASS_NAME = "player"
    TOTAL_PLAYER_NUMBER = 0
    TOTAL_PLAYER_LIST = []
    PLAYER_ID_INCREMENT = 0

    def __init__(self, name,
                 first_name,
                 birthday,
                 note,
                 player_id=None,
                 total_score=None,
                 tournament_score=None):

        self.PLAYER_ID_INCREMENT += 1
        self.TOTAL_PLAYER_NUMBER += 1
        self.name = name
        self.first_name = first_name
        self.birthday = birthday
        self.player_id = self.PLAYER_ID_INCREMENT
        self.total_score = 0
        self.tournament_score = 0
        self.note = note
        self.TOTAL_PLAYER_LIST.append(self.Player)

Итак, у класса Player есть список TOTAL_PLAYER_LIST = [], затем внутри __init__ я хочу добавить только что созданного игрока в список с последней строкой self.TOTAL_PLAYER_LIST.append(self.Player), но получаю эту ошибку

line 25, in __init__
    self.TOTAL_PLAYER_LIST.append(self.Player)
AttributeError: 'PLayer' object has no attribute 'Player'

Я не понимаю, почему. Я пробовал ставить и удалять self., скобки также () для Player() .

Player.TOTAL_PLAYER_LIST.append(себя)

Prudhviraj 10.02.2023 12:00

Что ж, класс PLayer действительно не имеет атрибута player...

Ftagliacarne 10.02.2023 12:05
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Удалите атрибут .Player

Если вы это сделаете, это работает нормально. В вашем классе нет атрибута Player. Игрок, которого вы хотите добавить, указан в переменной self, экземпляре.

        self.TOTAL_PLAYER_LIST.append(self)

Давайте рассмотрим более простой пример с отладкой:

class Player:
    TOTAL_PLAYER_NUMBER = 0
    TOTAL_PLAYER_LIST = []
    PLAYER_ID_INCREMENT = 0

    def __init__(self, name):
        self.PLAYER_ID_INCREMENT += 1
        self.TOTAL_PLAYER_NUMBER += 1
        self.name = name
        self.player_id = self.PLAYER_ID_INCREMENT
        self.TOTAL_PLAYER_LIST.append(self)

    def __repr__(self):
        return f"{self.name}:<{self.player_id}>"

print(Player("Doe"))  # Doe:<1>
print(Player.TOTAL_PLAYER_LIST)  # [Doe:<1>]

Другая критическая проблема с вашим кодом

  1. Назовите свой класс Player, а не PLayer

  2. Атрибут класса против атрибута экземпляра

        self.PLAYER_ID_INCREMENT += 1

Это не изменит атрибут класса PLAYER_ID_INCREMENT, просто создайте атрибут экземпляра 1:

doe = Player("Doe")
joe = Player("joe")
print(Player.TOTAL_PLAYER_NUMBER)  # 0
print(doe.TOTAL_PLAYER_NUMBER)  # 1
print(joe.TOTAL_PLAYER_NUMBER)  # 1

Исправьте это с помощью:

    def __init__(self, name):
        Player.PLAYER_ID_INCREMENT += 1
        Player.TOTAL_PLAYER_NUMBER += 1
        ...

doe = Player("Doe")
joe = Player("joe")
print(Player.TOTAL_PLAYER_NUMBER)  # 2
print(doe.TOTAL_PLAYER_NUMBER)  # 2
print(joe.TOTAL_PLAYER_NUMBER)  # 2

Это происходит потому, что целые числа являются неизменяемыми, а += «перепривязывает» увеличенное значение к новой ссылке, расположенной... в self, пространстве имен экземпляра, а не пространстве имен класса.

Более питонический способ сделать это с помощью метаклассов:

import typing


class CountInstances(type):
    def __init__(cls, name, bases, dict_):
        super().__init__(name, bases, dict_)
        cls.count = 0

    def __call__(cls, *args, **kwargs):
        cls.count += 1
        return super().__call__(*args, **kwargs)


class Player(metaclass=CountInstances):
    total_player_list: typing.Final = []

    def __init__(self, name):
        self.name = name
        self.player_id = self.count
        self.total_player_list.append(self)

    def __repr__(self):
        return f"{self.name}:<{self.player_id}>"


doe = Player("Doe")
joe = Player("Joe")
print(Player.count)  # 2
print(doe.count)  # 2
print(joe.count)  # 2
print(Player.total_player_list)  # [Doe:<1>, Joe:<2>]

Подробнее о метаклассах: Что такое метаклассы в Python?

Другие вопросы по теме