本文为大家分享了Python创建单例模式的5种常用方法,供大家参考,具体内容如下
所谓单例,是指一个类的实例从始至终只能被创建一次。
方法1:
如果想使得某个类从始至终最多只有一个实例,使用__new__方法会很简单。Python中类是通过__new__来创建实例的:
class Singleton(object): def __new__(cls,*args,**kwargs): if not hasattr(cls,'_inst'): cls._inst=super(Singleton,cls).__new__(cls,*args,**kwargs) return cls._inst if __name__=='__main__': class A(Singleton): def __init__(self,s): self.s=s a=A('apple') b=A('banana') print id(a),a.s print id(b),b.s
结果:
29922256 banana
29922256 banana
通过__new__方法,将类的实例在创建的时候绑定到类属性_inst上。如果cls._inst为None,说明类还未实例化,实例化并将实例绑定到cls._inst,以后每次实例化的时候都返回第一次实例化创建的实例。注意从Singleton派生子类的时候,不要重载__new__。
方法2:
有时候我们并不关心生成的实例是否具有同一id,而只关心其状态和行为方式。我们可以允许许多个实例被创建,但所有的实例都共享状态和行为方式:
class Borg(object): _shared_state={} def __new__(cls,*args,**kwargs): obj=super(Borg,cls).__new__(cls,*args,**kwargs) obj.__dict__=cls._shared_state return obj
将所有实例的__dict__指向同一个字典,这样实例就共享相同的方法和属性。对任何实例的名字属性的设置,无论是在__init__中修改还是直接修改,所有的实例都会受到影响。不过实例的id是不同的。要保证类实例能共享属性,但不和子类共享,注意使用cls._shared_state,而不是Borg._shared_state。
因为实例是不同的id,所以每个实例都可以做字典的key:
if __name__=='__main__': class Example(Borg): pass a=Example() b=Example() c=Example() adict={} j=0 for i in a,b,c: adict[i]=j j+=1 for i in a,b,c: print adict[i]
结果:
0
1
2
如果这种行为不是你想要的,可以为Borg类添加__eq__和__hash__方法,使其更接近于单例模式的行为:
class Borg(object): _shared_state={} def __new__(cls,*args,**kwargs): obj=super(Borg,cls).__new__(cls,*args,**kwargs) obj.__dict__=cls._shared_state return obj def __hash__(self): return 1 def __eq__(self,other): try: return self.__dict__ is other.__dict__ except: return False if __name__=='__main__': class Example(Borg): pass a=Example() b=Example() c=Example() adict={} j=0 for i in a,b,c: adict[i]=j j+=1 for i in a,b,c: print adict[i]
结果:
2
2
2
所有的实例都能当一个key使用了。
方法3
当你编写一个类的时候,某种机制会使用类名字,基类元组,类字典来创建一个类对象。新型类中这种机制默认为type,而且这种机制是可编程的,称为元类__metaclass__ 。
class Singleton(type): def __init__(self,name,bases,class_dict): super(Singleton,self).__init__(name,bases,class_dict) self._instance=None def __call__(self,*args,**kwargs): if self._instance is None: self._instance=super(Singleton,self).__call__(*args,**kwargs) return self._instance if __name__=='__main__': class A(object): __metaclass__=Singleton a=A() b=A() print id(a),id(b)
结果:
34248016 34248016
id是相同的。
例子中我们构造了一个Singleton元类,并使用__call__方法使其能够模拟函数的行为。构造类A时,将其元类设为Singleton,那么创建类对象A时,行为发生如下:
A=Singleton(name,bases,class_dict),A其实为Singleton类的一个实例。
创建A的实例时,A()=Singleton(name,bases,class_dict)()=Singleton(name,bases,class_dict).__call__(),这样就将A的所有实例都指向了A的属性_instance上,这种方法与方法1其实是相同的。
方法4
python中的模块module在程序中只被加载一次,本身就是单例的。可以直接写一个模块,将你需要的方法和属性,写在模块中当做函数和模块作用域的全局变量即可,根本不需要写类。
而且还有一些综合模块和类的优点的方法:
class _singleton(object): class ConstError(TypeError): pass def __setattr__(self,name,value): if name in self.__dict__: raise self.ConstError self.__dict__[name]=value def __delattr__(self,name): if name in self.__dict__: raise self.ConstError raise NameError import sys sys.modules[__name__]=_singleton()
python并不会对sys.modules进行检查以确保他们是模块对象,我们利用这一点将模块绑定向一个类对象,而且以后都会绑定向同一个对象了。
将代码存放在single.py中:
>>> import single >>> single.a=1 >>> single.a=2
ConstError
>>> del single.a
ConstError
方法5:
最简单的方法:
class singleton(object): pass singleton=singleton()
将名字singleton绑定到实例上,singleton就是它自己类的唯一对象了。
以上就是Python单例模式的实现方式详细介绍,希望对大家的学习有所帮助。

Python dan C masing -masing mempunyai kelebihan sendiri, dan pilihannya harus berdasarkan keperluan projek. 1) Python sesuai untuk pembangunan pesat dan pemprosesan data kerana sintaks ringkas dan menaip dinamik. 2) C sesuai untuk prestasi tinggi dan pengaturcaraan sistem kerana menaip statik dan pengurusan memori manual.

Memilih Python atau C bergantung kepada keperluan projek: 1) Jika anda memerlukan pembangunan pesat, pemprosesan data dan reka bentuk prototaip, pilih Python; 2) Jika anda memerlukan prestasi tinggi, latensi rendah dan kawalan perkakasan yang rapat, pilih C.

Dengan melabur 2 jam pembelajaran python setiap hari, anda dapat meningkatkan kemahiran pengaturcaraan anda dengan berkesan. 1. Ketahui Pengetahuan Baru: Baca dokumen atau tutorial menonton. 2. Amalan: Tulis kod dan latihan lengkap. 3. Kajian: Menyatukan kandungan yang telah anda pelajari. 4. Amalan Projek: Sapukan apa yang telah anda pelajari dalam projek sebenar. Pelan pembelajaran berstruktur seperti ini dapat membantu anda menguasai Python secara sistematik dan mencapai matlamat kerjaya.

Kaedah untuk belajar python dengan cekap dalam masa dua jam termasuk: 1. Semak pengetahuan asas dan pastikan anda sudah biasa dengan pemasangan Python dan sintaks asas; 2. Memahami konsep teras python, seperti pembolehubah, senarai, fungsi, dan lain -lain; 3. Menguasai penggunaan asas dan lanjutan dengan menggunakan contoh; 4. Belajar kesilapan biasa dan teknik debugging; 5. Memohon pengoptimuman prestasi dan amalan terbaik, seperti menggunakan komprehensif senarai dan mengikuti panduan gaya PEP8.

Python sesuai untuk pemula dan sains data, dan C sesuai untuk pengaturcaraan sistem dan pembangunan permainan. 1. Python adalah mudah dan mudah digunakan, sesuai untuk sains data dan pembangunan web. 2.C menyediakan prestasi dan kawalan yang tinggi, sesuai untuk pembangunan permainan dan pengaturcaraan sistem. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Python lebih sesuai untuk sains data dan perkembangan pesat, manakala C lebih sesuai untuk prestasi tinggi dan pengaturcaraan sistem. 1. Sintaks Python adalah ringkas dan mudah dipelajari, sesuai untuk pemprosesan data dan pengkomputeran saintifik. 2.C mempunyai sintaks kompleks tetapi prestasi yang sangat baik dan sering digunakan dalam pembangunan permainan dan pengaturcaraan sistem.

Adalah mungkin untuk melabur dua jam sehari untuk belajar Python. 1. Belajar Pengetahuan Baru: Ketahui konsep baru dalam satu jam, seperti senarai dan kamus. 2. Amalan dan Amalan: Gunakan satu jam untuk melakukan latihan pengaturcaraan, seperti menulis program kecil. Melalui perancangan dan ketekunan yang munasabah, anda boleh menguasai konsep teras Python dalam masa yang singkat.

Python lebih mudah dipelajari dan digunakan, manakala C lebih kuat tetapi kompleks. 1. Sintaks Python adalah ringkas dan sesuai untuk pemula. Penaipan dinamik dan pengurusan memori automatik menjadikannya mudah digunakan, tetapi boleh menyebabkan kesilapan runtime. 2.C menyediakan kawalan peringkat rendah dan ciri-ciri canggih, sesuai untuk aplikasi berprestasi tinggi, tetapi mempunyai ambang pembelajaran yang tinggi dan memerlukan memori manual dan pengurusan keselamatan jenis.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

VSCode Windows 64-bit Muat Turun
Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

mPDF
mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),
