Maison  >  Article  >  développement back-end  >  Introduction à deux méthodes d'implémentation de python singleton (avec code)

Introduction à deux méthodes d'implémentation de python singleton (avec code)

不言
不言avant
2018-10-12 15:37:001990parcourir

Ce que cet article vous apporte est une introduction à deux méthodes d'implémentation de singletons python (avec code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Au cours des deux derniers jours, j'ai regardé le code que j'ai écrit auparavant, donc j'ai juste trié les choses que j'ai utilisées. Le mode singleton est également souvent utilisé dans le travail de code quotidien, <.>

Voici donc un résumé des méthodes singleton qui ont été implémentées de différentes manières auparavant

La méthode décorateur

Cette méthode est également couramment utilisée dans work. Il est également plus pratique à utiliser. L'implémentation du code est la suivante Can :

def Singleton(cls):
    _instance = {}
    def _singleton(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]

    return _singleton

Personnellement, j'aime beaucoup cette méthode

Implémentation de type classe

@Singleton
class A(object):    
def __init__(self, x):
     self.x = x
Il y a en fait ici certains problèmes auxquels vous devez prêter attention. Jetons d'abord un coup d'œil aux codes d'erreur possibles

.

À première vue, cette classe semble avoir un singleton implémenté, mais il y a un problème potentiel ici, c'est-à-dire que si elle est multithread, écrire de cette façon posera des problèmes , surtout lorsqu'il y a des opérations chronophages dans l'objet d'initialisation de la classe actuelle

Par exemple, le code suivant :

class Member(object):
    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            Member._instance = Member(*args, **kwargs)
        return Member._instance

Le résultat de l'exécution de ce code sera que plusieurs objets seront instanciés, ce qui empêchera le singleton que vous avez écrit de fonctionner. Fonction

Bien sûr, nous penserons naturellement à le verrouiller et à le contrôler via des verrous, nous changeons donc le. code ci-dessus :

#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-
import time
import threading
import random
class Member(object):
    def __init__(self):
        time.sleep(random.randint(1,3))
    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            Member._instance = Member(*args, **kwargs)
        return Member._instance
def task(arg):
    obj = Member.instance()
    print(obj)
for i in range(5):
    t = threading.Thread(target=task, args=[i,])
    t.start()

Mais il y a un autre problème avec le code ci-dessus, c'est-à-dire que chaque fois que nous appelons l'instance après l'avoir instanciée, nous le ferons demander le verrou, donc ce n'est pas bon, donc on change à nouveau cette partie du code :

C'est un bon moyen d'implémenter un singleton qui peut être utilisé par plusieurs fils de discussion
#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-
import time
import threading
import random
class Member(object):
    _instance_lock = threading.Lock()
    def __init__(self):
        i = random.randint(1, 3)
        print(i)
        time.sleep(i)
    @classmethod
    def instance(cls, *args, **kwargs):
        with Member._instance_lock:
            if not hasattr(Member, "_instance"):
                Member._instance = Member(*args, **kwargs)
        return Member._instance
def task():
    obj = Member.instance()
    print(obj)

for i in range(5):
    threading.Thread(target=task,).start()

Ce qui précède représente l'intégralité du contenu de cet article. Pour un contenu plus passionnant sur Python, vous pouvez suivre le site Web PHP chinois

Tutoriel vidéo Python

et

Tutoriel d'article Python

colonnes! ! !

@classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            with Member._instance_lock:
                if not hasattr(Member, "_instance"):
                    Member._instance = Member(*args, **kwargs)
        return Member._instance

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer