无参装饰器:
不修改原函数,加入装饰器,在原有基础上包装函数
#!/usr/bin/env python import time def timer(fun): def wrapper(*args, **kwargs): start = time.time() res = fun(*args, **kwargs) end = time.time() print(‘run time is %s‘ % (end - start)) return res return wrapper @timer def index(msg): print(‘in the index‘, msg) return 1 res = index print(res(‘w‘))
res现在返回装饰器中的wrapper对象,但没有执行
res(‘w‘)这时传参数,并执行wrapper函数,到执行fun(*args,**kwargs),此时执行的是index(msg),最后完成整个函数体。
有参装饰器
#!/usr/bin/env python user_list=[ {‘name‘:‘alex‘,‘passwd‘:‘123‘}, {‘name‘:‘linhaifeng‘,‘passwd‘:‘123‘}, {‘name‘:‘wupeiqi‘,‘passwd‘:‘123‘}, {‘name‘:‘yuanhao‘,‘passwd‘:‘123‘}, ] current_user={‘username‘:None,‘login‘:False} def auth(auth_type=‘file‘): def auth_deco(func): def wrapper(*args,**kwargs): if auth_type == ‘file‘: if current_user[‘username‘] and current_user[‘login‘]: res=func(*args,**kwargs) return res username=input(‘用户名: ‘).strip() passwd=input(‘密码: ‘).strip() for index,user_dic in enumerate(user_list): if username == user_dic[‘name‘] and passwd == user_dic[‘passwd‘]: current_user[‘username‘]=username current_user[‘login‘]=True res=func(*args,**kwargs) return res break else: print(‘用户名或者密码错误,重新登录‘) elif auth_type == ‘ldap‘: print(‘巴拉巴拉小魔仙‘) res=func(*args,**kwargs) return res return wrapper return auth_deco #auth(auth_type=‘file‘)就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type=‘file‘) #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type=‘file‘参数 @auth(auth_type=‘ldap‘) def index(): print(‘欢迎来到主页面‘) @auth(auth_type=‘ldap‘) def home(): print(‘这里是你家‘) def shopping_car(): print(‘查看购物车啊亲‘) def order(): print(‘查看订单啊亲‘) # print(user_list) index() # print(user_list) home()
有参装饰器就是在装饰器多加一层嵌套函数
模块:
import 模块
from 模块 import 方法
需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法
import 模块 as 重命名
from 模块 import *
#在模块文件写入 __all__=[‘money‘,‘read1‘] ,这样就指定*导入的方法了
当做脚本运行:
__name__ 等于‘__main__‘
作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
添加脚本模块查找路径
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(base_dir) #将绝对路径临时添加到python变量里,这样就可以找到下面的包了
特别需要注意的是:可以用import导入内置或者第三方模块,但是要绝对避免使用import来导入自定义包的子模块,应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式。
atm/
├── README.md
├── atm (ATM主程目录)
│ ├── __init__.py
│ ├── bin (ATM执行文件目录)
│ │ ├── __init__.py
│ │ ├── atm.py (ATM 执行程序)
│ │ └── manage.py (ATM 管理端)
│ ├── conf (配置文件)
│ │ ├── __init__.py
│ │ └── settings.py
│ ├── core (主要程序逻辑都在这个目录里)
│ │ ├── __init__.py
│ │ ├── accounts.py (用于从文件里加载和存储账户数据)
│ │ ├── auth.py (用户认证模块)
│ │ ├── db_handler.py (数据库连接引擎)
│ │ ├── logger.py (日志记录模块)
│ │ ├── main.py (主逻辑交互程序)
│ │ ├── manage_main.py (管理逻辑交互程序)
│ │ └── transaction.py (记账\还钱\取钱等所有的与账户金额相关的操作都在这)
│ ├── db (用户数据存储的地方)
│ │ ├── __init__.py
│ │ └── accounts (存各个用户的账户数据 ,一个用户一个文件)
│ │ └── 1234.json (一个用户账户文件)
│ │ └── account_id_record.json (一个用户账户id文件)
│ └── log
│ ├── __init__.py
│ ├── access.log
│ └── transactions.log
└── shopping_mall
└── __init__.py
bin下的atm.py是执行文件
# __author__:"wangyufu" import os import sys base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(base_dir) sys.path.append(base_dir) from core import main #会在sys.path下面找到core包导入main模块 if __name__ == ‘__main__‘: main.run()