Apakah cara biasa untuk melaksanakan corak tunggal dalam Python?

WBOY
Lepaskan: 2023-05-12 09:07:17
ke hadapan
1032 orang telah melayarinya

Beberapa cara biasa untuk melaksanakan mod tunggal dalam Python

Metaclass:

class SingletonType(type):
    """
    单例元类。用于将普通类转换为单例类。
    """
    _instances = {}  # 存储单例实例的字典
    def __call__(cls, *args, **kwargs):
        """
        重写 __call__ 方法。用于创建和返回单例实例。
        """
        if cls not in cls._instances:  # 如果类还没有实例化过
            cls._instances[cls] = super().__call__(*args, **kwargs)  # 则创建新实例并存储在字典中
        return cls._instances[cls]  # 返回字典中的实例
class MyClass(metaclass=SingletonType):
    """
    单例类。使用元类 SingletonType 将其转换为单例类。
    """
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
# 创建 MyClass 的两个实例,应该是同一个对象
obj1 = MyClass("Alice")
obj2 = MyClass("Bob")
# 打印两个实例的内存地址,应该相同
print(hex(id(obj1)))  # 输出:0x7f8d94547a90
print(hex(id(obj2)))  # 输出:0x7f8d94547a90
# 调用两个实例的方法,输出应该相同
obj1.say_hello()  # 输出:Hello, my name is Alice.
obj2.say_hello()  # 输出:Hello, my name is Alice.
Salin selepas log masuk

Dalam kod di atas, kami mentakrifkan metaclass bernama SingletonType kelas dan menggunakannya sebagai metaclass MyClass. Dalam kelas SingletonType, kami mengekalkan kamus _instances yang menyimpan kejadian unik setiap kelas. Dalam kaedah __call__(), kami menyemak kamus _instances dan jika kelas belum mempunyai tika, buat tika baharu dan tambahkannya pada _instances. Akhirnya, kami mengembalikan contoh dalam _instances.

Dalam kelas MyClass, kami mentakrifkan pembina dengan parameter dan menggunakan parameter metaclass untuk menentukan SingletonType metaclass. Memandangkan kelas MyClass menggunakan metaclass SingletonType, ia mempunyai gelagat tunggal. Dalam program ini, kami mencipta dua kejadian MyClass, obj1 dan obj2, dan kemudian mencetak alamat memori mereka untuk mengesahkan sama ada ia adalah objek yang sama. Akhir sekali, kami memanggil kaedah pada kedua-dua keadaan dan output harus sama.

Penghias:

def singleton(cls):
    """
    单例装饰器。用于将普通类转换为单例类。
    """
    instances = {}  # 存储单例实例的字典
    def get_instance(*args, **kwargs):
        """
        获取单例实例的方法。
        """
        if cls not in instances:  # 如果类还没有实例化过
            instances[cls] = cls(*args, **kwargs)  # 则创建新实例并存储在字典中
        return instances[cls]  # 返回字典中的实例
    return get_instance
@singleton
class MyClass:
    """
    单例类。使用装饰器 singleton 将其转换为单例类。
    """
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
# 创建 MyClass 的两个实例,应该是同一个对象
obj1 = MyClass("Alice")
obj2 = MyClass("Bob")
# 打印两个实例的内存地址,应该相同
print(hex(id(obj1)))  # 输出:0x7f8d94547a90
print(hex(id(obj2)))  # 输出:0x7f8d94547
Salin selepas log masuk

Dalam kod di atas, kami mentakrifkan fungsi penghias bernama singleton. Di dalam fungsi singleton, kami mencipta kamus instances yang menyimpan contoh unik setiap kelas. Kemudian, kami mentakrifkan fungsi dalaman yang dipanggil get_instance yang mendapat tika tunggal. Dalam fungsi get_instance, kami menyemak kamus instances dan jika kelas belum mempunyai tika, buat tika baharu dan tambahkannya pada instances. Akhirnya, kami mengembalikan contoh dalam kamus.

Gunakan penghias MyClass pada kelas @singleton untuk menukarnya menjadi kelas tunggal. Memandangkan penghias ini beroperasi pada kelas, ia boleh menukar mana-mana kelas biasa kepada kelas tunggal dengan mudah. Dalam program ini, kami mencipta dua kejadian MyClass, obj1 dan obj2, dan kemudian mencetak alamat memori mereka untuk mengesahkan sama ada ia adalah objek yang sama. Akhir sekali, kami memanggil kaedah pada kedua-dua keadaan dan output harus sama.

Modul:

# mymodule.py
class MyClass:
    """
    单例类。
    """
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
my_singleton = MyClass("Alice")  # 创建单例实例
Salin selepas log masuk
# main.py
from mymodule import my_singleton
# 使用单例实例
my_singleton.say_hello()  # 输出:Hello, my name is Alice.
Salin selepas log masuk

Dalam kod di atas, kami mentakrifkan kelas MyClass dalam modul bebas mymodule.py dan mencipta tika tunggal di dalamnya my_singleton. Kemudian, dalam fail lain main.py, kami mengimport contoh mymodule daripada modul my_singleton dan menggunakannya untuk memanggil kaedah say_hello().

Memandangkan modul Python dilaksanakan secara automatik apabila pertama kali diimport, kami boleh memanfaatkan ciri ini untuk mencipta kejadian tunggal. Dalam modul mymodule.py kami boleh memastikan bahawa my_singleton hanya dibuat sekali dan berkongsi antara bahagian lain program.

kaedah baharu:

class MyClass:
    """
    单例类。
    """
    _instance = None  # 存储单例实例的类变量
    def __new__(cls, *args, **kwargs):
        """
        重写 __new__ 方法。用于创建和返回单例实例。
        """
        if cls._instance is None:  # 如果类还没有实例化过
            cls._instance = super().__new__(cls)  # 则创建新实例并存储在类变量中
        return cls._instance  # 返回类变量中的实例
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        print(f"Hello, my name is {self.name}.")
# 创建 MyClass 的两个实例,应该是同一个对象
obj1 = MyClass("Alice")
obj2 = MyClass("Bob")
# 打印两个实例的内存地址,应该相同
print(hex(id(obj1)))  # 输出:0x7f8d94547a90
print(hex(id(obj2)))  # 输出:0x7f8d94547a90
# 调用两个实例的方法,输出应该相同
obj1.say_hello()  # 输出:Hello, my name is Alice.
obj2.say_hello()  # 输出:Hello, my name is Alice.
Salin selepas log masuk

Dalam kod di atas, kami menukar pembina kelas MyClass kepada kaedah __new__() dan menggunakan pembolehubah kelas _instance untuk menyimpan contoh tunggal . Dalam kaedah __new__(), kami menyemak pembolehubah _instance dan jika kelas belum mempunyai tika, buat tika baharu dan tambahkannya pada _instance. Akhirnya, kami mengembalikan contoh dalam _instance.

Dalam atur cara, kami mencipta dua kejadian MyClass, obj1 dan obj2, dan kemudian mencetak alamat memori mereka untuk mengesahkan sama ada ia adalah objek yang sama. Akhir sekali, kami memanggil kaedah pada kedua-dua keadaan dan output harus sama.

Tidak kira kaedah mana yang digunakan untuk melaksanakan corak tunggal, anda perlu memberi perhatian kepada isu seperti keselamatan benang dan kebolehskalaan. Oleh itu, dalam pembangunan sebenar, sila pertimbangkan dengan teliti keperluan anda dan pilih pelaksanaan yang sesuai.

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

Label berkaitan:
sumber:yisu.com
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!