Frage

Ich möchte regelmäßig überprüfen, ob ein Objekt ein Mitglied hat oder nicht. Ein Beispiel ist die Schaffung eines Singleton in einer Funktion. Zu diesem Zweck können Sie hasattr wie folgt verwenden:

class Foo(object):
    @classmethod
    def singleton(self):
        if not hasattr(self, 'instance'):
            self.instance = Foo()
        return self.instance

Aber man kann dies auch tun:

class Foo(object):
    @classmethod
    def singleton(self):
        try:
            return self.instance
        except AttributeError:
            self.instance = Foo()
            return self.instance

Ist eine Methode besser von der anderen Seite?

Edit: wurde hinzugefügt @classmethod ... Aber beachten Sie, dass die Frage ist nicht , wie ein Singleton zu machen, sondern, wie die Anwesenheit eines Mitglieds in einem Objekt zu überprüfen .

Edit: Für dieses Beispiel eine typische Anwendung wäre:

s = Foo.singleton()

Dann s ist ein Objekt vom Typ Foo, die jedes Mal gleich. Und, in der Regel wird das Verfahren oft genannt wird.

War es hilfreich?

Lösung

Das sind zwei verschiedene Methoden: №1 ist LBYL (sehen Sie vor dem Sprung) und №2 ist EAFP (einfacher bitten um Vergebung als Erlaubnis)

.

Pythonistas legt nahe, dass typischerweise EAFP ist besser, mit Argumenten im Stil von „was ist, wenn ein Prozess die Datei zwischen der Zeit schafft sie es testen und die Zeit, die Sie versuchen, es selbst zu erstellen?“. Dieses Argument gilt hier nicht, aber es ist die allgemeine Idee. Ausnahmen sollten nicht so behandelt werden zu außergewöhnlich.

Performance-weise in Ihrem Fall -Da Ausnahme Manager einrichten (das try Schlüsselwort) ist sehr billig in CPython während einer Ausnahme zu schaffen (das raise Schlüsselwort und interne Ausnahme Schöpfung) ist das, was relativ expensive- ist mit der Methode №2 die Ausnahme würde nur einmal angehoben werden; danach, die Sie gerade die Eigenschaft verwenden.

Andere Tipps

Ich habe gerade versucht mal zu messen:

class Foo(object):
    @classmethod
    def singleton(self):
        if not hasattr(self, 'instance'):
            self.instance = Foo()
        return self.instance



class Bar(object):
    @classmethod
    def singleton(self):
        try:
            return self.instance
        except AttributeError:
            self.instance = Bar()
            return self.instance



from time import time

n = 1000000
foo = [Foo() for i in xrange(0,n)]
bar = [Bar() for i in xrange(0,n)]

print "Objs created."
print


for times in xrange(1,4):
    t = time()
    for d in foo: d.singleton()
    print "#%d Foo pass in %f" % (times, time()-t)

    t = time()
    for d in bar: d.singleton()
    print "#%d Bar pass in %f" % (times, time()-t)

    print

Auf meinem Rechner:

Objs created.

#1 Foo pass in 1.719000
#1 Bar pass in 1.140000

#2 Foo pass in 1.750000
#2 Bar pass in 1.187000

#3 Foo pass in 1.797000
#3 Bar pass in 1.203000

Es scheint, dass try / except schneller ist. Es scheint auch besser lesbar zu mir ohnehin von dem Fall, wurde dieser Test sehr einfach vielleicht würde Sie eine komplexere brauchen.

Es hängt davon ab, welchen Fall „typisch“ ist, weil Ausnahmen sollten, na ja, atypische Bedingungen modellieren. Also, wenn der typische Fall ist, dass das instance Attribut existieren sollte, verwenden Sie dann den zweiten Code-Stil. Wenn nicht instance, wie sie typisch ist instance hat, dann die erste Art verwendet werden.

Im speziellen Fall von Singleton zu schaffen, ich bin geneigt, mit der ersten Art zu gehen, weil einem Singleton die Anfangszeit zu schaffen ein typischer Anwendungsfall ist. : -)

Ein wenig vom Thema in der Art und Weise, es zu benutzen. Singletons sind überbewertet, und eine "shared-state" Methode ist so effektiv, und vor allem, sehr sauber in Python, zum Beispiel:

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
    # and whatever else you want in your class -- that's all!

Nun jedes Mal, wenn Sie tun:

obj = Borg()

es wird die gleiche Information hat, oder, sein etwas die gleiche Instanz.

Ich habe mit Chris zu vereinbaren. Denken Sie daran, nicht zu optimieren, bis Sie wirklich so tun müssen. Ich wirklich Zweifel Überprüfung auf Existenz zu einem Engpass in jedem vernünftigen Programm sein wird.

Ich sehe tat http://code.activestate.com/recipes/52558/ als eine Möglichkeit, dies zu tun, auch. Unkommentiert Kopie des Codes ( „Spam“ ist nur eine zufällige Methode der Klasse Schnittstelle):

class Singleton:
    class __impl:
        def spam(self):
            return id(self)
    __instance = None
    def __init__(self):
        if Singleton.__instance is None:
            Singleton.__instance = Singleton.__impl()
        self.__dict__['_Singleton__instance'] = Singleton.__instance
    def __getattr__(self, attr):
        return getattr(self.__instance, attr)
    def __setattr__(self, attr, value):
        return setattr(self.__instance, attr, value)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top