1、logging模块有几个日志级别?
# answer
# logging模块共5个级别,它们分别是:
# DEBUG INFO WARNING ERROR CRITICAL
2、请配置logging模块,使其在屏幕和文件里同时打印以下格式的日志
2017-10-18 15:56:26,613 - access - ERROR - account [1234] too many login attempts
import logging ch = logging.StreamHandler() fh = logging.FileHandler("access.log") formatter = logging.Formatter('%(asctime)s,- %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) fh.setFormatter(formatter) logger = logging.getLogger("access") logger.setLevel(logging.ERROR) logger.addHandler(fh) logger.addHandler(ch) logger.error("account [1234] too many login attempts")
- 3、json、pickle、shelve三个区别是什么?
# json跨语言,但适用范围小,仅限于简单的数据结构。
# pickle支持python,适用所有的python数据类型。
# shelve是可以多次dump、load
# answer
# 首先,这三个模块都是序列化工具。
# 1. json是所有语言的序列化工具,优点跨语言、体积小.只能序列化一些基本的数据类型。int\str\list\tuple\dict
# pickle是python语言特有序列化工具,所有数据都能序列化。只能在python中使用,存储数据占空间大.
# shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。
# 2. 使用方式,json和pickle用法一样,shelve是f = shelve.open('shelve_test')
4、json的作用是什么?
# 将内容数据转成字符串
# answer
# 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes
5、subprocess执行命令方法有几种?
# 对系统命令或脚本的实现。run,call,popen
# answer:
# 有三种方法,分别是
# run()方法
# call()方法
# Popen()方法
6、为什么要设计好目录结构?
#可读性高,可维护性高
# answer
# 1.可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,
# 测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
# 2.可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。
# 这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。
7、打印出命令行的第一个参数。例如:python argument.py luffy 打印出 luffy
import sys
print(sys.argv[1])
8、代码如下:
''' Linux当前目录/usr/local/nginx/html/ 文件名:index.html '''
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(index.html)))
print(BASE_DIR)
打印的内容是什么?
# answer
# /usr/local/nginx
9、os.path.dirname和os.path.abspath含义是什么?
# answer
# os.path.dirname:指定文件的目录
# os.path.abspath:指定文件的绝对路径
10、通过configparser模块完成以下功能
文件名my.cnf
[DEFAULT]
[client]
port = 3306
socket = /data/mysql_3306/mysql.sock
[mysqld]
explicit_defaults_for_timestamp = true
port = 3306
socket = /data/mysql_3306/mysql.sock
back_log = 80
basedir = /usr/local/mysql
tmpdir = /tmp
datadir = /data/mysql_3306
default-time-zone = '+8:00'
修改时区 default-time-zone = '+8:00' 为 校准的全球时间 +00:00
删除 explicit_defaults_for_timestamp = true
为DEFAULT增加一条 character-set-server = utf8
# import configparser # config = configparser.ConfigParser() # config["DEFAULT"]={} # config["client"]={} # config["client"]["port"]="3306" # config["client"]["soket"]="/data/mysql_3306/mysql.sock" # config["mysqld"] = {} # config["mysqld"]["explicit_defaults_for_timestamp"]="true" # config["mysqld"]["port"]="3306" # config["mysqld"]["socket"]="/data/mysql_3306/mysql.sock" # config["mysqld"]["back_log"]="80" # config["mysqld"]["basedir"]="/usr/local/mysql" # config["mysqld"]["tmpdir"]="/tmp" # config["mysqld"]["datadir"]="/data/mysql_3306" # config["mysqld"]["default-time-zone"]="'+8:00'" # with open("my.cnf","w")as configfile: # config.write(configfile) # # con = configparser.ConfigParser() # con.read("my.cnf") # con.set("mysqld","default-time-zone","+00:00") # con.remove_option("mysqld","explicit_defaults_for_timestamp") # con["DEFAULT"]["character-set-server"]="utf8" # con.write(open("my.cnf","w"))
# answer修改 # import configparser # config = configparser.ConfigParser() # config.read('my.cnf') # config.set('mysqld','default-time-zone','+00:00') # config.write(open('my.cnf', "w")) # print(config['mysqld']['default-time-zone'] ) # answer 删除 # import configparser # config = configparser.ConfigParser() # config.read('my.cnf') # config.remove_option('mysqld','explicit_defaults_for_timestamp') # config.write(open('my.cnf', "w")) # answer 添加 # import configparser # config = configparser.ConfigParser() # config.read('my.cnf') # config.set('DEFAULT','character-set-server','utf8') # config.write(open('my.cnf', "w"))
11、写一个6位随机验证码程序(使用random模块),要求验证码中至少包含一个数字、一个小写字母、一个大写字母.
# import random,string # msg = random.sample(string.ascii_letters+string.digits,6) # msg = ''.join(msg) # print(msg) # import random # import string # code_li = [] # code_li.append(random.choice(string.ascii_lowercase)) # code_li.append(random.choice(string.digits)) # code_li.append(random.choice(string.ascii_uppercase)) # while len(code_li) < 6: # code_li.append(random.choice(string.digits+string.ascii_lowercase+string.ascii_uppercase)) # q_code=''.join(code_li) # print(q_code)
12、利用正则表达式提取到 luffycity.com ,内容如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>luffycity.com</title> </head> <body> </body> </html>
# name = ET.SubElement(new_xml,"html lang") # name.text = '"en"' # head = ET.SubElement(new_xml,"head") # meta = ET.SubElement(head,"meta charset") # meta.text = '"UTF-8"' # title = ET.SubElement(head,"title") # title.text = "luffycity.com" # body = ET.SubElement(new_xml,"body") # et = ET.ElementTree(new_xml) # et.write("c",encoding="utf-8") # ET.dump(new_xml) # import re # f = open('text.xml','r',encoding='utf-8') # data = f.read() # print(re.search('luffycity.com',data).group()) # answer # import re # f = open('index.html','r',encoding='utf-8') # data = f.read() # print(re.findall('luffycity.com',data))
13、写一个用户登录验证程序,文件如下
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,os # data = {"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"} # with open("1234.json","w")as fp: # json.dump(data,fp) # fp = open("1234.json","r") # data = json.load(fp) # count = 0 # while count < ATM与购物商城: # name = input("username:") # passwd = input("possword:") # n = "1234.json".split(".") # if name == n[0] and passwd == data["password"]: # if data["status"] == 1: # print("Locked!") # exit() # else: # t= time.strftime('%Y-%m-%d',time.localtime()) # if t <= data["expire_date"]: # print("Welcome...") # exit() # else: # print("过期") # exit() # else: # count += 1 # print("wrong") # # else: # print("Fail") # data["status"] = 1 # with open("1234.json", "w")as fp: # json.dump(data,fp)
14、把第13题三次验证的密码进行hashlib加密处理。即:json文件保存为md5的值,然后用md5的值进行验证。
# import json,time,os,hashlib # # data = {"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"} # # m = hashlib.md5() # # m.update(data["password"].encode("utf-8")) # # data["password"] = m.hexdigest() # # with open("1234.json","w")as fp: # # json.dump(data,fp) # # fp = open("1234.json","r") # data = json.load(fp) # count = 0 # while count < ATM与购物商城: # name = input("username:") # passwd = input("possword:") # m = hashlib.md5() # m.update(passwd.encode("utf-8")) # passwd = m.hexdigest() # n = "1234.json".split(".") # if name == n[0] and passwd == data["password"]: # if data["status"] == 1: # print("Locked!") # exit() # else: # t= time.strftime('%Y-%m-%d',time.localtime()) # if t <= data["expire_date"]: # print("Welcome...") # exit() # else: # print("过期") # exit() # else: # count += 1 # print("wrong") # # else: # print("Fail") # data["status"] = 1 # with open("1234.json", "w")as fp: # json.dump(data,fp)
15、最近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 os,sys,json # from bin.start import deal # deal() account ->_init__: import json data = {"账户余额":"800000","信用额度":"1000000"} with open("luffy.json","w")as f: json.dump(data,f) with open("luffy.json","r")as f2: d = json.load(f2) print(d) bin -> start.py import os,json from core.withdraw import withdraw1 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) base_dir = os.path.join(base_dir, "account") luffy_path = os.path.join(base_dir, "luffy.json") tsela_path = os.path.join(base_dir, "tsela.json") flag = False name, passwd = "alex", "123" def confirm(func): def conf(*args, **kwargs): global flag if not flag: username = input("name:") password = input("password:") if name == username and passwd == password: print("Welcome") flag = True else: print("Fail") else: print("login in ") if flag: func() return conf @confirm def trans(): price = 750000 other = 0.05 * price price1 = price + other tesla_data = json.load(open(tsela_path, "r", encoding="utf_8")) num = int(tesla_data["账户余额"]) luffy_data = json.load(open(luffy_path, "r", encoding="utf_8")) cost = int(luffy_data["账户余额"]) - price1 num = num + price tesla_data["账户余额"] = num luffy_data["账户余额"] = cost json.dump(tesla_data, open(tsela_path, "w", encoding="utf_8")) json.dump(luffy_data, open(luffy_path, "w", encoding="utf_8")) print("done") def deal(): info = """ ------- Luffy Bank --------- 1. 账户信息 2. 转账 ATM与购物商城. 提现 """ print(info) choice = input("choice num:>") if choice == "1": f1 = open(luffy_path, "r", encoding="utf-8") luffy_data = json.load(f1) for i in luffy_data: print(i, luffy_data[i]) elif choice == "2": trans() elif choice == "ATM与购物商城": withdraw1()
16、对上题增加一个需求:提现。
目录结构如下
. ├── account │ └── luffy.json ├── bin │ └── start.py └── core └── withdraw.py
当执行start.py时,出现交互窗口
------- Luffy Bank --------- 1. 账户信息 2. 提现
选择1 账户信息 显示luffy的当前账户余额和信用额度。
选择2 提现 提现金额应小于等于信用额度,利息为5%,提现金额为用户自定义。
尝试把上一章的验证用户登陆的装饰器添加到提现和转账的功能上。
17、对第15题的用户转账、登录、提现操作均通过logging模块记录日志,日志文件位置如下
. ├── account │ └── luffy.json ├── bin │ └── start.py └── core | └── withdraw.py └── logs └── bank.log