2

私が求めていることは奇妙に見えるかもしれませんが、ここに例があります:

私はクラス「A」を持っています

class A:
    a=1

その他私はクラス「B」を持っています

class B:
    def __init__(self, obj):
        self.obj = obj # obj is any object

今私は使用します:

first = A()
second = B(first)
isinstance(second, A)

ステップ3を真にしたいと思います。つまり、オブジェクトクラスBが取っているものは何でも、そのオブジェクトタイプのインスタンスをオブジェクトに追加する必要があります。

このようなことはPythonで可能ですか?

4

4 に答える 4

2

もちろん、効果的にクラス ファクトリを作成する代わりに、オブジェクトをオーバーライドし__new__て派生させることもできます...typeobject

最終的に行うことは、次のようになります。

b = type('B', (A,), {'obj': A()})

これは、A() のインスタンスを含む A から派生したものを生成class Bします。これは関数であるため、任意の理由で好きなものを渡すことができます。

于 2012-06-24T19:18:38.153 に答える
2

2つの可能性

isinstance(second, A)する代わりにisinstance(second.obj, A)

2番目...よりハックな方法は、次のようなことです:

class B:
    def __init__(self, obj):
        self.obj = obj # obj is any object
        self.__class__ = obj.__class__

これは、基本的にインスタンスが別のクラスであると解釈するようにインタプリタを欺くため、ハックです。つまりisinstance(second, B)返ってくるFalse

以下の質問に答えるには: インタプリタは基本的にsecondがクラスAであるかのように動作し、クラス レベルで定義されたものは何もB残りません。たとえば、次のようなことをすると

class B:
    b=2 #Won't be visible
    def __init__(self, obj):
        self.obj = obj # obj is any object
        self.b2 = 5 #Instance variable will be visible
        self.__class__ = obj.__class__

    def someFunc(self): #Won't be visible
        return 3

上記で初期化に使用したのと同じコードを使用すると、インタープリターを使用するいくつかの呼び出しで何が起こるかが分かります。一般に、クラス変数またはメソッドはすべて削除され、代わりにA'a が使用されますが、インスタンス変数は記憶されます。このため、この操作self.obj = objは少し冗長です。基本的にインスタンス化B(obj) すると、多かれ少なかれ と同じクラスのオブジェクトが返されobjます。obj'sは呼び出されませんが__init__、そのためにはさらにブードゥー/マジックが必要になります (興味がある場合は投稿してください)。

>>> isinstance(second, A)
True
>>> isinstance(second, B)
False
>>> second.a
1
>>> second.b
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    second.b
AttributeError: A instance has no attribute 'b'
>>> second.someFunc()
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    second.someFunc()
AttributeError: A instance has no attribute 'someFunc'
>>> second.b2
5
>>> second.obj
<__main__.A instance at 0x0123CAF8>
于 2012-06-24T19:08:21.940 に答える
2

はい、継承を使用します。

class B(A):
    def __init__(self, obj):
        self.obj = obj # obj is any object
于 2012-06-24T18:58:01.033 に答える
1

ハックではない方法で可能だとしても、これが良いアイデアである可能性は非常に低いと示唆したくなるでしょう。(編集:Jon Clementsの提案は、最善/最小のハックな方法だと思いますが、それでも私の投稿の残りの部分は関連性があることを示唆しています。)これが「is-a」関係を何おそらく「has-a」関係になるはずです。OPが何を達成しようとしているのかについて詳細が投稿されない限り、確実に知ることは不可能です.

とにかく、誰か (私が思うに Kent Beck) はかつて (私が覚えているように言い換えて) 言ったことがあります。安易に使うべきではありません。別の言い方をすれば、可能な限り、継承よりも構成 (または集約) を優先します。

于 2012-06-24T19:22:12.910 に答える