首先這邊有給準(zhǔn)備一些python資料、源碼、練習(xí)題、教程皆可點(diǎn)擊文章下方名片獲取此處跳轉(zhuǎn)
1.logging模塊有幾個日志級別?
#INFO,WARNING,DEBUG,CRITICAL,ERROR
2.請配置logging模塊,使其在屏幕和文件里同時打印以下格式的日志
2017-10-18 15:56:26,613 - access - ERROR - account [1234] too many login attempts
代碼;
import logging
from logging import handlers
logger = logging.getLogger('access')
logger.setLevel(logging.ERROR)
ch = logging.StreamHandler()
fh = handlers.TimedRotatingFileHandler(interval=1,when='D',filename='web.log', backupCount=10)
logger.addHandler(fh)
logger.addHandler(ch)
file_format = logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(file_format)
fh.setFormatter(file_format)
logger.error('account [1234] too many login attempts')
3.json、pickle、shelve三個區(qū)別是什么?
首先,這三個模塊都是序列化工具。
- json是所有語言的序列化工具,優(yōu)點(diǎn)跨語言、體積小.只能序列化一些基本的數(shù)據(jù)類型。int\str\list\tuple\dict pickle是python語言特有序列化工具,所有數(shù)據(jù)都能序列化。只能在python中使用,存儲數(shù)據(jù)占空間大.
shelve模塊是一個簡單的k,v將內(nèi)存數(shù)據(jù)通過文件持久化的模塊,可以持久化任何pickle可支持的python數(shù)據(jù)格式。
4.json的作用是什么?
序列化,把dict,tuple,list等內(nèi)存對象轉(zhuǎn)換為字符串,持久化數(shù)據(jù),存儲到硬盤中或網(wǎng)絡(luò)傳輸,因?yàn)榫W(wǎng)絡(luò)和硬盤只接受bytes
5.subprocess執(zhí)行命令方法有幾種?
run()方法
call()方法
Popen()方法
6.為什么要設(shè)計(jì)好目錄結(jié)構(gòu)?
- 可讀性高:
不熟悉這個項(xiàng)目的代碼的人,一眼就能看懂目錄結(jié)構(gòu),知道程序啟動腳本是哪個,測試目錄在哪兒,配置文件在哪兒等等。從而非??焖俚牧私膺@個項(xiàng)目。 - 可維護(hù)性高:
定義好組織規(guī)則后,維護(hù)者就能很明確地知道,新增的哪個文件和代碼應(yīng)該放在什么目錄之下。這個好處是,隨著時間的推移,代碼/配置的規(guī)模增加,項(xiàng)目結(jié)構(gòu)不會混亂,仍然能夠組織良好。
7.打印出命令行的第一個參數(shù)。例如:
python argument.py luffy
打印出 luffy
import sys
print(sys.argv[1])
8.代碼
'''
Linux當(dāng)前目錄/usr/local/nginx/html/
文件名:index.html
'''
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath('index.html')))
print(BASE_DIR)
打印
/usr/local/nginx/
9.os.path.dirname和os.path.abspath含義是什么?
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'
修改時區(qū) default-time-zone = ‘+8:00’ 為 校準(zhǔn)的全球時間 +00:00
刪除 explicit_defaults_for_timestamp = true
為DEFAULT增加一條 character-set-server = utf8
import configparser
import os
config = configparser.ConfigParser()
config.read('my.cnf')
new_file = 'my.cnf%s'%('new')
with open(new_file,'w') as new_f:
print(config.sections())
print(config)
# 為DEFAULT增加一條 character-set-server = utf8
config['DEFAULT']={'character-set-server':'utf8'}
# 修改時區(qū) default-time-zone = '+8:00' 為 校準(zhǔn)的全球時間 +00:00
config.set('mysqld','default-time-zone','+00:00')
# 刪除 explicit_defaults_for_timestamp = true
config.remove_option('mysqld','explicit_defaults_for_timestamp')
config.write(new_f)
os.remove('my.cnf')
os.rename(new_file,'my.cnf')
11.寫一個6位隨機(jī)驗(yàn)證碼程序(使用random模塊),要求驗(yàn)證碼中至少包含一個數(shù)字、一個小寫字母、一個大寫字母.
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))
print(code_li)
q_code=''.join(code_li)
print(q_code)
12.利用正則表達(dá)式提取到 luffycity.com ,內(nèi)容如下
s='''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>luffycity.com</title>
</head>
<body>
</body>
</html>
'''
import re
match_s = re.findall('<title>(.*?)</title>',s)
print(match_s[0])
13.寫一個用戶登錄驗(yàn)證程序,文件如下 1234.json
1234.json{"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
'''
寫一個用戶登錄驗(yàn)證程序,文件如下
1234.json
用戶名為json文件名,密碼為 password。
判斷是否過期,與expire_date進(jìn)行對比。
登陸成功后,打印“登陸成功”,三次登陸失敗,status值改為1,并且鎖定賬號。
'''
import json
import os
import time
import hashlib
count = 0
exit_flag =False
while count < 3:
user = input('輸入用戶名: ')
f = user.strip()+'.json'
if os.path.exists(f):
fp = open(f,'r+',encoding='utf-8')
j_user = json.load(fp)
if j_user["status"] == 1:
print('賬號已經(jīng)鎖定')
break
else:
expire_dt = j_user["expire_date"]
current_st = time.time()
expire_st = time.mktime(time.strptime(expire_dt,'%Y-%m-%d'))
# print(expire_st,current_st)
if current_st > expire_st:
print('用戶已經(jīng)過期')
break
else:
while count < 3:
pwd = input('輸入密碼: ')
if pwd.strip() == j_user["password"]:
print('用戶[%s]登錄成功'%user)
exit_flag = True
break
else:
print('密碼不對')
if count == 2:
print('用戶登錄已超過3次,鎖定賬號')
j_user["status"] = 1
fp.seek(0)
fp.truncate() # 清空文件內(nèi)容
json.dump(j_user,fp) # 寫入鎖定信息
count += 1
if exit_flag:
break
else:
print('用戶不存在')
count += 1
14. 把第13題三次驗(yàn)證的密碼進(jìn)行hashlib加密處理。即:json文件保存為md5的值,然后用md5的值進(jìn)行驗(yàn)證。
加密密碼
f ='1234.json'
fp = open(f,'r+',encoding='utf-8')
j_user = json.load(fp)
md = hashlib.md5()
md.update('abc'.encode('utf-8'))
md_pwd = md.hexdigest()
print(md_pwd)
j_user["password"] = md_pwd
fp.seek(0)
fp.truncate() # 清空文件內(nèi)容
json.dump(j_user,fp) # 寫入md5密碼信息
fp.close()
用戶登錄驗(yàn)證
count = 0
exit_flag = False
md = hashlib.md5()
while count < 3:
user = input(‘輸入用戶名: ‘)
f = user.strip()+’.json’
if os.path.exists(f):
fp = open(f,‘r+’,encoding=‘utf-8’)
j_user = json.load(fp)
if j_user[“status”] == 1:
print(‘賬號已經(jīng)鎖定’)
break
else:
expire_dt = j_user[“expire_date”]
current_st = time.time()
expire_st = time.mktime(time.strptime(expire_dt,'%Y-%m-%d'))
# print(expire_st,current_st)
if current_st > expire_st:
print('用戶已經(jīng)過期')
break
else:
while count < 3:
pwd = input('輸入密碼: ')
md.update(pwd.strip().encode('utf-8'))
md5_pwd = md.hexdigest()
if md5_pwd == j_user["password"]:
print('用戶[%s]登錄成功'%user)
exit_flag = True
break
else:
print('密碼不對')
if count == 2:
print('用戶登錄已超過3次,鎖定賬號')
j_user["status"] = 1
fp.seek(0)
fp.truncate() # 清空文件內(nèi)容
json.dump(j_user,fp) # 寫入鎖定信息
fp.close()
count += 1
if exit_flag:
break
else:
print('用戶不存在')
count += 1
15.
- 最近luffy買了個tesla,通過轉(zhuǎn)賬的形式,并且支付了5%的手續(xù)費(fèi),tesla價格為75萬。文件為json,請用程序?qū)崿F(xiàn)該轉(zhuǎn)賬行為。
需求如下: - 目錄結(jié)構(gòu)為
.
├── account
│ ├── luffy.json
│ └── tesla.json
└── bin
└── start.py
當(dāng)執(zhí)行start.py時,出現(xiàn)交互窗口
------- Luffy Bank ---------
1. 賬戶信息
2. 轉(zhuǎn)賬
-
選擇1 賬戶信息 顯示luffy的當(dāng)前賬戶余額。
-
選擇2 轉(zhuǎn)賬 直接扣掉75萬和利息費(fèi)用并且tesla賬戶增加75萬
-
對上題增加一個需求:提現(xiàn)。 目錄結(jié)構(gòu)如下
.
├── account
│ └── luffy.json
├── bin
│ └── start.py
└── core
└── withdraw.py
當(dāng)執(zhí)行start.py時,出現(xiàn)交互窗口
------- Luffy Bank ---------
1. 賬戶信息
2. 提現(xiàn)
- 選擇1 賬戶信息 顯示luffy的當(dāng)前賬戶余額和信用額度。
- 選擇2 提現(xiàn) 提現(xiàn)金額應(yīng)小于等于信用額度,利息為5%,提現(xiàn)金額為用戶自定義。
- 嘗試把上一章的驗(yàn)證用戶登陸的裝飾器添加到提現(xiàn)和轉(zhuǎn)賬的功能上。
- 對第15題的用戶轉(zhuǎn)賬、登錄、提現(xiàn)操作均通過logging模塊記錄日志,日志文件位置如下
.
├── account
│ └── luffy.json
├── bin
│ └── start.py
└── core
| └── withdraw.py
└── logs
└── bank.log
目錄結(jié)構(gòu)
代碼 settings.py
import os
'''
日志文件設(shè)置
'''
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOG_LEVEL='INFO'
LOG_FILE='bank.log'
'''
交易類型
'''
TRANS_TYPE={
'withdraw':{'interest':0.05,'action':'minus'},
'transfer': {'interest': 0.05, 'action': 'minus'}
}
print(BASE_DIR)
代碼 my_logset.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Time : 2018/4/23 8:55
# @Author : hyang
# @File : my_logset.py
# @Software: PyCharm
import logging
import os
from conf import settings
# 日志格式
log_format = '[%(asctime)s - %(levelname)s - %(name)s - %(filename)s - %(lineno)d ] %(message)s '
def get_mylogger(name):
"""
get log
:param name:
:return:
"""
logger = logging.getLogger(name)
logger.setLevel(settings.LOG_LEVEL)
console_handler = logging.StreamHandler()
# 文件絕對路徑
logfile_path = os.path.join(settings.BASE_DIR, 'log',settings.LOG_FILE)
file_handler = logging.FileHandler(logfile_path)
logger.addHandler(console_handler)
logger.addHandler(file_handler)
file_format = logging.Formatter(fmt=log_format)
console_format = logging.Formatter(fmt=log_format, datefmt='%Y-%m-%d %H:%M:%S ')
console_handler.setFormatter(console_format)
file_handler.setFormatter(file_format)
return logger
if __name__ == '__main__':
log = get_mylogger('access')
log.info('access')
log.error('Error')
log1 = get_mylogger('trans')
log1.info('trans')
代碼 auth.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/5/14 22:57
# @Author : hyang
# @Site :
# @File : auth.py
# @Software: PyCharm
import json
import time
import os
from conf import settings
from log import my_logset
from functools import wraps
# logger = my_logset.get_mylogger('access')
def login_required(func):
"""
登錄認(rèn)證裝飾器
:param func:
:return:
"""
@wraps(func)
def wrapper(*args,**kwargs):
# print(args[0].get('is_authenticated'))
if args[0].get('is_authenticated'):
print('execute %s'%func.__name__)
res = func(*args, **kwargs)
else:
exit('user is not authenticated')
return res
return wrapper
def acc_login(user, pwd,logger):
"""
用戶登錄
:param log_obj:
:return:
"""
# 賬號文件
account_file = os.path.join(settings.BASE_DIR,'account','%s.json'%user)
if os.path.isfile(account_file):
user_fp = open(account_file,'r',encoding='utf-8')
account_data = json.load(fp=user_fp)
if account_data["password"] == pwd:
exp_time_stamp = time.mktime(time.strptime(account_data["expire_date"],'%Y-%m-%d'))
status = account_data['status']
if time.time() > exp_time_stamp:
msg = 'Account [%s] has expired,please contact the back to get a new card!' % user
logger.error(msg)
elif status != 0:
msg = 'Account [%s] has frozen' % user
logger.error(msg)
else:
logger.info('***********歡迎{}登錄***********'.format(user))
return account_data
else:
logger.error("Account ID or password is incorrect!")
else:
msg = "Account [%s] does not exist!" % user
logger.error(msg)
def auth_acc(user_data,logger):
"""
用戶登錄
:return:
"""
retry_count = 0
if user_data['is_authenticated'] is not True:
while retry_count < 3:
user = input('input username: ').strip()
pwd = input('input password: ').strip()
acc_data = acc_login(user, pwd,logger)
if acc_data:
user_data['is_authenticated'] = True
return acc_data
retry_count +=1
else:
exit("account too many login attempts" )
if __name__ == '__main__':
logger = my_logset.get_mylogger('access')
user_data = {'is_authenticated':False}
auth_acc(user_data,logger)
代碼 main.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/5/14 23:55
# @Author : hyang
# @Site :
# @File : main.py
# @Software: PyCharm
import os
import json
from core import auth
from core.auth import login_required
from conf import settings
from log import my_logset
user_data = {
'user_id':None,
'is_authenticated':False,
'user':None
}
# transaction logger
trans_logger = my_logset.get_mylogger('transaction')
# access logger
access_logger = my_logset.get_mylogger('access')
@login_required
def account_info(user_data):
"""
print acoount_info
:param acc_data:
:return:
"""
curr_data = user_data['user']
current_user = '''
--------- USER INFO --------
user_id: {}
Credit : {}
Balance: {}
expire_date: {}
----------------------------------
'''.format(curr_data['id'], curr_data['credit'], curr_data['balance'],curr_data['expire_date'])
access_logger.info(current_user)
@login_required
def withdraw(user_data):
"""
print current balance and let user do the withdraw action
:param user_data:
:return:
"""
curr_data = user_data['user']
back_flag = False
while not back_flag:
withdraw_amount = input("Input withdraw amount:").strip()
if withdraw_amount.isdigit():
old_bal = curr_data['balance']
curr_data['balance'] = old_bal - float(withdraw_amount)*settings.TRANS_TYPE['withdraw']['interest']
if curr_data['balance']:
msg = "New Balance:%s" % (curr_data['balance'])
trans_logger.info(msg)
save_data(curr_data)
elif withdraw_amount == 'b':
back_flag = True
else:
msg = "[%s] is not a valid amount, only accept integer!" % withdraw_amount
trans_logger.error(msg)
@login_required
def transfer(user_data):
"""
print current balance and let user do the transfer action
:param user_data:
:return:
"""
curr_data = user_data['user']
back_flag = False
while not back_flag:
transfer_amount = input("Input transfer amount:").strip()
tesla_data = get_data('tesla') # 得到轉(zhuǎn)賬人的信息
if transfer_amount.isdigit():
transfer_amount = float(transfer_amount) # 轉(zhuǎn)賬金額轉(zhuǎn)化float
old_bal = curr_data['balance']
new_tesla_bal = tesla_data['balance'] + transfer_amount # 得到轉(zhuǎn)賬人的余額
curr_data['balance'] = old_bal - float(transfer_amount) * settings.TRANS_TYPE['withdraw']['interest']
tesla_data['balance'] = new_tesla_bal
if curr_data['balance']:
msg = "New Balance: %s new_tesla_bal: %s " % (curr_data['balance'], new_tesla_bal)
trans_logger.info(msg)
# 保存數(shù)據(jù)
save_data(curr_data)
save_data(tesla_data)
elif transfer_amount == 'b':
back_flag = True
else:
msg = "[%s] is not a valid amount, only accept integer!" % transfer_amount
trans_logger.error(msg)
def logout(user_data):
"""
user logout
:param acc_data:
:return:
"""
msg = "%s logout" % user_data['user_id']
user_data['is_authenticated']= False
def save_data(acc_data):
"""
保存acc_data
:param acc_data:
:return:
"""
file = os.path.join(settings.BASE_DIR,'account',acc_data['id']+'.json')
user_fp = open(file,'w',encoding='utf-8')
print('save_data: ',file, acc_data)
json.dump(acc_data,user_fp,ensure_ascii=False)
user_fp.close()
def get_data(user_id):
"""
得到acc_data
:param user_id:
:return:
"""
file = os.path.join(settings.BASE_DIR, 'account', user_id+'.json')
user_fp = open(file, 'r', encoding='utf-8')
acc_data = json.load(user_fp)
user_fp.close()
return acc_data
def interactive(acc_data):
'''
interact with user
:return:
'''
menu = """
------- Bank ---------
1. 賬戶信息(功能已實(shí)現(xiàn))
2. 取款(功能已實(shí)現(xiàn))
3. 轉(zhuǎn)賬(功能已實(shí)現(xiàn))
4. 用戶退出(功能已實(shí)現(xiàn))
"""
menu_dic = {
'1': account_info,
'2': withdraw,
'3': transfer,
'4': logout,
}
exit_flag = False
while not exit_flag:
print(menu)
user_option = input(">>:").strip()
if user_option in menu_dic:
# print('accdata', acc_data)
# print(menu_dic[user_option], acc_data)
menu_dic[user_option](acc_data)
else:
print("Option does not exist!", "error")
exit_flag = True
def run():
'''
this function will be called right a way when the program started, here handles the user interaction stuff
:return:
'''
acc_data = auth.auth_acc(user_data,access_logger)
# print(acc_data)
# 如果用戶認(rèn)證成功
if user_data['is_authenticated']:
user_data['user'] = acc_data
user_data['user_id'] = acc_data.get('id')
interactive(user_data)
if __name__ == '__main__':
run()
# print(a[0])
代碼 start.py
import sys,os
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR) # 加入環(huán)境變量
from core import main as m
if __name__ == '__main__':
m.run()
最后,給大家準(zhǔn)備的??????Python資料、源碼、整套學(xué)習(xí)路線圖、素材、解答、皆點(diǎn)擊下方獲取呀??????文章來源:http://www.zghlxwxcb.cn/news/detail-427457.html
本文所有模塊\環(huán)境\源碼\教程皆可點(diǎn)擊此處跳轉(zhuǎn)免費(fèi)領(lǐng)文章來源地址http://www.zghlxwxcb.cn/news/detail-427457.html
到了這里,關(guān)于Python模塊練習(xí)題-測試你的Python技能。的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!