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.
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.
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
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.
# 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") # 创建单例实例
# main.py from mymodule import my_singleton # 使用单例实例 my_singleton.say_hello() # 输出:Hello, my name is Alice.
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.
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.
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!