47 单例模式 和装饰器

一.装饰 器 

  不改变被装饰函数原来的执行方式 给原函数增加一些额外的功能,登录验证,打印日志,测试效率等。

 

1.简单版装饰器

import time

#装饰器

def
timer(f) : def inner(): #被装饰函数执行前 要做的事情
start_time = time.time() res = f() #被装饰的函数 #被装饰函数执行后 要做的事情 end_time = time.time() print("函数执行时间:",end_time-start_time) return res return inner @timer #相当于 func = timer(func)
#被装饰函数
def func(x,y):
  print(x+y)
  return x+y

func()

2.带参数的装饰器

  带参数装饰器一   :控制装饰器的关和开

# 带参数的装饰器    可以同时控制装饰器的启用和关闭
import time
def timmer(flag):
    def wrapper(f):
        def inner(*args, **kwargs):
            if flag:
                start_time = time.time()
                ret = f(*args, **kwargs)
                end_time = time.time()
                print('执行时间%s' % (end_time-start_time))
                return ret
            else:
                ret = f(*args, **kwargs)
                return ret
        return inner
    return wrapper

flag1 = False
@timmer(flag1)  # 第一步,将@ 与后面 分开,只是单纯的执行timmer(flag1)函数     第二步 将@ 与 wrapper相结合,形成装饰器
def func1():
    time.sleep(0.3)
    print('in func1')

@timmer(flag1)
def func2():
    time.sleep(0.3)
    print('in func2')

@timmer(flag1)
def func3():
    time.sleep(0.3)
    print('in func3')

func1()
func2()
func3()

  带参数装饰器二 : 

# 做一个带参数的装饰器:
# 访问JD  JD_shop 输入京东的账号密码
# 访问taobao tianmao_shop() 输入支付宝的账号密码


status = {
    "username":None,
    "京东":False,
    "淘宝":False
}
def login(flag):
    def wapper(f):
        def inner(*args,**kwargs):
            if status[flag]:
                res = f(*args,**kwargs)
                return res
            else:
                print("-----登录页面-------")
                username = input("请输入用户名:").strip()
                password = input("请输入密码:").strip()
                with open(flag,"r",encoding="utf-8") as f1:
                    for line in f1:
                        user,pwd  = line.strip().split("|")
                        if user.strip() == username and password == pwd.strip():
                            status [flag] = True
                            print("登录成功!")
                            res = f(*args, **kwargs)
                            return res
                    else:
                        print("登录失败!")
        return inner
    return wapper


@login('京东')
def JD():
    print("-----欢迎进入京东首页!------")
@login('京东')
def JD_shop():
    print("-----欢迎进入京东商店!------")

@login('淘宝')
def taobao():
    print("-----欢迎进入淘宝首页!------")
@login('淘宝')
def tianmao_shop():
    print("-----欢迎进入天猫超市!------")


JD()
JD_shop()
taobao()
tianmao_shop()

 

3. 多个装饰器,装饰同一个函数

#多个装饰器 装饰一个函数

def wrapper1(func):  # func == f 函数名
    def inner1():
        print('wrapper1 ,before func')  # 2
        func()
        print('wrapper1 ,after func')  # 4
    return inner1

def wrapper2(func):  # func == inner1
    def inner2():
        print('wrapper2 ,before func')  # 1
        func()
        print('wrapper2 ,after func')  # 5
    return inner2

# 就近原则
@wrapper2  # f = wrapper2(f) 里面f == inner1  外面的f == inner2
@wrapper1  # f = wrapper1(f) 里面的f == 函数名f   外面的f == inner1
def f():
    print('in f')  # 3
f()  # inner2()

二. 单例模式

#单例模式  :只能创建同一个实例对象
class A:
    def __new__(cls, *args, **kwargs):
        print(111)
        obj = object.__new__(cls)
        return obj
    def __init__(self):
        print(222)
obj1 = A()

class A:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if A.__instance is None:
            obj = object.__new__(cls)
            A.__instance = obj
        return A.__instance
obj1 = A()
obj2 = A()
obj3 = A()
obj4 = A()
print(obj1)
print(obj2)
print(obj3)
print(obj4)

 

posted @ 2018-12-21 22:00  冰底熊  阅读(224)  评论(0编辑  收藏  举报