0

この回答に基づいて、Pythonでどのよう__new__に動作することになっているのか、__init__

新しいクラスとオブジェクトを動的に定義して作成するために、このコードを書きました。

class A(object):
    def __new__(cls):
      class C(cls, B):
          pass
      self = C()
      return self

    def foo(self):
      print 'foo'

class B(object):
    def bar(self):
      print 'bar'

a = A()
a.foo()
a.bar()

基本的に、__new__A の は A と B を継承する動的に作成された C を返すため、属性が必要ですbar

なぜ属性がC ないのですか?bar

4

3 に答える 3

7

質問には実際の質問がないので文字通りそれを取るつもりです:

動的にそれを行うのは何が悪いのですか?
まあ、それは実際には読めない、非常に不透明で、あなたのコードのユーザーには自明ではありません(それはあなたを1ヶ月で含みます:P)。

私の経験から(かなり限られていますが、残念ながら私は20年間のプログラミングを行っていません)、そのようなソリューションの必要性は、クラス構造が明確に定義されていないことを示しています-つまり、ほとんどの場合、より良いものがあります、そのようなことを行うためのより読みやすく、より難解な方法。

たとえば、本当にその場で基本クラスを定義したい場合は、必要に応じて適切なクラスを返すファクトリ関数を使用することをお勧めします。

質問に対する別の見方:
動的にそれを行うのは何が悪いのですか?
現在の実装では、「最大再帰深度を超えました」というエラーが発生します。それは、A.__new__それ自体を無期限に内部から呼び出すためです(それ自体とから継承するためB)。

10:内部A.__new__では、「cls」はに設定されてい<class '.A'>ます。コンストラクター内で、(実際には)Cから継承するクラスと別のクラスを定義します。インスタンス化すると、が呼び出されます。独自のを定義していないため、その基本クラス'が呼び出されます。基本クラスはたまたまです。20:GOTO 10clsABC__new____new____new__A

于 2010-01-08T09:41:29.420 に答える
7

無限再帰を解決します。

class A(object):
  def __new__(cls):
    class C(cls, B):
      pass
    self = object.__new__(C)
    return self

(実際の質問を指摘してくれたbalphaに感謝します。)

于 2010-01-08T09:44:50.877 に答える
3

あなたの質問が「どうすればこれを達成できますか」である場合–これは機能します:

class A(object):
    @classmethod
    def get_with_B(cls):
      class C(B, cls):
        pass

      return C()

    def foo(self):
      print 'foo'

class B(object):
    def bar(self):
      print 'bar'

a = A.get_with_B()
a.foo()
a.bar()

あなたの質問が「なぜそれが機能しないのか」である場合-それはあなたが呼び出すときに無限の再帰に遭遇するためです。それは呼び出されることC()につながりA.__new__、再び呼び出すC()などです。

于 2010-01-08T09:40:16.160 に答える