python装饰器【单例模式】,一段代码的理解

以下摘自https://zhuanlan.zhihu.com/p/269012332

instances = {}

def singleton(cls):
    def get_instance(*args, **kw):
        cls_name = cls.__name__
        if not cls_name in instances:
            instance = cls(*args, **kw)
            instances[cls_name] = instance
        return instances[cls_name]
    return get_instance

@singleton
class User:
    _instance = None

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

u1 = User('zhouxixi1')
u1.age = 20
u2 = User('zhouxixi2')
print(u2.age)
assert u1 is u2

执行顺序

instances = {} # 定义空字典

u1 = User('zhouxixi1') # 实例化User类,传入name=zhouxixi1

# 本来应该走class User这一步的,因为加了装饰器,所以先运行装饰器,随后在装饰器内运行类
def singleton(cls):  # cls为接受的类,此处为传入的User类

def get_instance(*args, **kwargs) # 此处接受类的参数,此处为传入的zhouxixi1(放在args中)

cls_name = cls.__name__ # 把cls.__name__赋值给cls_name ,此处cls.__name__为User类的名字,即User

if cls_name not in instances: # 如果cls_name 没有在instances 字典中,则继续

instance = cls(*args, **kwargs) # 此处要执行类了,实例化类User,此处args中包含了zhouxixi1

def __init__(self, name) # 执行构造函数,此处name为传入的*args,即zhouxixi1

self.name = name # zhouxixi1赋值给self.name

instance = cls(*args, **kwargs) # 回到这里,生成类的实例instance 

instances[cls_name] = instance # 在字典instances中加入key:cls_name即User,value:instance ,即User object

return instances[cls_name] # 返回User object

# u1 = User('zhouxixi1')执行完成,获得u1:<__main__.User object at 0x000001EB1E42CD90>

u1.age = 20 

u2 = User('zhouxixi2') # 同u1的执行步骤
...
...
...
# 以上中间步骤省略
if cls_name not in instances: # 执行到这里,因为instances已经包含User了,所以就不往下走了

return instances[cls_name] # 直接返回和u1同一个User object

print(u2.age) # u1,u2是同一个object,所以都有age属性

assert u1 is u2 # true

关于一直没用到的 return get_instance,
需要知道的是装饰器必须返回一个可被调用对象callable,固定格式吧,需要把get_instance返回回去

return get_instance
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值