Как устранить «ошибку атрибута», например, в классах атрибутов?

#python-3.x #class #tkinter #turtle-graphics #attributeerror

#python-3.x #класс #tkinter #черепаха-графика #ошибка атрибута

Вопрос:

В моем домашнем задании нужно написать функции в двух классах (Person и World), и я почти уверен, что мой код правильный. Однако,

«Ошибка атрибута: объект ‘World’ не имеет атрибута ‘destination'»

продолжает отображаться, когда self.destination существует только в классе Person.

Похоже, что слово «self» теперь относится к мировому классу, и я не могу понять, почему.

 class Person:
    def __init__(self, world_size):
        self.world_size = world_size
        self.radius = 7
        self.location = turtle.position()#this cause attribute error
        self.destination = self._get_random_location()#and this causes too

    #moves person towards the destination
    def move(self):
        turtle.setheading(turtle.towards(self.destination))
        turtle.forward(self.radius/2)
  

Должен ли я заменять «self» другими словами для класса Person? Если да, то как я мог это сделать?

 
class World:
    def __init__(self, width, height, n):
        self.size = (width, height)
        self.hours = 0
        self.people = []
        self.add_person()

    #everything involve of Person class in World class
    #add a person to the list
    def add_person(self):
        person = Person(1)
        self.people.append(person)

    def simulate(self):
        self.hours  = 1
        Person.update(self)

    def draw(self):
        p = Person(self)
        p.draw()
  

**

 Exception in Tkinter callback
Traceback (most recent call last):
  File "C:Users AppDataLocalProgramsPythonPython37libtkinter__init__.py", line 1702, in __call__
    return self.func(*args)
  File "C:Users AppDataLocalProgramsPythonPython37libtkinter__init__.py", line 746, in callit
    func(*args)
  File "C:UsersDesktopVIRUS_PART_A.py", line 261, in __animation_loop
    self.tick()
  File "C:UsersDesktopVIRUS_PART_A.py", line 216, in next_turn
    self.world.simulate()
  File "C:UsersDesktopVIRUS_PART_A.py", line 124, in simulate
    Person.update(self)
  File "C:UsersDesktopVIRUS_PART_A.py", line 71, in update
    Person.move(self)
  File "C:UsersDesktopVIRUS_PART_A.py", line 79, in move
    turtle.setheading(turtle.towards(self.destination))
AttributeError: 'World' object has no attribute 'destination'
  

**

Комментарии:

1. Покажите нам свое World определение класса

2. Проблемы, похоже, связаны с def simulate и def draw ; когда вы говорите обновить всех пользователей для simulate, означает ли это обновить каждого пользователя внутри self.people ? ваш конструктор People, похоже, принимает мировой размер, но вы передаете объект world в draw , так что можете ли вы объяснить, каково желаемое поведение и здесь?

3. можете ли вы также включить полную обратную трассировку ошибки?

4. «обновить всех пользователей» просто означает вызов метода обновления в классе Person и self.people — это список, в котором хранится информация о пользователе из класса Person, а для объекта world, если я просто использую’person.draw(self)’ для вызова draw лично, «AttributeError: объект ‘World’ не имеет атрибута ‘radius'», это появится, поскольку мне нужно использовать self.radius для создания точки.

5. если у вас есть radius in Person и у вас есть Person in World as self.people[0] , тогда World вы не можете использовать self.radius , но self.people[0].radius

Ответ №1:

У вас есть Person в списке self.people , поэтому вы должны использовать этот список в цикле

 def simulate(self):
    self.hours  = 1
    for item in self.people:
        item.update(self)

def draw(self):
    for item in self.people:
        item.draw()
  

Возможно, в Person вы используете Person.move() , но вам следует использовать self.move() или что-то подобное.

Комментарии:

1. Но могу я спросить, как python узнал, что ‘item.update (self)’ вызывает метод в классе Person?

2. item из списка, self.people и в add_person() вы создаете Person() и добавляете его в self.people — так item и должно быть Person . Вы можете проверить это с помощью print( type(item) )