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 auparavantLa 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
<🎜. >
Implémentation de type classe@Singleton class A(object): def __init__(self, x): self.x = x
.
À 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 Pythonet
Tutoriel d'article Pythoncolonnes! ! !
@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!