Циркулярные ссылки между методами классов в Python - PullRequest
0 голосов
/ 28 марта 2020

В моем коде есть два класса, которые зависят друг от друга следующим образом.

class Shepherd:

    def __init__(self, name='Bob', address='Shepherd Way 1', sheep=[]):
        self.name=name
        self.address=address
        self.sheep=sheep # a list of objects of the class Sheep

class Sheep:

    def __init__(self, shepherd=Shepherd(), address=None, color='brown'):
        self.color=color
        # a sheep inherits the shepherd's address
        self.address=shepherd.address
        # and it gets added to the shepherd's list of sheep
        shepherd.sheep = shepherd.sheep + [self]

    def set_color(self, color='white'):
        self.color=color

Теперь я хотел бы добавить метод set_sheep_color() в класс Shepherd. Этот метод должен использовать метод set_color для каждой овцы, которая есть у пастуха. Проблема в том, что я не могу этого сделать, потому что set_color определяется после класса Shepherd. Однако я не могу переместить определение класса Sheep до класса Shepherd, потому что я использую Shepherd() в классе Sheep. Как я могу добавить set_sheep_color() в класс Shepherd после определения? Или есть лучший способ решить эту проблему?

1 Ответ

1 голос
/ 28 марта 2020
class Shepherd:
  ...
  def set_sheep_color(self, color):
    for s in self.sheep:
        s.set_color(color)

Имена, которые прикреплены к объекту, не проверяются до тех пор, пока строка кода фактически не будет выполнена. Не имеет значения, если вы определяете до того, как определите класс Sheep; это имеет значение только, если вы используете до запускаете класс овец. Что вы явно уже сделали, так как вы инициализировали Пастыря с некоторым количеством овец, которые должны уже существовать.

Другими словами, когда python смотрит на переменные и методы, прикрепленные к объекту, он смотрит на объект в том виде, в котором он существует , а не на спецификацию объекта.

...