Python魔法の方法(一)new__()

3199 ワード

まず、新しいタイプだけが魔法の方法を持っています.new__()は,Objectクラスから継承されるサブクラスであり,いずれも新式クラスである.
objectクラス説明_new__()の定義は次のとおりです.
@staticmethod # known case of __new__
    def __new__(cls, *more): # known special case of object.__new__
        """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
        pass

パラメータの説明:
(1)object将_new__()静的メソッドとして定義します.
(2)入力されたパラメータの少なくとも1つのclsパラメータであり、clsはインスタンス化が必要なクラスを表す.
 
使用方法の例を挙げます.
class A(object):
    def __init__(self, value):
        print  "into __init__"
        self.value = value
    def __new__(cls, *args, **kwargs):
        print "into __new__"
        return super(A, cls).__new__(cls, *args, **kwargs)

a =  A(10)

#     :
# into __new__
# into __init__

呼び出し_init__()初期化前に、先に呼び出しました_new__().
新しいクラスで、_new__()現在のクラスをインスタンス化し、インスタンスを返して__に渡します.init__(),__init__()メソッドでselfは_new__()伝わってきました.
しかし、実行されました_new__()、必ずしも入るとは限りません_-;)init__()、_のみnew__()は、現在のクラスclsのインスタンス、現在のクラスの__を返します.init__()しか入れません.
2つの例を見てみましょう.
class A(object):
    def __init__(self, value):
        print  "into A __init__"
        self.value = value
        
    def __new__(cls, *args, **kwargs):
        print "into A __new__"
        return object.__new__(cls, *args, **kwargs)


class B(A):
    def __init__(self, value):
        print  "into B __init__"
        self.value = value
        
    def __new__(cls, *args, **kwargs):
        print "into B __new__"
        return super(B, cls).__new__(cls, *args, **kwargs)

b = B(10)

b = B(10)
#   :
# into B __new__
# into A __new__
# into B __init__



class A(object):
    def __init__(self, value):
        print  "into A __init__"
        self.value = value

    def __new__(cls, *args, **kwargs):
        print "into A __new__"
        return object.__new__(cls, *args, **kwargs)


class B(A):
    def __init__(self, value):
        print  "into B __init__"
        self.value = value

    def __new__(cls, *args, **kwargs):
        print "into B __new__"
        return super(B, cls).__new__(A, *args, **kwargs) #   cls  A

b = B(10)
#   :
into B __new__
into A __new__

若_new__現在のクラスclsのインスタンスが正しく返されていません.init__呼び出されません.親のインスタンスでもできません.init__呼び出されます.
 
__new__の役割
(1)
__new__方法は主に、int、str、tupleなどの可変classを継承するときに、これらのクラスのインスタンス化プロセスをカスタマイズする方法を提供します.
もし私たちが永遠に正数の整数タイプが必要なら.
class PositiveInteger(int):
    def __init__(self, value):
        super(PositiveInteger, self).__init__(self, abs(value))


i = PositiveInteger(-3)
print i

# -3

class PositiveInteger(int):
    def __new__(cls, value):
        return super(PositiveInteger, cls).__new__(cls, abs(value))


i = PositiveInteger(-3)
print i

# 3

リロードにより_new__方法は、必要な機能を実現しました.
(2)実現例
 
いくつかの説明:
(1)サブクラス定義時に再定義されていない_new__()の場合、Pythonのデフォルトは、そのクラスの直接親を呼び出す__です.new__()メソッドは、クラスの親が書き換えられていない場合にクラスのインスタンスを構築します.new__()では、この規則に従ってobjectに遡る_new__()メソッドは、objectがすべての新しいクラスのベースクラスであるためです.
(2)1つの2つの作用を除いて、一般的に_new__()使用量が少なく、通過できる_init__()実現できる限り_init__()実装.