1、logging模块有几个日志级别?
logging模块共有5个级别,分别是: DEBUG INFO WARNING ERROR CRITICALlogging的日志可以分为 debug(), info(), warning(), error(){ 美 /'ɛrɚ/ } and critical()5个级别
2、请配置logging模块,单独在文件,屏幕。同时在屏幕和文件打印以下格式的日志
#2017-10-18 15:56:26,613 - access - ERROR - account [1234] too many login attempts (1)仅将日志输出至屏幕
a = 123# 打印输出import logginglogging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p',level=logging.WARNING,filemode='a')logging.warning(f'{a}is when this event was logged.')
(2)仅将日志输出至文件
a = 123# 保存在文件中logging.basicConfig(filename='log.txt',format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.WARNING, filemode='a')logging.warning('how to use the python.')
#将日志同时输出到屏幕和日志文件import logging#logger提供了应用程序可以直接使用的接口;logger = logging.getLogger('access')logger.setLevel(level = logging.INFO)#handler将(logger创建的)日志记录发送到合适的目的输出;# FileHandler()输出至文件file = logging.FileHandler("log.txt",encoding='utf-8')file.setLevel(logging.ERROR)# StreamHandler()输出至屏幕console = logging.StreamHandler()console.setLevel(logging.ERROR)#增加指定的Handlerlogger.addHandler(file)logger.addHandler(console)#formatter决定日志记录的最终输出格式。formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')file.setFormatter(formatter)console.setFormatter(formatter)#logger.info("Start print log")logger.error("account [1234] too many login attempts")#logger.warning("Something maybe fail.")#logger.info("Finish") #--------------------------------------------------- 实例:
#---------------------atm_user------------------------- logger_user = logging.getLogger('atm_user') # logger.setLevel()指定日志最低级别 logger_user.setLevel(level = logging.DEBUG) #FileHandler()输出至文件 handler_user = logging.FileHandler(settings.atm_user_path,encoding='utf-8') #指定被处理的信息最低级别 Handler.setLevel() handler_user.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s--%(name)s--%(levelname)s--%(message)s') handler_user.setFormatter(formatter) logger_user.addHandler(handler_user) 引用文件:
logger.logger_user.debug(f"查看{account}信息 ")
3、json、pickle、shelve三个区别是什么?
首先,这三个模块都是序列化工具。 1. json是所有语言的序列化工具,优点跨语言、体积小.只能序列化一些基本的数据类型。int\str\list\tuple\dict pickle是python语言特有序列化工具,所有数据都能序列化。只能在python中使用,存储数据占空间大. shelve模块是一个简单的k,v(健值对)将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。 2. 使用方式,json和pickle用法一样,shelve是f =shelve.open('shelve_test') #-------------------------------------------------------------------------------------------------
Python中两种序列化json和pickle区别 序列化是把内存的数据类型转变为字符串(bytes类型)。 json:用于字符串和Python数据类型之间进行转换 pickle:用于Python特有类型(仅Python认识)和Python数据类型间进行转换。 shelve:将内存数据通过文件持久化,支持任何pickle支持的数据格式。
4、json的作用是什么?
功能:序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes(二进制)json,用于字符串和python数据类型间进行转换pickle,用于python特有的类型和python的数据类型间进行转换
5、subprocess
即允许你去创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等。 注意:使用这个模块之前要先引入该模块。我们经常需要通过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程之外的,每执行一条命令,就是发起一个新进程,通过python调用系统命令或脚本的模块在python2有os.system,除了os.system可以调用系统命令,,commands,popen2等也可以,比较乱,于是官方推出了subprocess,目地是提供统一的模块来实现对系统命令或脚本的调用三种执行命令的方法subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) #官方推荐subprocess.call(*popenargs, timeout=None, **kwargs) #跟上面实现的内容差不多,另一种写法subprocess.Popen() #上面各种方法的底层封装整个概念不理解!!!
6、为什么要设计好目录结构?
1.可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。2.可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。
7、打印出命令行的第一个参数。例如:
python argument.py luffy打印出 luffy在脚本里面写入:from sys import argvscript,name = argvprint(name)在命令行里输入:先进入脚本所在目录D:\> python argument.py luffy输出 luffy
8、os/sys模块
在当前目录下的D:/Pycharm/demo/LuFei/第二模块/第二章/练习题/argument.py 文件名:/argument.py
'''import os# 获取路径名:os.path.dirname()# 获得绝对路径: os.path.abspath()BASE_DIR = os.path.abspath('argument.py') #文件的绝对路径BASE_DIR2 = os.path.dirname(os.path.abspath('argument.py'))BASE_DIR3 = os.path.dirname(os.path.dirname(os.path.abspath('argument.py')))BASE_DIR4 = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath('argument.py'))))print(BASE_DIR)print(BASE_DIR2)print(BASE_DIR3)print(BASE_DIR4)打印内容:D:\Pycharm\demo\LuFei\第二模块\第二章\练习题\argument.pyD:\Pycharm\demo\LuFei\第二模块\第二章\练习题D:\Pycharm\demo\LuFei\第二模块\第二章D:\Pycharm\demo\LuFei\第二模块打印的内容是什么?os.path.dirname和os.path.abspath含义是什么?
9、通过configparser模块完成以下功能:
文件名my.cnf.ini[DEFAULT][client]port = 3306socket = /data/mysql_3306/mysql.sock[mysqld]explicit_defaults_for_timestamp = trueport = 3306socket = /data/mysql_3306/mysql.sockback_log = 80basedir = /usr/local/mysqltmpdir = /tmpdatadir = /data/mysql_3306default-time-zone = '+8:00'-----------------------------------------import configparserconfig =configparser.ConfigParser() #初始化实例config.read('my.cnf.ini')#读取配置文件print(config.sections())#读取模块名到列表中,也就是[]中的内容print(config.default_section)>['client', 'mysqld']# 修改时区 default-time-zone = '+8:00' 为 校准的全球时间 +00:00config['mysqld']['default-time-zone'] = '+00:00'config.write(open('my.cnf.ini','w'))# 删除 explicit_defaults_for_timestamp = trueconfig.remove_option('mysqld','explicit_defaults_for_timestamp = true')config.write(open('my.cnf.ini','w'))# 为DEFAULT增加一条 character-set-server = utf8config['DEFAULT']['character-set-server'] = 'utf8'config.write(open('my.cnf.ini','w'))----------------------------------------------拓展:#读取指定sections内的所有keyprint('se_keys:',config.options('mysqld'))#获取指定sections的配置信息print(config.items('mysqld'))#在指定的sections中通过key找出value#通过getprint(config.get('mysqld','back_log '))
10、写一个6位随机验证码程序(使用random模块),要求验证码中至少包含一个数字、一个小写字母、一个大写字母.
def choice(): global ran1,ran2,ran3 ran1 = random.randint(0,9) # randint()头尾都包括 ran2 = chr(random.randint(65,90))# 大写 ran3 = chr(random.randint(97,122))# 小写def random_num(): global code code = '' for i in range(3):#生成为3位数的验证码 choice() add = random.choice([ran1,ran2,ran3]) code = ''.join([code,str(add)]) return codeimport randomchoice()code2 =''.join([str(ran1),str(ran2),str(ran3)])random_num()print(''.join([code2,code])) 拓展:数字,英文字母,标点符号
print(''.join(random.sample(string.digits+string.punctuation+string.ascii_letters,6)))
--------------------------------------------------------------- #使用 string模块 # 在大、小写、数字中随机返回6位数 import string,random s = ''.join(random.sample(string.ascii_letters + string.digits, 3)) ran1 = random.randint(0,9) # randint()头尾都包括 ran2 = chr(random.randint(65,90))# 大写 ran3 = chr(random.randint(97,122))# 小写 code =''.join([str(ran1),str(ran2),str(ran3)]) print(''.join([code,s]))
11、利用正则表达式提取到 luffycity.com ,内容如下
luffycity.com import ref = open('index.html','r',encoding='utf-8')data = f.read()print(re.findall('luffycity.com',data))
12、写一个用户登录验证程序
,文件如下 1234.json{ "expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"} 用户名为json文件名,密码为 password。判断是否过期,与expire_date进行对比。登陆成功后,打印“登陆成功”,三次登陆失败,status值改为1,并且锁定账号。import json,time,datetimeusername = '1234.json'#首次登入将数据写入文件# data = {"expire_date": "2020-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}# with open('1234.json','r+',encoding='utf-8') as f:# file = json.dump(data,f)with open('1234.json', 'r+', encoding='utf-8') as f2: file2 = json.load(f2)print('请登录用户名、密码进行验证:')count = 3while count > 0: user_name = input('name:>').strip() pass_word = input('password:>').strip() if file2['status'] == 1: print('该用户已锁定') exit() else: time_now = time.strftime('%Y-%m-%d') d1 = datetime.datetime.strptime(file2['expire_date'], '%Y-%m-%d') d2 = datetime.datetime.strptime(time_now, '%Y-%m-%d') if d1 > d2: if user_name == username: if pass_word == file2['password']: print('登录成功') exit() else: count -= 1 print(f"您还有{count}次机会输入") if count == 0: file2['status'] = 1 with open('1234.json', 'w', encoding='utf-8') as f3: json.dump(file2,f3) break else: print('用户名不存在:') continue else: print('已过期') break
13、把第12题三次验证的密码进行hashlib加密处理。
即:json文件保存为md5的值,然后用md5的值进行验证。import hashlibfile2 = { "expire_date": "2020-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}hash_pass = file2['password']m5 = hashlib.md5()pass_data= m5.update(b"hash_pass")#print(m5.digest(),type(m5.digest()))#print(m5.hexdigest())pass_word = input('>')pass_input = m5.update(b'pass_word')if pass_input == pass_data: print('nice')
14、请用程序实现该转账行为
14、最近luffy买了个tesla,通过转账的形式,并且支付了5%的手续费,tesla价格为75万。文件为json,
请用程序实现该转账行为
。 需求如下: . ├── account │ ├── luffy.json │ └── tesla.json └── bin └── start.py 当执行start.py时,出现交互窗口 ------- Luffy Bank --------- 1. 账户信息 2. 转账 选择1 账户信息 显示luffy的当前账户余额。 选择2 转账 直接扣掉75万和利息费用并且tesla账户增加75万 import json,os,sys #取出当前文件的目录dir, #当前文件父目录os.path.dirname(dir)
print(__file__)dir = os.path.abspath(__file__)dir2 = os.path.dirname(os.path.dirname(dir))# 取出json文件的绝对路径file_path1 = dir2 + "\\" + "account" + "\\" + "luffy.json"file_path2 = dir2 + "\\" + "account" + "\\" + "tesla.json"print("""------- Luffy Bank ---------1. 账户信息2. 转账""")while True: choice = input("""请选择如下序号:1. 账户信息2. 转账q.退出>""") # 此题前提在luffy 下存入100万 with open(file_path1, 'r', encoding='utf-8') as f: balance = json.load(f) if choice == '1': print(f'当前余额:{balance}万') continue if choice == '2': balance = balance - balance*0.05 - 75 tesla_balance = 75 print(f"购买tesla共花费{balance - balance*0.05 - 75},tesla账户增加{tesla_balance}") with open(file_path2,'w',encoding='utf-8') as f2: json.dump(tesla_balance,f2) with open(file_path1, 'w', encoding='utf-8') as f3: json.dump(balance, f3) continue elif choice == 'q': exit()
14.1、提现
提现:对上题增加一个需求:提现。 目录结构如下.├── account│ └── luffy.json├── bin│ └── start.py└── core└── withdraw.py当执行start.py时,出现交互窗口 ------- Luffy Bank --------- 1. 账户信息 2. 提现选择1 账户信息 显示luffy的当前账户余额和信用额度。选择2 提现 提现金额应小于等于信用额度,利息为5%,提现金额为用户自定义。import json,os,sys#取出当前文件的父目录,print(__file__)dir = os.path.abspath(__file__)dir2 = os.path.dirname(os.path.dirname(dir))# 取出json文件的绝对路径file_path1 = dir2 + "\\" + "account" + "\\" + "luffy.json"file_path2 = dir2 + "\\" + "account" + "\\" + "tesla.json"print("""------- Luffy Bank ---------1. 账户信息2. 提现""")data = { 'balance': 100, 'credit': 50}with open(file_path1, 'w', encoding='utf-8') as f: json.dump(data,f)while True: choice = input("""请选择如下序号:1. 账户信息2. 提现q.退出>""") # 此题前提在luffy 下存入data字典信息 #data = {'balance': 100, 'credit': 50} with open(file_path1, 'r', encoding='utf-8') as f: #json.dump(data,f) balance = json.load(f) if choice == '1': print(f"当前余额:{balance['balance']}万,信用额度:{balance['credit']}万") continue if choice == '2': withdraw_money = int(input('请输入提现金额:').strip()) if withdraw_money > balance['credit']: print(f"提现金额超过信用额度:{balance['credit']}万,请重新输入") else: balance['balance'] = balance['balance'] - withdraw_money - withdraw_money*0.05 print(f"剩下余额{ balance['balance']}") with open(file_path1, 'w', encoding='utf-8') as f2: json.dump(balance, f2) continue elif choice == 'q': exit()
14.2、加装饰器
加登装饰器import json,os,sys#取出当前文件的父目录,print(__file__)dir = os.path.abspath(__file__)dir2 = os.path.dirname(os.path.dirname(dir))# 取出json文件的绝对路径file_path1 = dir2 + "\\" + "account" + "\\" + "luffy.json"file_path2 = dir2 + "\\" + "account" + "\\" + "tesla.json"global withdraw,transferprint("""------- Luffy Bank ---------1. 账户信息2. 提现""")# data = {'balance': 100, 'credit': 50}# with open(file_path1, 'w', encoding='utf-8') as f:# json.dump(data,f)user_status = Falsedef login(fun): def inner(*args,**kwargs): user_name = 'xiao' pass_word = '123' global user_status if user_status == False: username = input('user:>').strip() password = input('password:>').strip() if username == user_name and pass_word == password: print('welcome login...') user_status = True else: print('wrong username or passerword') if user_status == True: return fun(*args,**kwargs) return inner@logindef transfer(): tesla_balance = 75 balance['balance'] = balance['balance'] - tesla_balance * 0.05 - 75 print(f"购买tesla共花费{tesla_balance * 0.05 + 75},tesla账户增加{tesla_balance}") with open(file_path2, 'w', encoding='utf-8') as f2: json.dump(tesla_balance, f2) with open(file_path1, 'w', encoding='utf-8') as f3: json.dump(balance, f3)@logindef withdraw(): withdraw_money = int(input('请输入提现金额:').strip()) if withdraw_money > balance['credit']: print(f"提现金额超过信用额度:{balance['credit']}万,请重新输入") else: balance['balance'] = balance['balance'] - withdraw_money - withdraw_money*0.05 print(f"剩下余额{ balance['balance']}") with open(file_path1, 'w', encoding='utf-8') as f2: json.dump(balance, f2)---------------------------------主函数-----------------------------------------while True: choice = input("""请选择如下序号:1. 账户信息2. 提现3.转账q.退出>""") # 此题前提在luffy 下存入data字典信息 # data = {'balance': 100, 'credit': 50} with open(file_path1, 'r', encoding='utf-8') as f: # json.dump(data,f) balance = json.load(f) if choice == '1': print(f"当前余额:{balance['balance']}万,信用额度:{balance['credit']}万") continue if choice == '2': withdraw() continue if choice == '3': transfer() continue elif choice == 'q': exit()
14.3、加日志功能
加日志功能对第15题的用户转账、登录、提现操作均通过logging模块记录日志,日志文件位置如下.├── account│ └── luffy.json├── bin│ └── start.py└── core| └── withdraw.py└── logs└── bank.logimport json,os,sys#取出当前文件的父目录,print(__file__)dir = os.path.abspath(__file__)dir2 = os.path.dirname(os.path.dirname(dir))# 取出json文件的绝对路径file_path1 = dir2 + "\\" + "account" + "\\" + "luffy.json"file_path2 = dir2 + "\\" + "account" + "\\" + "tesla.json"#bank.logs绝对路径file_path3 = os.path.dirname(dir)+"\\" + "bank.log"global withdraw,transfer#日志# 将日志同时输出到屏幕和日志文件import logging#logger提供了应用程序可以直接使用的接口;logger = logging.getLogger('wed')logger.setLevel(level = logging.INFO)#handler将(logger创建的)日志记录发送到合适的目的输出;# FileHandler()输出至屏幕handler = logging.FileHandler(file_path3)handler.setLevel(logging.INFO)#formatter决定日志记录的最终输出格式。formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')handler.setFormatter(formatter)# StreamHandler()输出至屏幕console = logging.StreamHandler()console.setLevel(logging.INFO)#增加指定的Handlerlogger.addHandler(handler)logger.addHandler(console)print("""------- Luffy Bank ---------1. 账户信息2. 提现""")# data = {'balance': 100, 'credit': 50}# with open(file_path1, 'w', encoding='utf-8') as f:# json.dump(data,f)user_status = Falsedef login(fun): def inner(*args,**kwargs): user_name = 'xiao' pass_word = '123' global user_status if user_status == False: username = input('user:>').strip() password = input('password:>').strip() if username == user_name and pass_word == password: logger.info('----登录-----') print('welcome login...') user_status = True else: print('wrong username or passerword') if user_status == True: return fun(*args,**kwargs) return inner@logindef transfer(): tesla_balance = 75 balance['balance'] = balance['balance'] - tesla_balance * 0.05 - 75 print(f"购买tesla共花费{tesla_balance * 0.05 + 75},tesla账户增加{tesla_balance}") with open(file_path2, 'w', encoding='utf-8') as f2: json.dump(tesla_balance, f2) with open(file_path1, 'w', encoding='utf-8') as f3: json.dump(balance, f3)@logindef withdraw(): withdraw_money = int(input('请输入提现金额:').strip()) if withdraw_money > balance['credit']: print(f"提现金额超过信用额度:{balance['credit']}万,请重新输入") else: balance['balance'] = balance['balance'] - withdraw_money - withdraw_money*0.05 print(f"剩下余额{ balance['balance']}") with open(file_path1, 'w', encoding='utf-8') as f2: json.dump(balance, f2)while True: choice = input("""请选择如下序号:1. 账户信息2. 提现3.转账q.退出>""") # 此题前提在luffy 下存入data字典信息 # data = {'balance': 100, 'credit': 50} with open(file_path1, 'r', encoding='utf-8') as f: # json.dump(data,f) balance = json.load(f) if choice == '1': logger.info('----显示账户信息-----') print(f"当前余额:{balance['balance']}万,信用额度:{balance['credit']}万") continue if choice == '2': logger.info('----提现-----') print() withdraw() continue if choice == '3': logger.info('----转账-----') transfer() continue elif choice == 'q': exit()