クラスの__new__メソッドをファクトリとして使用:__init__が2回呼び出される

xApple:

Pythonで__new__、クラスメソッドをファクトリーとして使用する__init__と、インスタンス化されたクラスのメソッドが2回呼び出されるという奇妙なバグが発生しました

本来__new__、クラスの外部でファクトリ関数を宣言する必要なしに、渡されたパラメータに応じて、母クラスのメソッドを使用して子の1つの特定のインスタンスを返すというアイデアでした

ファクトリ関数を使用することがここで使用するのに最適なデザインパターンであることは知っていますが、プロジェクトのこの時点でデザインパターンを変更するとコストがかかります。したがって、私の質問は次のとおりです。そのようなスキーマでへの二重呼び出しを回避し__init__て単一の呼び出しのみを取得する方法はあり__init__ますか?

class Shape(object):
    def __new__(cls, desc):
        if cls is Shape:
            if desc == 'big':   return Rectangle(desc)
            if desc == 'small': return Triangle(desc)
        else:
            return super(Shape, cls).__new__(cls, desc)

    def __init__(self, desc):
        print "init called"
        self.desc = desc

class Triangle(Shape):
    @property
    def number_of_edges(self): return 3

class Rectangle(Shape):
    @property
    def number_of_edges(self): return 4

instance = Shape('small')
print instance.number_of_edges

>>> init called
>>> init called
>>> 3

どんな助けも大歓迎です。

ダンカン:

オブジェクト__new__を作成すると、Pythonはそのメソッドを呼び出してオブジェクトを作成し、次に__init__返されたオブジェクトを呼び出します。あなたは内側からオブジェクトを作成するときに__new__呼び出すことによりTriangle()に対する更なる呼び出しになりますことを__new__して__init__

あなたがすべきことは:

class Shape(object):
    def __new__(cls, desc):
        if cls is Shape:
            if desc == 'big':   return super(Shape, cls).__new__(Rectangle)
            if desc == 'small': return super(Shape, cls).__new__(Triangle)
        else:
            return super(Shape, cls).__new__(cls, desc)

作成されたRectangleかをTriangleへの呼び出しをトリガすることなく__init__して、__init__一度だけ呼ばれます。

スーパーがどのように機能するかについての@Adrianの質問に答えるように編集します。

super(Shape,cls)検索cls.__mro__見つけるためShape当時と属性を見つけるために、配列の残りを下に検索します。

Triangle.__mro__である(Triangle, Shape, object)Rectangle.__mro__され(Rectangle, Shape, object)ている間Shape.__mro__だけです(Shape, object)これらのいずれの場合でも、呼び出すsuper(Shape, cls)と、mroシーケンス内のすべてのものが無視されるShapeため、残っているのは単一の要素のタプルだけで(object,)あり、それを使用して目的の属性を検索します。

ダイヤモンドの継承がある場合、これはさらに複雑になります。

class A(object): pass
class B(A): pass
class C(A): pass
class D(B,C): pass

これで、Bのメソッドが使用する可能性がsuper(B, cls)あり、それがBインスタンスである場合は検索され(A, object)ますが、Dインスタンスがある場合isであるため、同じ呼び出しでB検索さ(C, A, object)ます。D.__mro__(B, C, A, object)

したがって、この特定のケースでは、形状の構築動作を変更する新しいミックスインクラスを定義し、既存のものから継承するが異なる方法で構築された特殊な三角形と長方形を作成できます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ツイストPythonファクトリメソッドがreactorラッパーを使用しているときに呼び出されない

分類Dev

リスト内のオブジェクトごとにメソッドが1回呼び出されることを確認してください

分類Dev

__new__クラスが正しいときに__init__を呼び出さない

分類Dev

ドットソース呼び出しでネストされているときにクラスが呼び出されるスクリプトファイルの名前を取得するにはどうすればよいですか?

分類Dev

Pythonでは、サブクラスの__init__の後に自動的に呼び出されるメソッドを作成することができます。

分類Dev

メタクラスの__new__が呼び出される理由

分類Dev

同じリクエストに対して@PostConstructメソッドが2回呼び出されました

分類Dev

PowerMockitoを使用して、最終クラスのプライベート静的メソッドが呼び出されることを確認します

分類Dev

C#でリフレクションを使用してメソッドから呼び出されたメソッドのリストを取得する方法

分類Dev

PySide.QtGui RuntimeError: '__ init__'オブジェクトの基本クラスのメソッドが呼び出されていません...しかし、呼び出されました

分類Dev

スーパークラス__new__が定義されている場合、サブクラス__init__は呼び出されません

分類Dev

jqueryを使用して2回クリックしたときに呼び出されるチェックボックスのクリックイベント

分類Dev

__init__呼び出しでself.trを使用すると、「RuntimeError:%Sのスーパークラス__init __()が呼び出されませんでした」

分類Dev

抽象クラスのエラー「基本クラスの__init__メソッドが呼び出されていません」

分類Dev

RSpecを使用してコントローラーメソッドでクラスが呼び出されることをテストする方法

分類Dev

別のファイルからクラスをインポートすると__init__関数が呼び出されるのはなぜですか?

分類Dev

リンクリストクラスが別のクラスメソッドから呼び出されたときにノードを挿入しない

分類Dev

リフレクションを使用してメソッドを呼び出すと、「オブジェクトは宣言クラスのインスタンスではない」と表示されるのはなぜですか?

分類Dev

子クラスの動的メソッドは、ラムダキャプチャで使用されると、親クラスの仮想メソッドを呼び出します/セグメンテーションフォールトが発生します

分類Dev

PHPUnitを使用して、同じクラスの他のメソッドを呼び出すが値を返さないメソッドをテストする方法

分類Dev

別のクラスのメソッドを呼び出し、返されたリストを保存する

分類Dev

静的クラス メソッドは、クラスの外部で呼び出されるとオブジェクトを返しますが、異なるクラスの内部で呼び出されると空のオブジェクトを返します。

分類Dev

ソフトウェア全体で適切なパラメータを使用してメソッドが呼び出されることをテストします

分類Dev

ユーザー定義型のメタクラス__new__と__init__はどこで呼び出されますか?

分類Dev

Activityクラスを使用してフラグメントクラス内のメソッドを呼び出す

分類Dev

Python スクリプトで __init__ を呼び出すときに重複した行が表示される

分類Dev

列挙とリフレクションを使用してクラスのリストに対してメソッドを呼び出す

分類Dev

-mを指定してPythonスクリプトを実行すると、__ init__。pyが呼び出されないのはなぜですか?

分類Dev

ジェネリッククラスでジェネリックリターンを使用してメソッドを呼び出すことが、javacによって安全でないと見なされるのはなぜですか?

Related 関連記事

  1. 1

    ツイストPythonファクトリメソッドがreactorラッパーを使用しているときに呼び出されない

  2. 2

    リスト内のオブジェクトごとにメソッドが1回呼び出されることを確認してください

  3. 3

    __new__クラスが正しいときに__init__を呼び出さない

  4. 4

    ドットソース呼び出しでネストされているときにクラスが呼び出されるスクリプトファイルの名前を取得するにはどうすればよいですか?

  5. 5

    Pythonでは、サブクラスの__init__の後に自動的に呼び出されるメソッドを作成することができます。

  6. 6

    メタクラスの__new__が呼び出される理由

  7. 7

    同じリクエストに対して@PostConstructメソッドが2回呼び出されました

  8. 8

    PowerMockitoを使用して、最終クラスのプライベート静的メソッドが呼び出されることを確認します

  9. 9

    C#でリフレクションを使用してメソッドから呼び出されたメソッドのリストを取得する方法

  10. 10

    PySide.QtGui RuntimeError: '__ init__'オブジェクトの基本クラスのメソッドが呼び出されていません...しかし、呼び出されました

  11. 11

    スーパークラス__new__が定義されている場合、サブクラス__init__は呼び出されません

  12. 12

    jqueryを使用して2回クリックしたときに呼び出されるチェックボックスのクリックイベント

  13. 13

    __init__呼び出しでself.trを使用すると、「RuntimeError:%Sのスーパークラス__init __()が呼び出されませんでした」

  14. 14

    抽象クラスのエラー「基本クラスの__init__メソッドが呼び出されていません」

  15. 15

    RSpecを使用してコントローラーメソッドでクラスが呼び出されることをテストする方法

  16. 16

    別のファイルからクラスをインポートすると__init__関数が呼び出されるのはなぜですか?

  17. 17

    リンクリストクラスが別のクラスメソッドから呼び出されたときにノードを挿入しない

  18. 18

    リフレクションを使用してメソッドを呼び出すと、「オブジェクトは宣言クラスのインスタンスではない」と表示されるのはなぜですか?

  19. 19

    子クラスの動的メソッドは、ラムダキャプチャで使用されると、親クラスの仮想メソッドを呼び出します/セグメンテーションフォールトが発生します

  20. 20

    PHPUnitを使用して、同じクラスの他のメソッドを呼び出すが値を返さないメソッドをテストする方法

  21. 21

    別のクラスのメソッドを呼び出し、返されたリストを保存する

  22. 22

    静的クラス メソッドは、クラスの外部で呼び出されるとオブジェクトを返しますが、異なるクラスの内部で呼び出されると空のオブジェクトを返します。

  23. 23

    ソフトウェア全体で適切なパラメータを使用してメソッドが呼び出されることをテストします

  24. 24

    ユーザー定義型のメタクラス__new__と__init__はどこで呼び出されますか?

  25. 25

    Activityクラスを使用してフラグメントクラス内のメソッドを呼び出す

  26. 26

    Python スクリプトで __init__ を呼び出すときに重複した行が表示される

  27. 27

    列挙とリフレクションを使用してクラスのリストに対してメソッドを呼び出す

  28. 28

    -mを指定してPythonスクリプトを実行すると、__ init__。pyが呼び出されないのはなぜですか?

  29. 29

    ジェネリッククラスでジェネリックリターンを使用してメソッドを呼び出すことが、javacによって安全でないと見なされるのはなぜですか?

ホットタグ

アーカイブ