1

次の形式のクラスがあるとしましょう。

class A(models.Model):
   attrA = models.CharField()
class B(A):
   attrB = models.CharField()
class C(A):
   attrC = models.CharField()

次に、B のインスタンスを作成します。

b = B()

ここで、いくつかの決定に基づいて、そのオブジェクト b を C クラスのインスタンスに変換したいと考えましたが、attrC 属性を使用できるようにしました。それは可能ですか?

4

2 に答える 2

2

Python では、次のようにオブジェクトのクラスを変更できます。

b.__class__=C

次に、クラス C に定義されていない場合でも、B のすべての属性を使用できます。b は現在クラス C のインスタンスですが、C の属性はありません。オブジェクトをデータベースに保存する (または Model クラスの他のメソッドを呼び出す) 前に、クラス C の残りのすべての属性を追加する必要があります。それが機能することを証明するために、単純なアプリを作成しました。ここに私のモデルがあります:

class A(models.Model):
    attrA = models.CharField(max_length=128)
    class Meta:
        abstract=True
class B(A):
    attrB = models.CharField(max_length=128)
class C(A):
    attrC = models.CharField(max_length=128)

そして、ここに私のテストがあります:

class ABCTestCase(TestCase):
    def test_changing_classes(self):
        """Changing classes"""
        a = A()
        self.assertIsInstance(a, A)
        a.attrA='bacon'
        self.assertEqual(a.attrA, 'bacon')
        a.__class__=B
        self.assertIsInstance(a, B)
        self.assertEqual(a.attrA, 'bacon')
        a.attrB='spam'
        self.assertEqual(a.attrA, 'bacon')
        self.assertEqual(a.attrB, 'spam')
        a.__class__=C
        self.assertIsInstance(a, C)
        self.assertIsInstance(a, A)
        self.assertNotIsInstance(a, B)
        a.attrC='egg'
        self.assertEqual(a.attrA, 'bacon')
        self.assertEqual(a.attrB, 'spam')
        self.assertEqual(a.attrC, 'egg')
        a.id=None
        a.save()
        self.assertIsNotNone(a.id)

テストの結果はOKです。

より安全な方法は、B から C へ、または C から B へ変換するクラスごとにメソッドを定義することです。

于 2013-11-14T02:32:14.947 に答える
-3

b = C() は、ローカル変数 b を C クラスのインスタンスにします。なぜあなたがこれをしたいのか分かりません。あなたのコードをもっと投稿できますか?

于 2013-11-14T02:22:54.540 に答える