24

キーワードに関するpythonドキュメントを読んで、これに出くわしました:super

2 番目の引数を省略すると、返されるスーパー オブジェクトはバインドされません。2 番目の引数がオブジェクトの場合、isinstance(obj, type) は true でなければなりません。2 番目の引数が型の場合、issubclass(type2, type) は true でなければなりません (これはクラスメソッドに役立ちます)。

Type を 2 番目の引数として渡す場合と Object を渡す場合の違いの例を教えてください。

ドキュメントはオブジェクトのインスタンスについて話していますか?

ありがとうございました。

4

3 に答える 3

10

Python のsuper関数は、その引数が何であるかに応じて、さまざまなことを行います。これを使用するさまざまな方法のデモンストレーションを次に示します。

class Base(object):
    def __init__(self, val):
        self.val = val

    @classmethod
    def make_obj(cls, val):
        return cls(val+1)

class Derived(Base):
    def __init__(self, val):
        # In this super call, the second argument "self" is an object.
        # The result acts like an object of the Base class.
        super(Derived, self).__init__(val+2)

    @classmethod
    def make_obj(cls, val):
        # In this super call, the second argument "cls" is a type.
        # The result acts like the Base class itself.
        return super(Derived, cls).make_obj(val)

テスト出力:

>>> b1 = Base(0)
>>> b1.val
0
>>> b2 = Base.make_obj(0)
>>> b2.val
1
>>> d1 = Derived(0)
>>> d1.val
2
>>> d2 = Derived.make_obj(0)
>>> d2.val
3

3結果は、前の修飾子の組み合わせです: 1 (から)Base.make_objと 2 (からDerived.__init__)。

「バインドされていない」スーパーオブジェクトを取得するために引数を 1 つだけ指定して呼び出すことができることに注意してくださいsuper。これは明らかにあまり役に立ちません。Python の内部をいじりたくて、自分が何をしているのかを本当に理解しているのでない限り、これを行う理由はまったくありません。

Python 3 では、super引数なしで呼び出すこともできます (これは上記の関数の呼び出しと同等ですが、より魔法のようです)。

于 2013-03-30T21:39:27.777 に答える
0

ここでは、2 つの関数について簡単に説明します。この演習を通して、私はそれが明るくなったと感じました。私はよく、単純な関数の内外を調査する単純なプログラムを作成し、参照用に保存します。

#
# Testing isinstance and issubclass
#

class C1(object):
    def __init__(self):
        object.__init__(self)

class B1(object):
    def __init__(self):
        object.__init__(self)

class B2(B1):
    def __init__(self):
        B1.__init__(self)

class CB1(C1,B1):
    def __init__(self):
        # not sure about this for multiple inheritance
        C1.__init__(self)
        B1.__init__(self)

c1 = C1()
b1 = B1()
cb1 = CB1()

def checkInstanceType(c, t):
    if isinstance(c, t):
        print c, "is of type", t
    else:
        print c, "is NOT of type", t

def checkSubclassType(c, t):
    if issubclass(c, t):
        print c, "is a subclass of type", t
    else:
        print c, "is NOT a subclass of type", t

print "comparing isinstance and issubclass"
print ""

# checking isinstance
print "checking isinstance"

# can check instance against type
checkInstanceType(c1, C1)
checkInstanceType(c1, B1)
checkInstanceType(c1, object)

# can check type against type
checkInstanceType(C1, object)
checkInstanceType(B1, object)

# cannot check instance against instance
try:
    checkInstanceType(c1, b1)
except Exception, e:
    print "failed to check instance against instance", e

print ""

# checking issubclass
print "checking issubclass"

# cannot check instance against type
try:
    checkSubclassType(c1, C1)
except Exception, e:
    print "failed to check instance against type", e

# can check type against type
checkSubclassType(C1, C1)
checkSubclassType(B1, C1)
checkSubclassType(CB1, C1)
checkSubclassType(CB1, B1)

# cannot check type against instance
try:
    checkSubclassType(C1, c1)
except Exception, e:
    print "failed to check type against instance", e

編集: isinstance は API 実装を壊す可能性があるため、次のことも考慮してください。例としては、辞書のように機能するオブジェクトですが、dict から派生したものではありません。isinstance は、オブジェクトがディクショナリ スタイルのアクセスをサポートしている場合でも、オブジェクトがディクショナリであることを確認する場合があります: isinstance は有害と見なされます

編集2:

Type を 2 番目の引数として渡す場合と Object を渡す場合の違いの例を教えてください。

上記のコードをテストすると、2 番目のパラメーターは型でなければならないことがわかります。したがって、次の場合:

checkInstanceType(c1, b1)

呼び出しは失敗します。次のように記述できます。

checkInstanceType(c1, type(b1))

したがって、あるインスタンスのタイプを別のインスタンスと比較してチェックしたい場合は、type() 組み込み呼び出しを使用する必要があります。

于 2013-03-30T20:46:34.467 に答える