python装饰器实现单例模式

实现单例所利用的装饰器传参原理:

def fun1(fun):
    print('fun1 action')
    return fun

@fun1
def fun2():
    print('fun2 action')

# 在函数执行时,类对象会作为参数传给 装饰器
if __name__ == '__main__':
    fun2()

# 运行结果:
fun1 action
fun2 action

实现单例:
利用了闭包特性,具有全局唯一性:

def singleton(w):  # w 值得是作为参数传入的 类对象,此例中为 Student
    instances = {}
    def get_instance(*args, **kwargs):
        if w not in instances:
        	# 灵魂:实例化w对象,并存入instance中
            instances[w] = w(*args, **kwargs)
        return instances[w]
    return get_instance


@singleton
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age


student = Student('f', 25)
print(id(student))
print(student.name)
student1 = Student('w', 25)
print(id(student1))
print(student1.name)

# 运行结果:
140647278726392
f
140647278726392
f

注意:正是应为使用了装饰器来实现单例,它与重写 __ new __ 方法的方式实现单例有所区别

在装饰器中使用了闭包的特性,所以使用装饰器达到的单例具有全局唯一性,即:第一次实例化后就永久有效,后面实例化类对象无法更改类的所有属性。但是使用 __ new __ 方法的单例,在后面使用时可以对属性进行更改。

使用重写 __ new __方法来实现单例

class A(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
      		# 将使用 __new__ 方法创建的类作为 值 存储在cls的类属性中
            cls._instance = object.__new__(cls)
            return cls._instance
        else:
            return cls._instance

    def __init__(self, f):
        self.f = f

cc = A(23)
print(id(cc))
print(cc.f)
cc = A(66)
print(id(cc))
print(cc.f)

# 运行结果:
140197397482632
23
140197397482632
66

当然两种方式实现的都是单例,只是有所区别罢了,各自有各自的妙用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值