1

OOPS は初めてです

親クラスのインスタンスPがいつ初期化されるかを知りたい、子クラスのインスタンスを初期化したいC

お気に入り

class A(object):
    def __init__(self):
        print "A created"
P = A()


class B(A):
    def __init__(self):
        print super((B), self).__init__ # Q1: How to get "A created" from parent class?
        print self.__class__.__name__
        print super(B, self).__class__.__name__

Q2: インスタンスを作成する場合、以前のインスタンスが存在する場合にのみ作成する必要があるieのサブインスタンスとしてz = B()作成したいと考えています。また、属性に追加されたデータがある場合は、属性がデータと共に流れます。基本的に存在しない場合は作成しないでくださいzPzPPzzP

同様にy = B() iff x = A() それを行う方法はありますか?

Aさまざまなコンテキストでクラスの複数のインスタンスが作成されるプログラムを作成しているため、これを行っています。

Mathematics = A()
English = A()
Now,
Algebra = B() iff Mathematics = A()
And 
Grammar = B() iff English = A()

それをチェックするセルフチェッカーはありますか?つまり、それはどのように行われますか?

Q2 の更新: A クラスのインスタンスをチェックするインスタンスを作成し、特定のインスタンス データを取得するときに、B クラスをチェックインする方法はありますか? Bクラスのように、クラスAで作成されたインスタンスをチェックしてから1つを選択し、そのインスタンスの属性からクラスBで作成されているインスタンスにデータを取得しますか??

また

 z = B()
    <bound method B.__init__ of <__main__.B object at 0x000000000791DB38>>
    B
super #Q3: I thought it would print `A`. WHY NOT?
4

3 に答える 3

3

__init__に電話していませんB。関数の名前を使用すると、その関数オブジェクトが得られます。__init__()実際に関数を実行した後の括弧。

super(B, self)オブジェクトではなくクラスを返すため (クラスにはスーパーインスタンスがなく、スーパークラスがあります)、__class__そのクラスを呼び出すと、予期しない結果が生じます。はクラスのインスタンスであるため、 __class__on を使用します。selfself

class B(A):
    def __init__(self):
        super(B, self).__init__()
        print type(self).__name__
        print super(B, self).__name__

type()私の過剰アクセスの使用に注意してください__class__- ビルトイン関数を使用することは、魔法の値に直接アクセスするよりも優れています。より読みやすく、特別な機能を可能にします。

于 2013-06-13T17:54:42.957 に答える
0

更新された Q2 を読み、Q1 をもう一度見ると、クラスとクラスが何をしてくれるのかについて基本的な誤解があるように思えます。(あなたが「OOP の初心者」であると言うので、これは理にかなっています。)

あなたがよく知っている非OOP 言語を知らない限り、ここで用語に反することになりますが、C の例を使用して、多くの問題を意図的に説明し、あなたclass Aは のようなものであると主張しますstruct A。全体を含むclass B単なる aです:struct Bstruct A

struct A {
    int x, y; /* ... etc */
};
struct B {
    struct A a;
    int z;
}

の新しいインスタンスを作成する場合、そのメンバーのBを変更することはできません。常に実際の になります。(タイプまたはインスタンス)があるかどうかは関係ありません。aの内容には 1 つだけが含まれます。aAstruct A2BA

あなたが望むのはサブクラスではなく、単なる通常のメンバーのように聞こえます。これは、(C では) 他のオブジェクトへのポインターを物理的に組み込むのではなく、他のオブジェクトへのポインターを持っているようなものです。

class A1(object):
    def __init__(self):
        pass
    def about(self):
        print 'I am an A1'

class A2(object):
    def __init__(self):
        pass
    def about(self):
        print 'I am an A2'

class B(object):
    def __init__(self, connected_to = None):
        self.connected_to = connected_to
    def about(self):
         print 'I am a B'
         if self.connected_to is not None:
             print '... and I am connected to a %s:' % type(self.connected_to)
             self.connected_to.about() # and ask it to describe itself
         else:
             print '... and I am connected to no one!'

(C では、ポインターがあるということは、少なくとも、ある場合は、必要な型を指すことができるvoid *ことを意味し、まったく何も指すことができないことを意味します。そのままです。)BNone.about()

上記を考えると、次のことができます。

>>> B(A1()).about()
I am a B
... and I am connected to a <class '__main__.A1'>:
I am an A1
>>> B(A2()).about()
I am a B
... and I am connected to a <class '__main__.A2'>:
I am an A2
>>> B().about()
I am a B
... and I am connected to no one!
>>> 

もちろん、A1 または A2 (存在する場合) を明示的に渡すことが望ましくない場合は、それ自体で A1 または A2 を見つけるようにすることもできBます。__init__

もちろん、これは(サブ)クラスが何をするかを覆い隠します。上記の例を考えると、クラスを作成してMaths(object)からサブクラスを作成し、Algebra(Maths)別のサブクラスを作成することもできますTopology(Maths)HumanLanguage(object)個別に、クラスとサブクラスEnglish(HumanLanguage)、および別のサブクラスを作成できますRussian(HumanLanguage)。ただし、サブクラスは作成しRing(HumanLanguage)ませRing(Algebra)んが、意味があるかもしれません。


super(B, self).__class__.__name__アドレス Q3 に編集: インタプリタで、印刷が「super」のみを印刷する理由を確認できます。やったz = B()

>>> type(z)
<class '__main__.B'>
>>> super(B, z)
<super: <class 'B'>, <B object>>

呼び出すだけで、この特別なプロキシ オブジェクトsuperを取得できます。プロキシ オブジェクトは、インスタンスが「上向き」(技術的には「mro」-wards) を呼び出す方法です。Python2 ドキュメント内のリンクをたどってください。

于 2013-06-13T19:33:53.563 に答える