Jadual Kandungan
Cara terbaik untuk melaksanakan singleton dalam Python
Kaedah pelaksanaan
Kaedah 1: Penghias
Kaedah 2: Kelas asas
Kaedah 3: Metaclass
Kaedah 4: Kembalikan penghias kelas dengan nama yang sama
Kaedah 5: Modul
Kaedah Disyorkan
Peranan metaclass
Sudah tentu
Versi serasi Python 2 dan 3
Pembetulan
Rumah pembangunan bahagian belakang Tutorial Python Apakah cara terbaik untuk melaksanakan singleton dalam Python?

Apakah cara terbaik untuk melaksanakan singleton dalam Python?

Dec 17, 2024 pm 04:07 PM

What is the best way to implement a singleton in Python?

Cara terbaik untuk melaksanakan singleton dalam Python

Walaupun kelebihan dan kekurangan corak reka bentuk singleton bukanlah fokus artikel ini, artikel ini akan meneroka bagaimana untuk melaksanakan singleton dalam Python dengan cara yang terbaik. Di sini, "kebanyakan Pythonic" bermaksud mengikuti "prinsip paling tidak mengejutkan".

Kaedah pelaksanaan

Kaedah 1: Penghias

def singleton(class_):
    instances = {}

    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]

    return getinstance

@singleton
class MyClass(BaseClass):
    pass
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Kelebihan:

  • Penghias mempunyai jantina tambahan, lebih intuitif daripada pelbagai warisan.

Kelemahan:

  • Objek yang dicipta menggunakan MyClass() ialah objek tunggal sebenar, tetapi MyClass itu sendiri ialah fungsi, bukan kelas, jadi kaedah kelas tidak boleh dipanggil.

Kaedah 2: Kelas asas

class Singleton(object):
    _instance = None

    def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance

class MyClass(Singleton, BaseClass):
    pass
Salin selepas log masuk
Salin selepas log masuk

Kelebihan:

  • Ia adalah kelas sebenar.

Kelemahan:

  • Pewarisan berbilang, tidak menyenangkan. Apabila mewarisi daripada kelas asas kedua, __new__ boleh ditindih.

Kaedah 3: Metaclass

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

# Python2
class MyClass(BaseClass):
    __metaclass__ = Singleton

# Python3
class MyClass(BaseClass, metaclass=Singleton):
    pass
Salin selepas log masuk

Kelebihan:

  • Ia adalah kelas sebenar.
  • Warisan dilindungi secara automatik.
  • Gunakan __metaclass__ dengan betul (dan buat saya faham).

Kelemahan:

  • Tiada keburukan.

Kaedah 4: Kembalikan penghias kelas dengan nama yang sama

def singleton(class_):
    class class_w(class_):
        _instance = None

        def __new__(class_, *args, **kwargs):
            if class_w._instance is None:
                class_w._instance = super(class_w, class_).__new__(class_, *args, **kwargs)
                class_w._instance._sealed = False
            return class_w._instance

        def __init__(self, *args, **kwargs):
            if self._sealed:
                return
            super(class_w, self).__init__(*args, **kwargs)
            self._sealed = True

    class_w.__name__ = class_.__name__
    return class_w

@singleton
class MyClass(BaseClass):
    pass
Salin selepas log masuk

Kelebihan:

  • Ia adalah kelas sebenar.
  • Warisan dilindungi secara automatik.

Keburukan:

  • Adakah terdapat overhed dalam mencipta dua kelas untuk setiap kelas yang anda mahu menjadi singleton? Walaupun ini berfungsi dengan baik dalam kes saya, saya bimbang ia mungkin tidak berskala. Apakah tujuan
  • _sifat termeterai?
  • Anda tidak boleh menggunakan super() untuk memanggil kaedah dengan nama yang sama dalam kelas asas kerana ia akan menjadi rekursif. Ini bermakna __new__ tidak boleh disesuaikan, begitu juga kelas yang memerlukan panggilan __init__ boleh disubkelaskan.

Kaedah 5: Modul

Singleton module singleton.py.

Kebaikan:

  • Mudah lebih baik daripada kompleks.

Kelemahan:

  • Bukan instantiasi tertunda.

Kaedah Disyorkan

Saya syorkan menggunakan Kaedah 2, tetapi lebih baik menggunakan metaclass berbanding kelas asas. Berikut ialah contoh pelaksanaan:

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Logger(object):
    __metaclass__ = Singleton
Salin selepas log masuk

Atau dalam Python3:

class Logger(metaclass=Singleton):
    pass
Salin selepas log masuk

Jika anda mahu __init__ dijalankan setiap kali kelas dipanggil, tambah kod berikut pada Singleton.__call__ In pernyataan if:

def singleton(class_):
    instances = {}

    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]

    return getinstance

@singleton
class MyClass(BaseClass):
    pass
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Peranan metaclass

Metaclass ialah kelas kelas, iaitu kelas ialah instance daripada metaclassnya. Metaclass objek dalam Python boleh didapati melalui type(obj). Kelas baharu biasa adalah jenis jenis. Logger di atas akan menjadi kelas jenis 'your_module.Singleton' sama seperti contoh (sahaja) Logger akan menjadi kelas jenis 'your_module.Logger' . Apabila logger dipanggil menggunakan Logger(), Python terlebih dahulu bertanya kepada Singleton metaclass Logger apa yang patut dilakukannya, membenarkan penciptaan instance preemptive. Proses ini serupa dengan cara Python meminta kelas apa yang harus dilakukan dengan atributnya dengan memanggil __getattr__, dan anda merujuk atributnya dengan melakukan myclass.attribute.

Metaclasses pada asasnya menentukan maksud kelas panggilan dan cara melaksanakan makna tersebut. Lihat mis. http://code.activestate.com/recipes/498149/ yang menggunakan metaclass untuk mencipta semula struktur gaya C dalam Python. Thread Perbincangan [Apakah kes penggunaan khusus untuk metaclass? ](https://codereview.stackexchange.com/questions/82786/what-are-some-concrete-use-cases-for-metaclasses) juga menyediakan beberapa contoh, yang umumnya berkaitan dengan pengaturcaraan deklaratif, terutamanya dalam ORM yang digunakan dalam .

Dalam kes ini, jika anda menggunakan Kaedah 2 anda dan subkelas mentakrifkan kaedah __baru__, ia akan dilaksanakan setiap kali SubClassOfSingleton() dipanggil, kerana Ia bertanggungjawab untuk memanggil kaedah yang kembalikan kejadian yang disimpan. Dengan metaclass, ia hanya dilaksanakan sekali, apabila contoh unik dibuat. Anda perlu menyesuaikan definisi kelas panggilan, yang ditentukan oleh jenisnya.

Secara umum, masuk akal untuk menggunakan metaclass untuk melaksanakan singleton. Singleton adalah istimewa kerana contohnya dibuat sekali sahaja, manakala metaclass ialah pelaksanaan tersuai bagi kelas yang dicipta yang menjadikannya berkelakuan berbeza daripada kelas biasa. Menggunakan metaclass memberi anda lebih kawalan apabila anda sebaliknya perlu menyesuaikan definisi kelas tunggal anda.

Sudah tentu

Tunggal anda tidak memerlukan warisan berbilang (kerana metaclass bukan kelas asas), tetapi untuk warisan mencipta subkelas kelas, anda perlu memastikan tunggal kelas ialah yang pertama/ Metaclass paling kiri mentakrifkan semula __call__. Ini tidak mungkin menjadi masalah. Kamus contoh tiada dalam ruang nama contoh, jadi ia tidak boleh ditimpa secara tidak sengaja.

Anda juga akan mendengar bahawa corak tunggal melanggar "prinsip tanggungjawab tunggal", yang bermaksud bahawa setiap kelas hanya perlu melakukan satu perkara. Dengan cara ini, anda tidak perlu risau tentang memecahkan satu perkara yang dilakukan oleh kod apabila anda perlu menukar kod lain kerana ia bebas dan dikapsulkan. Pelaksanaan metaclass melepasi ujian ini. Metaclasses bertanggungjawab untuk menguatkuasakan corak, mencipta kelas dan subkelas yang tidak perlu sedar bahawa mereka adalah tunggal. Kaedah 1 gagal dalam ujian ini, seperti yang anda nyatakan dengan "MyClass itu sendiri ialah fungsi, bukan kelas, jadi kaedah kelas tidak boleh dipanggil".

Versi serasi Python 2 dan 3

Menulis kod dalam Python 2 dan 3 memerlukan skema yang lebih rumit. Memandangkan metaclass biasanya merupakan subclass bagi kelas jenis, anda boleh menggunakan metaclass untuk mencipta kelas asas perantara secara dinamik dengannya sebagai metaclass pada masa jalanan, dan kemudian menggunakan kelas asas itu sebagai kelas asas untuk kelas asas singleton awam. Ini lebih mudah diucapkan daripada dilakukan, seperti berikut:

def singleton(class_):
    instances = {}

    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]

    return getinstance

@singleton
class MyClass(BaseClass):
    pass
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Satu ironi pendekatan ini ialah ia menggunakan subkelas untuk melaksanakan metaclass. Satu kelebihan yang mungkin ialah, tidak seperti metaclass tulen, isinstance(inst, Singleton) akan mengembalikan True.

Pembetulan

Berkenaan topik lain, anda mungkin perasan, tetapi pelaksanaan kelas asas dalam siaran asal anda adalah salah. Untuk merujuk _instances dalam kelas, anda perlu menggunakan super(), atau kaedah statik kaedah kelas, kerana kelas sebenar belum lagi dibuat pada masa panggilan. Semua ini berlaku untuk pelaksanaan metaclass juga.

class Singleton(object):
    _instance = None

    def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance

class MyClass(Singleton, BaseClass):
    pass
Salin selepas log masuk
Salin selepas log masuk

Atas ialah kandungan terperinci Apakah cara terbaik untuk melaksanakan singleton dalam Python?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

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

Artikel Panas

<🎜>: Bubble Gum Simulator Infinity - Cara Mendapatkan dan Menggunakan Kekunci Diraja
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Sistem Fusion, dijelaskan
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers of the Witch Tree - Cara Membuka Kunci Cangkuk Bergelut
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial Java
1665
14
Tutorial PHP
1270
29
Tutorial C#
1249
24
Python vs C: Aplikasi dan kes penggunaan dibandingkan Python vs C: Aplikasi dan kes penggunaan dibandingkan Apr 12, 2025 am 12:01 AM

Python sesuai untuk sains data, pembangunan web dan tugas automasi, manakala C sesuai untuk pengaturcaraan sistem, pembangunan permainan dan sistem tertanam. Python terkenal dengan kesederhanaan dan ekosistem yang kuat, manakala C dikenali dengan keupayaan kawalan dan keupayaan kawalan yang mendasari.

Python: Permainan, GUI, dan banyak lagi Python: Permainan, GUI, dan banyak lagi Apr 13, 2025 am 12:14 AM

Python cemerlang dalam permainan dan pembangunan GUI. 1) Pembangunan permainan menggunakan pygame, menyediakan lukisan, audio dan fungsi lain, yang sesuai untuk membuat permainan 2D. 2) Pembangunan GUI boleh memilih tkinter atau pyqt. TKInter adalah mudah dan mudah digunakan, PYQT mempunyai fungsi yang kaya dan sesuai untuk pembangunan profesional.

Python vs C: Lengkung pembelajaran dan kemudahan penggunaan Python vs C: Lengkung pembelajaran dan kemudahan penggunaan Apr 19, 2025 am 12:20 AM

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.

Python dan Masa: Memanfaatkan masa belajar anda Python dan Masa: Memanfaatkan masa belajar anda Apr 14, 2025 am 12:02 AM

Untuk memaksimumkan kecekapan pembelajaran Python dalam masa yang terhad, anda boleh menggunakan modul, masa, dan modul Python. 1. Modul DateTime digunakan untuk merakam dan merancang masa pembelajaran. 2. Modul Masa membantu menetapkan kajian dan masa rehat. 3. Modul Jadual secara automatik mengatur tugas pembelajaran mingguan.

Python vs C: Meneroka Prestasi dan Kecekapan Python vs C: Meneroka Prestasi dan Kecekapan Apr 18, 2025 am 12:20 AM

Python lebih baik daripada C dalam kecekapan pembangunan, tetapi C lebih tinggi dalam prestasi pelaksanaan. 1. Sintaks ringkas Python dan perpustakaan yang kaya meningkatkan kecekapan pembangunan. 2. Ciri-ciri jenis kompilasi dan kawalan perkakasan meningkatkan prestasi pelaksanaan. Apabila membuat pilihan, anda perlu menimbang kelajuan pembangunan dan kecekapan pelaksanaan berdasarkan keperluan projek.

Python: Automasi, skrip, dan pengurusan tugas Python: Automasi, skrip, dan pengurusan tugas Apr 16, 2025 am 12:14 AM

Python cemerlang dalam automasi, skrip, dan pengurusan tugas. 1) Automasi: Sandaran fail direalisasikan melalui perpustakaan standard seperti OS dan Shutil. 2) Penulisan Skrip: Gunakan Perpustakaan Psutil untuk memantau sumber sistem. 3) Pengurusan Tugas: Gunakan perpustakaan jadual untuk menjadualkan tugas. Kemudahan penggunaan Python dan sokongan perpustakaan yang kaya menjadikannya alat pilihan di kawasan ini.

Yang merupakan sebahagian daripada Perpustakaan Standard Python: Senarai atau Array? Yang merupakan sebahagian daripada Perpustakaan Standard Python: Senarai atau Array? Apr 27, 2025 am 12:03 AM

Pythonlistsarepartofthestandardlibrary, sementara

Pembelajaran Python: Adakah 2 jam kajian harian mencukupi? Pembelajaran Python: Adakah 2 jam kajian harian mencukupi? Apr 18, 2025 am 12:22 AM

Adakah cukup untuk belajar Python selama dua jam sehari? Ia bergantung pada matlamat dan kaedah pembelajaran anda. 1) Membangunkan pelan pembelajaran yang jelas, 2) Pilih sumber dan kaedah pembelajaran yang sesuai, 3) mengamalkan dan mengkaji semula dan menyatukan amalan tangan dan mengkaji semula dan menyatukan, dan anda secara beransur-ansur boleh menguasai pengetahuan asas dan fungsi lanjutan Python dalam tempoh ini.

See all articles