闭包函数和装饰器

知识点1:闭包函数

1.1.定义:

1>.定义在函数内部的函数

2>.内层函数使用了外层函数名称空间中的名字

def func1():
    name = 'jason'

    def func2():
        print(name)
        

def func1(name):
    def func2():
        print(name)

    func2()


func1()

知识点2:装饰器

2.1本质

1>.不改变被装饰对象原来的“调用方式”和“内部代码”

2>.给原函数增加新的功能

2.2原则

1>.对修改封闭,对扩散开放

2.3装饰器的推导过程
```python
import time


# 4.装饰器的引入
def display_time(func):
    def wapper():
        t1 = time.time()
        func()
        t2 = time.time()
        print(t2 - t1)
    return wapper


# 6.加入参数的装饰器
def display_time(func):
    def wapper(*args):
        t1 = time.time()
        result = func(*args)
        t2 = time.time()
        print('运行时间是 {:.4} 秒'.format(t2 - t1))
        return func
    return wapper


# 1.首先书写一个判断是否质数的函数
def is_prime(num):
    if num < 2:
        return False
    elif num == 2:
        return True
    else:
        for i in range(2, num):
            if num % i == 0:
                return False
        return True


# 2(函数2).再写一个判断0-10000之间质数的函数
# def prime_num():
#     for i in range(2, 10000):
#         if is_prime(i):
#             print(i)


# 3(函数3).现在我们需要增加一个新的功能:得到函数2运行花费的时间
# @display_time
# def account_prime_num():
#     # t1 = time.time()
#     account = 0
#     for i in range(2, 10000):
#         if is_prime(i):
#             # print(i)
#             account += 1
#     print(account)
#     # t2 = time.time()
#     # print(t2 - t1)


'''4.那如果除了函数2,还有n多个函数也需要得到运行其所花费的时间,
每一个函数里面都会加入相同的代码,违背了写代码简洁的原则,那这里我
们就可以把这个功能写道一个函数当中,到时候需要的时候直接用就行了'''

# 5.那我们又想给函数函数3增加一个新的功能:打印出质数的总数量

# 6.那如果函数3有参数num,而不是固定值:10000


@display_time
def account_prime_num(num):
    # t1 = time.time()
    account = 0
    for i in range(2, num):
        if is_prime(i):
            # print(i)
            account += 1
    print(account)
    # t2 = time.time()
    # print(t2 - t1)


account_prime_num(10000)
2.4装饰器的固定模板
from functools import wraps
def outer(func_name):
    @wraps(func_name)  # 仅仅是为了让装饰器不容易被别人发现 做到真正的以假乱真
    def inner(*args, **kwargs):
        print('执行被装饰对象之前可以做的额外操作')
        res = func_name(*args, **kwargs)
        print('执行被装饰对象之后可以做的额外操作')
        return res
    return inner

练习(功能没问题,代码我自己都觉得太垃圾)

前提:用文件data.txt当作数据库,文件格式是:jason|111|10000

data_dic = {
    'is_auth': ''  # 默认没登录的情况下0,如果登录了1
}
from functools import wraps


# 验证用户是否存在和登录的装饰器
def auth_emp(func):
    @wraps(func)
    def inner(*args, **kwargs):
        username = input('username').strip()
        with open(r'data.txt', 'r', encoding='utf8') as f:
            data = f.read()
        if username == data.strip('\n').split('|')[0]:
            # print('用户已存在')
            res = func(*args, **kwargs)
            return res

    return inner



# 1.注册
def register():
    while True:
        # print('注册'.center(50, '*'))
        username = input('username').strip()
        with open(r'data.txt', 'r', encoding='utf8') as f:
            data = f.read()
        if username == data.strip('\n').split('|')[0]:
            print('用户名已注册')
            continue
        else:
            password = input('password').strip()
            emp_data = f'{username}|{password}|10000\n'
            with open(r'data.txt', 'w', encoding='utf8') as f:
                f.write(emp_data)
                print(f'用户{username}注册成功')
            break


# 2.登录
@auth_emp
def login():
    # print('登录功能'.center(50, '*'))
    while True:
        if data_dic.get('is_auth') == '1':
            print('用户已登录')
            break
        else:
            password = input("password").strip()
            with open(r'data.txt', 'r', encoding='utf8') as f:
                data = f.read()
                if password == data.strip('\n').split('|')[1]:
                    data_dic['is_auth'] = '1'
                    print('登录成功')
                    break
                print('密码错误')
                continue


# 3.转账
@auth_emp
def transfer():
    while True:
        # print('转账功能'.center(50, '*'))
        if data_dic.get('is_auth') == '1':
            money = input('请输入你要转账的金额').strip()
            money = int(money)
            with open(r'data.txt', 'r', encoding='utf8') as f:
                data = f.read()
                username = data.strip('\n').split('|')[0]
                password = data.strip('\n').split('|')[1]
                account = int(data.strip('\n').split('|')[2])
                if money <= account:
                    account -= money
                    with open(r'data.txt', 'w', encoding='utf8') as f1:
                        f1.write(f'{username}|{password}|{account}\n')
                        print(f'用户{username}成功转账{money}元')
                        return
            break
        else:
            # username = input('username').strip()
            password = input('password').strip()
            data_dic['is_auth'] = '1'
            while True:
                money = input('请输入你要转账的金额').strip()
                money = int(money)
                with open(r'data.txt', 'r', encoding='utf8') as f:
                    data = f.read()
                    username = data.strip('\n').split('|')[0]
                    account = int(data.strip('\n').split('|')[2])
                    if money <= account:
                        account -= money
                        with open(r'data.txt', 'w', encoding='utf8') as f1:
                            f1.write(f'{username}|{password}|{account}\n')
                            print(f'用户{username}成功转账{money}元')
                            return

                    else:
                        print('输入的金额超多账户余额,请重新输入')
                        continue


# 4.提现
@auth_emp
def withdraw():
    while True:
        # print('提现功能'.center(50, '*'))
        if data_dic.get('is_auth') == '1':
            money = input('请输入你要提现的金额').strip()
            money = int(money)
            with open(r'data.txt', 'r', encoding='utf8') as f:
                data = f.read()
                username = data.strip('\n').split('|')[0]
                password = data.strip('\n').split('|')[1]
                account = int(data.strip('\n').split('|')[2])
                account += money
                with open(r'data.txt', 'w', encoding='utf8') as f1:
                    f1.write(f'{username}|{password}|{account}\n')
                    print(f'用户{username}成功提现{money}元')
                    return
        else:
            # username = input('username').strip()
            password = input('password').strip()
            data_dic['is_auth'] = '1'
            while True:
                money = input('请输入你要提现的金额').strip()
                money = int(money)
                with open(r'data.txt', 'r', encoding='utf8') as f:
                    data = f.read()
                    username = data.strip('\n').split('|')[0]
                    account = int(data.strip('\n').split('|')[2])
                    account += money
                    with open(r'data.txt', 'w', encoding='utf8') as f1:
                        f1.write(f'{username}|{password}|{account}\n')
                        print(f'用户{username}成功提现{money}元')
                        return


data_dic = {
    '1': register,
    '2': login,
    '3': transfer,
    '4': withdraw,
}

while True:
    print("""
    1 注册
    2 登录
    3 转账
    4 提现
    5 退出
    """)
    choice = input('请输入编号').strip()
    if choice in data_dic:
        data_dic[choice]()
    elif choice == '5':
        print('退出')
        break
    else:
        print('请输入正确得编号')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值