1、获取当前月份前一个月月份import datetime aaa = ((datetime.datetime.now() + datetime.timedelta(days = -30))).strftime("%Y%m") print(aaa)2、遍历目录os.walk(dir_name)def go_though():'''遍历指定目录'''db_path = db_handler.db_handler(settings.DATABASE)# 获取路径,目录,文件名称for root, dirs, files in os.walk(db_path):print("root:%s, dirs:%s files:%s" % (root,dirs,files))for f in files:# 判断是否存在.json结尾的文件if os.path.splitext(f)[1] == ".json":# 获取账户IDaccount_id = os.path.splitext(f)[0] # 帐户id# account_file = "%s/%s.json" % (db_path, account_id)# account_data = auth.check_account(account_id) # 获取用户信息account_data = auth.ck_acc_data(account_id)# 判断用户权限是否为管理员if account_data:status = account_data['status']# print(status)print("Account bill:".center(50, "-"))# 除了管理员,普通帐户都应该出帐单,即使帐户禁用if status != 8:# print("status != 8 ",account_id) auth.display_account_info(account_data)get_user_bill(account_id) # 获取帐单print("End".center(50, "-"))return True3、用户登录次数验证def acc_login(user_data,log_obj):'''判断用户登录错误次数,超过3次记录日志和打印屏幕输出,使用字典方式支持多用户互相切换错误记录:param user_data::param log_obj: access_logger:return: auth = account_data'''account_login_dic = {}retry_count = 0exit_count = 4while user_data['is_authorized'] is False and retry_count < exit_count:account = input('\033[32;1m请输入账户ID:\033[0m'.strip())password = input('\033[32;1m请输入密码:\033[0m'.strip())# 判断用户正确性,用户正确则初始化用户数据状态auth = acc_auth(account,password)if auth:user_data['is_authorized'] = Trueuser_data['account_id'] = accountreturn authelse:#先检测 dic 里面是否有相同名称 的key,没有就增加,有就取valueif account not in account_login_dic: # 如果账户不存在于字典count = 0count += 1account_login_dic.update({account:count}) # 初始化新用户到字典else:count = account_login_dic[account] # 初始化 计数count += 1 # 到此处错误已经产生,错误次数+1account_login_dic.update({account:count}) # 将用户对应错误次数更新到字典# print("old",account_login_dic)for i in account_login_dic.values(): # 判断字典中用户名对应的 错误次数retry_count = i# print(retry_count)if retry_count == 3: # 判断用户是否产生3次错误,3次错误 记录日志 并且 退出当前程序curr_account = list(account_login_dic.keys())[list(account_login_dic.values()).index(retry_count)]# print(curr_account)# 记录用户错误行为日志log_obj.error(" [%s] have try too many attempts,System exit!" % (curr_account))exit()4、初始化用户数据到字典,再将字典写入数据文件curr_day = datetime.datetime.now().strftime("%Y-%m-%d") # 当前日期 yesterday = datetime.datetime.now() + datetime.timedelta(days=-1) # 昨天日期 after_3_years_day = yesterday.replace(year=(int(yesterday.strftime("%Y")) + 3)) # 三年后的昨天(过期时间) expire_day = after_3_years_day.strftime('%Y-%m-%d') # 过期日期 pay_day = 22 # 还款日 account_data = {'enroll_date': curr_day,'password': password,'id': account,'credit': 15000,'status': 0,'balance': 0.0,'expire_date': expire_day,'pay_day': pay_day} # 存储新用户数据 accounts.dump_account(account_data)5、空格分隔数据# 格式化输出结果,a,b间隔20个空格,以':' 分隔,b变色print("{:<20}:\033[32;1m{:<20}\033[0m".format(a,b))6、密码加密 def get_md5(password):'''用户密码加密:param password::return:'''# 获取 md5md5 = hashlib.md5()md5.update(password)return md5.hexdigest()7、日志记录函数 def logger(log_type):'''日志输出和记录:param log_type::return:'''logger = logging.getLogger(log_type)logger.setLevel(settings.LOG_LEVEL)# 屏幕输出 screen output showch = logging.StreamHandler()ch.setLevel(settings.LOG_LEVEL) # 屏幕 输出 info# 日志文件输出 logs file outputlog_file = "%s/logs/%s" % (settings.BASE_DIR,settings.LOG_TYPES[log_type])# print(log_file)fh = logging.FileHandler(log_file)fh.setLevel(settings.LOG_LEVEL) # 日志记录 info#日志输出格式formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')ch.setFormatter(formatter)fh.setFormatter(formatter)#屏幕输出和日志输出加入到logger logger.addHandler(ch)logger.addHandler(fh)#返回输出return logger8、根据传入类型函数进行操作函数 类型为在配置中定义值 TRANSACTION_TYPE = {'repay': {'action': 'plus', 'interest': 0}, # 还款'receive': {'action': 'plus', 'interest': 0}, # 接收'withdraw': {'action': 'minus', 'interest': 0.05}, # 提款'transfer': {'action': 'minus', 'interest': 0.05}, # 转出'pay': {'action': 'minus', 'interest': 0}, # 支付'save': {'action': 'plus', 'interest': 0}, # 存钱 }def make_transaction(log_obj,account_data,trans_type,amount,**others):'''用户金额操作改动数据后存储日志,改动后返回用户数据:param log_obj::param account_data::param trans_type::param amount::param others::return:account_data'''# 金额转换浮点类型amount = float(amount)# 判断 交易类型if trans_type in settings.TRANSACTION_TYPE: # 交易类型存在interest = amount * settings.TRANSACTION_TYPE[trans_type]['interest'] # 定义利息old_balance = account_data['balance'] # 初始化 交易前的值# 根据交易类型,对金额进行加减操作,并减除带有利息的操作if settings.TRANSACTION_TYPE[trans_type]['action'] == 'plus':new_balance = old_balance + amount + interestaccount_data['balance'] = new_balanceaccounts.dump_account(account_data)elif settings.TRANSACTION_TYPE[trans_type]['action'] == 'minus':new_balance = old_balance - amount - interestif new_balance < 0:print("\033[32;1m 您的信用额度为:[%s],您的额度不支持本次操作[-%s],您当前的余额为:[%s]\033[0m"%(account_data['credit'],(amount +interest),old_balance))return Falseaccount_data['balance'] = new_balanceaccounts.dump_account(account_data)# log_obj = transaction_logger = logger.logger('transaction')# 将操作记录到日志文件log_obj.info("accounts:%s action:%s amount:%s interest:%s "%(account_data['id'],trans_type,amount,interest))return account_dataelse:print("您的选项有误或不存在:%s"%(trans_type))9、接口调用流程 调用方: 以充值为例:atm_api = os.path.dirname(BASE_DIR) + "/Atm/api/pay_api.py"# 定义 接口文件和金额comm = "python " + atm_api + " " + charge# 创建 调用进程,执行指定的commpgm = subprocess.Popen(comm,shell=True)# 接口文件交互 pgm.communicate()if pgm.returncode == 0:print("\033[31;1m付款成功\033[0m")# 充值成功后,更新用户余额acc_data['balance'] += float(charge)# 将用户余额存入账户 accounts.dumpAccount(acc_data)print("您的余额为:%s"%acc_data['balance'])else:print("充值失败!")被调用方 入口 pay_api.py# 取金额参数 amount = sys.argv[1]# 执行接口程序调用,定义退出 rlt = main.payApi(amount)if rlt:exit(0) else:exit(1)def payApi(amount):'''交易接口,提供给其他消费方式调用:param amount::return:'''amount = int(amount)acc_data = get_user_data()# print("\033[42;1m payApi \033[0m",acc_data)# 根据获取到的用户id 获取用户数据account_data = accounts.load_balance(acc_data['account_id'])# 判断交易金额 是否大于,交易大于0 则进行交易操作if amount > 0:new_balance = transaction.make_transaction(transaction_logger,account_data,'pay',amount)if new_balance:return Trueelse:print("你的输入 [%s] 有误,请输入数字金额"% amount)return None