1

OpenSource GitHub プロジェクトから次のコードを理解しようとしています。__init__メソッドがなくてもメソッドがあるクラスがあり__new__ます。コードは次のように与えられます。

class Node(object):
    #pylint: disable=W0404

    #Singleton-Pattern
    _instances = dict()

    def __new__(cls, name=None):
        """ Instanciates a node from a file, and (name=None) creates a new node 
            Caution: Filenames are always given relative to the root-dir
            When no name is given, a new node is created. """

        if(name!=None and cls._instances.has_key(name)):
            return(cls._instances[name])

        if(name==None):  # a new node, lets find a name
            for i in itertools.count(0):
                name = "node%.4d"%i
                if(cls._instances.has_key(name)): continue# new nodes might not been saved, yet
                if(path.exists("./nodes/"+name)): continue
                break


        self = object.__new__(cls)
        cls._instances[name] = self

        #actuall init-code
        from ZIBMolPy.pool import Pool #avoids circular imports
        self._pool = Pool() #Pool is a singleton
        self._name = name
        self._tmp = Store() #for thing that need to be stored temporarly
        self._obs = Store()
        self.parent = None

        if(path.exists(self.dir)):
            self.reload()

        #self.pool.append(self) #register with pool
        return(self)

    #---------------------------------------------------------------------------
    @property
    def obs(self):
        return(self._obs)

Python での __new__ と __init__ の使用で__init__、メソッドと__new__メソッドの間で1 つの議論を見つけました。最高評価のコメントによると、 、、または のような不変型をサブクラス化する場合にのみ、 new を使用する必要があります。しかし、ここでは別の理由で使用されていると思います。さらに、クラスに名前を付ける必要がある理由(および一部のフォルダーで何かを行う必要がある理由)と、なぜ呼び出すことができるのかわかりませんstrintunicodetuplecls

n= Node()
n.obs

関数obsのようにプロパティ関数になりますが、実際にはそうではありません..

私は混乱しています。そうでない場合は、返信を待ちきれません。

4

1 に答える 1

3

このクラスは__new__、シングルトン パターンの実装に使用します。

__new__クラスの新しいインスタンスを生成しますが、この場合、同じ名前が以前に使用されていた場合は代わりに既存のインスタンスを返します。はインスタンスの作成__init__に呼び出されるため、これを で行うことはできません。isの場合、クラスの新しいインスタンスを作成するためにが呼び出され、初期化されて返されることに注意してください。cls._instances.has_key(name)Falseself = object.__new__(cls)

クラスがディレクトリ内の既存のパスをチェックする理由は./nodes/明確ではありません。これは、アプリケーション固有のチェックであり、それ以上のコンテキストがないとすぐに公開できないためです。

デコレーターは、関数をpython 記述子@propertyに置き換えます。クラスから属性を検索するとき、Python は、属性に属性がある場合、そのメソッドを呼び出します。Python 式は Python によって に変換されます。オブジェクトはラップされた関数を呼び出し、呼び出されたときに結果を返します。__get__n.obstype(n).obs.__get__(n, type(n))property__get__

于 2013-05-03T16:28:52.403 に答える