0

相互に (多くの場合循環) 参照を持つオブジェクトをいくつか作成する必要があります。一般に、複数のオブジェクトが関与する可能性がありますが、ここでは、相互に参照する 1 組の車だけが必要な単純なケースを 1 つ示します。

class Car:
  def __init__(self, position, speed):
    self.position = position
    self.speed = speed
  def set_reference(self, other_car):
    self.other_car = other_car
  # ...


def main():
  # ...
  car1 = Car(pos1, spd1)
  car2 = Car(pos2, spd2)
  car1.set_reference(car2)
  car2.set_reference(car1)

他の車への参照がない車は有効なオブジェクトではありません。理想的には、メソッドset_reference内から実行したいと思います。__init__これは、より安全 (無効なオブジェクトを使用する可能性がない) であり、クリーン (すべての初期化が__init__期待どおりに実行される) の両方になります。

この目標を達成するきちんとした解決策はありますか? 一度に 2 台の車を作成してもかまいませんが、各車はスタンドアロンのエンティティであるため、それ自体がインスタンスである必要があります。

また、循環参照が GC にとって厄介であることも認識しています。私はそれを処理します。

使用事例:

各車は、他の車のバックアップとして機能します。車のインスタンスは「スマート」です。つまり、多くの作業を実行できます。車のインスタンスがそのバックアップを認識していない場合、毎回外部からの参照を必要とせずに車がアクションを完了できないため、面倒です。

4

3 に答える 3

2

他の車がまだ存在しない可能性があるため、set_reference()呼び出しをに移動する良い方法はないと思います。__init__()私はおそらくこのようなことをするでしょう。

class Car:
  def __init__(self, position, speed):
    self.position = position
    self.speed = speed
  def set_reference(self, other_car):
    self.other_car = other_car
  @classmethod
  def create_pair(cls, car1_args, car2_args):
    car1 = cls(*car1_args)
    car2 = cls(*car2_args)
    car1.set_reference(car2)
    car2.set_reference(car1)
    return car1, car2

def main():
  car1, car2 = Car.create_pair((pos1, spd1), (pos2, spd2))

この同じ概念をより大きな循環参照構造に拡張する方法を次に示します。

class Car:
  # ...
  @classmethod
  def create_loop(cls, *args):
    cars = [cls(*car_args) for car_args in args]
    for i, car in enumerate(cars[:-1]):
        car.set_reference(cars[i+1])
    cars[-1].set_reference(cars[0])
    return cars

次に、次のように呼び出すことができます (任意の数の車で)。

car1, car2, car3 = Car.create_loop((pos1, spd1), (pos2, spd2), (pos3, spd3))

次のように参照を設定する必要があります。

>>> car1.other_car is car2 and car2.other_car is car3 and car3.other_car is car1
True
于 2012-04-30T19:22:33.390 に答える
0

車のデータ構造を、一連の車を参照するデータ構造から分離することをお勧めします。 other_car厳密に に属するデータのようには見えませんがcar、反復可能な車のシーケンスで表されます。したがって、最も単純で最も論理的に一貫した解決策は、車を定義してから、一連の車に入れることです。

于 2012-04-30T19:32:09.630 に答える
0

ファクトリ メソッドを本当に使用したくない場合、唯一の実際のオプションは、後でユーザーに強制的に構成させることです。(コメントで依存関係のループが必要になる可能性についてあなたが言ったことを取り入れてください):

class Car:
  def __init__(self, position, speed):
    self.position = position
    self.speed = speed

  @staticmethod
  def setup(*args):
    for car, next in zip(args, args[1:]):
      car.other_car = next
    args[-1].other_car = args[0]

def main():
  ...
  car1 = Car(pos1, spd1)
  car2 = Car(pos2, spd2)
  Car.setup(car1, car2)

もう 1 つのオプションは、グループ化を分割することです。

class CarGroup(list):
    def other_car(self, car):
        index = self.index(car)+1
        index = 0 if index >= len(self) else index
        return self[index]

class Car:
    def __init__(self, position, speed, group):
        self.position = position
        self.speed = speed
        self.group = group
        self.group.append(self)

    @property
    def other_car(self):
        return self.group.other_car(self)

def main():
    ...
    group = CarGroup()
    car1 = Car(pos1, spd1, group)
    car2 = Car(pos2, spd2, group)
于 2012-04-30T19:26:55.587 に答える