- class MySingleton:
- def __init__(self):
- pass
-
- def __new__(cls, *args, **kwargs):
- pass
-
-
- mysingleton1 = MySingleton()
- mysingleton2 = MySingleton()
- print(mysingleton1)
- print(mysingleton2)
- print(id(mysingleton1))
- print(id(mysingleton2))
- print(mysingleton1 == mysingleton2)
输出结果:
None
None
1601545424
1601545424
True
此时连个对象是同一个对象,但是都是None,也就是没有进行实例化,失败。
- class MySingleton:
- def __init__(self):
- pass
-
- def __new__(cls, *args, **kwargs):
- # 创建对象,并返回
- return super(MySingleton, cls).__new__(cls)
-
-
- mysingleton1 = MySingleton()
- mysingleton2 = MySingleton()
- print(mysingleton1)
- print(mysingleton2)
- print(id(mysingleton1))
- print(id(mysingleton2))
- print(mysingleton1 == mysingleton2)
输出结果:
<__main__.MySingleton object at 0x0000024BEB827A20>
<__main__.MySingleton object at 0x0000024BEB827AC8>
2525096999456
2525096999624
False
创建了对象,但是却创建了两次,失败。
- class MySingleton:
-
- __instance = None
-
- def __init__(self, name, age):
- self.name = name
- self.age = age
- print("调用了__init方法__")
-
- def __new__(cls, *args, **kwargs):
- # 如果类属性__instance不为None,则直接返回它的值
- if cls.__instance:
- return cls.__instance
-
- # 如果类属性__instance是None
- # 创建对象,并返回
- cls.__instance = super(MySingleton, cls).__new__(cls)
- return cls.__instance
-
-
- mysingleton1 = MySingleton(name='zhangsan', age=25)
- mysingleton2 = MySingleton(name='lisi', age=35)
- print(mysingleton1)
- print(mysingleton2)
- print(id(mysingleton1))
- print(id(mysingleton2))
- print(mysingleton1 == mysingleton2)
- # mysingleton1的值被覆盖掉了,因为__init__方法调用了两次
- print(mysingleton1.name, str(mysingleton1.age))
- print(mysingleton2.name, str(mysingleton2.age))
输出结果:
调用了__init方法__
调用了__init方法__
<__main__.MySingleton object at 0x000001F49B877400>
<__main__.MySingleton object at 0x000001F49B877400>
2150092993536
2150092993536
True
lisi 35
lisi 35
是同一个对象,但是第二次赋值'lisi'覆盖了'zhangsan'的赋值,失败。
- class MySingleton:
-
- __instance = None
-
- def __init__(self, name, age):
- # 如果对象没有'name‘属性,就赋值,否则不赋值
- if not hasattr(self, 'name'):
- self.name = name
- self.age = age
- print("调用了__init方法__")
-
- def __new__(cls, *args, **kwargs):
- # 如果类属性__instance不为None,则直接返回它的值
- if cls.__instance:
- return cls.__instance
-
- # 如果类属性__instance是None
- # 创建对象,并返回
- cls.__instance = super(MySingleton, cls).__new__(cls)
- return cls.__instance
-
-
- mysingleton1 = MySingleton(name='zhangsan', age=25)
- mysingleton2 = MySingleton(name='lisi', age=35)
- print(mysingleton1)
- print(mysingleton2)
- print(id(mysingleton1))
- print(id(mysingleton2))
- print(mysingleton1 == mysingleton2)
- # mysingleton1的值被覆盖掉了,因为__init__方法调用了两次
- print(mysingleton1.name, str(mysingleton1.age))
- print(mysingleton2.name, str(mysingleton2.age))
输出结果:
调用了__init方法__
调用了__init方法__
<__main__.MySingleton object at 0x000002B02C8A7A20>
<__main__.MySingleton object at 0x000002B02C8A7A20>
2955684772384
2955684772384
True
zhangsan 25
zhangsan 25
同一个对象,值也没有发生覆盖,算是成功。
但是如果多线程情况呢?
- import threading
-
-
- class MySingleton:
-
- __instance = None
- __instence_lock = threading.Lock()
-
- def __init__(self, name, age):
- # 如果对象没有'name‘属性,就赋值,否则不赋值
- if not hasattr(self, 'name'):
- self.name = name
- self.age = age
- print("调用了__init方法__")
-
- def __new__(cls, *args, **kwargs):
- # 如果类属性__instance为None
- if not cls.__instance:
- # 代码块加锁,线程排队后再次判断是否为None
- with MySingleton.__instence_lock:
- if not cls.__instance:
- # 如果类属性__instance是None,创建对象
- cls.__instance = object.__new__(cls)
- return cls.__instance
-
- def __str__(self):
- # 类似java的toString
- return str(id(self)) + " [name] = " + self.name + " [age] = " + str(self.age)
-
-
- # 类似java的Thread中的run方法
- def task(name, age):
- obj = MySingleton(name=name, age=age)
- print(obj)
-
-
- for i in range(50):
- thread = threading.Thread(target=task, args=['name' + str(i), 30 + i])
- thread.start()
- class Car(object):
-
- def run(self):
- print("__轿车__在跑")
-
-
- class Benz(Car):
-
- def run(self):
- print("[奔驰]在跑")
-
-
- class Bmw(Car):
-
- def run(self):
- print("[宝马]在跑")
-
-
- class Audi(Car):
-
- def run(self):
- print("[奥迪]在跑")
-
-
- class User(object):
-
- def __init__(self, name):
- self.name = name
-
- def drive(self, car):
- print(self.name, "驾驶", end='')
- car.run()
-
-
- user = User('张三')
- user.drive(Audi())
- user.drive(Bmw())
- user.drive(Benz())
-
-
- class Factory(object):
-
- @staticmethod
- def get_tool(toolname):
- if 'benz' == toolname:
- return Benz()
- elif 'bmw' == toolname:
- return Bmw()
- elif 'audi' == toolname:
- return Audi()
- else:
- return Car()
-
-
- print()
-
- user.drive(Factory.get_tool('audi'))
- user.drive(Factory.get_tool('bmw'))
- user.drive(Factory.get_tool('benz'))
- user.drive(Factory.get_tool('hello'))
-