一、模块说明
模块加载顺序:内置模块 --> 内存 --> 磁盘(sys.path)
模块导入忽略或者指定只能导入说明
xiecheng
_name = 'ckl'_age = '21'hoppy = 'eat'
test
from xiecheng import *print(hoppy)print(name)print(age)
导入使用*时候,_name和_age不会被加载
xiecheng
__all__ = ['name','age']name = 'ckl'age = '21'hoppy = 'eat'
test
from xiecheng import *print(name)print(age)print(hoppy)
执行:
在使用*导入时候指定__all__,只导入这个列表的里面的内容
python文件使用场景
1.文件当做脚本运行__name__等于__main__
2.文件当做模块加载运行时__name__等于模块名
二、关于包说明
包内的文件供调用使用,不要直接执行
包导入示例
1.目录结构
2.模块内容
m1.py
def func1(): print('-----> from func1')
m2.py
def func2(): print('-----> from func2')
m3.py
def func3(): print("----> from func3")
3.运行run
3.1.调用m3
import m3m3.func3()
运行结果:
3.2.调用m1导入spring
import m3import springsm3.func3()springs.m1.func1()
报错:
因为运行的是run,run找的是sys.path路径里面的m1,当前路径没有m1,spring路径的__init__.py,在文件里面没有导入m1
from springs import m1
再次运行程序:
3.3.调用m2同理
在summer的__init__.py导入m2
from summer import m2
调用:
import m3import springsimport summerm3.func3()springs.m1.func1()summer.m2.func2()
运行结果:
进一步思考,如果springs里面再有一个包呢,结构如下:
m4内容:
def func4(): print('-----> i am f4')
如果run想调用m4
import m3import springsimport summerm3.func3()springs.m1.func1()summer.m2.func2()springs.winter.m4.func4()
报错:
同样需要在spings的__init__.py导入m4
from springs import m1from springs.winter import m4
运行结果:
包的导入,点的左边必须是包
包的绝对导入与相对导入
示例如下:
run想运行所有函数:
import glimpseglimpse.get()glimpse.create_a()glimpse.main()glimpse.register()
运行如下:
无法找到模块,需要在__init__.py导入模块
添加如下:
from glimpse.api.policy import getfrom glimpse.api.version import create_afrom glimpse.cmd.manage import mainfrom glimpse.db.models import register
运行结果:
问题来了,绝对导入要加入所有路径,如果glimpse名称改变,所有导入都要改变,那相对导入呢?
相对导入修改__init__.py:
from .api.policy import getfrom .api.version import create_afrom .cmd.manage import mainfrom .db.models import register
执行结果:
问题2,如果要在policy导入manage的模块呢?
policy 导入manage,相对导入
from ..cmd.manage import maindef get(): print("----> I AM GET") main()
manage:
def main(): print("---- I AM MAIN")
运行run
import glimpseglimpse.get()
结果:
架构简单说明
如果main想调用src的函数,怎么实现?
调用src必须获得src的路径,查看main获取大路径:
import sysprint(sys.path)
如下:
['/Users/kindle/PycharmProjects/SDM/bin', ...]
在mian的路径必须获取到上层目录如bin,conf...
1.获取到当前文件绝对路径
import sysimport osprint(os.path.abspath(__file__))
/Users/kindle/PycharmProjects/SDM/bin/main.py
2.获取到上级目录路径
import sysimport os
print(os.path.dirname(os.path.abspath(__file__)))
/Users/kindle/PycharmProjects/SDM/bin
3.再获取到上级路径
import sysimport osprint(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
/Users/kindle/PycharmProjects/SDM
4.通过获取的路径可以加入sys.path,之后导入任何子目录里面的模块
import sysimport osBASEPATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))sys.path.append(BASEPATH)from core import srcif __name__ == '__main__': src.souc()
冒泡排序
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 """ 4 冒泡排序 5 """ 6 NumList = [10,4,33,21,54,3,8,11,5,22,2,1,17,13,6] 7 8 def BubblingSort(args): 9 NumLength = NumList.__len__()10 EndNum = NumLength11 for j in range(1,EndNum):12 #循环获取索引值,范围不能超过长度13 for i in range(EndNum-j):14 #如果当前的索引所在的值,大于下一个索引所在的值,则进行替换15 if NumList[i] > NumList[i+1]:16 tmp = NumList[i+1]17 NumList[i+1] = NumList[i]18 NumList[i] = tmp19 print(NumList)20 21 BubblingSort(NumList)
模拟小程序
结构大概是这样的:
#tree
.
├── Backend│ ├── db│ │ ├── __init__.py│ │ └── SqlApi.py│ └── logic│ ├── handle.py│ └── __init__.py├── Config│ ├── __init__.py│ └── settings.py└── Frontend ├── __init__.py └── UserMain.pySqlApi.py:
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 from day05.CklDj.Config import settings 4 def db_auth(configs): 5 if configs.DATABASE["user"] == 'root' and configs.DATABASE["password"] == "123": 6 print("db auth passed") 7 return True 8 else: 9 print("db login error....")10 11 def Select(table,colume):12 if db_auth(settings):13 if table == 'user':14 user_info = {15 "001":['ckl',23,'engineer'],16 "002":['zld',21,'Manager'],17 "007":['xxx',28,'chef']18 }19 return user_info
handle.py
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 4 from day05.CklDj.Backend.db.SqlApi import Select 5 6 def Home(): 7 print("welcome to home page!") 8 Qdata = Select("user",'wukaka') 9 print("query ress:",Qdata)10 11 def Movie():12 print("welcome to movie page!")13 14 def Tv():15 print("welcome to Tv page!")
settings.py
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 4 DATABASE = { 5 "engine":"mysql", 6 "host":"localhost", 7 "port":3306, 8 "user":"root", 9 "password":"123"10 }
UserMain.py
#!/usr/bin/env python#-*- coding:utf-8 -*-import sysfrom day05.CklDj.Backend.logic import handlehandle.Home()
执行UserMain.py结果:
welcome to home page!db auth passedquery ress: { '001': ['ckl', 23, 'engineer'], '002': ['zld', 21, 'Manager'], '007': ['xxx', 28, 'chef']}
关于信用卡购物、取现的示例小程序
目录结构如下:
.
├── ATM│ ├── __init__.py│ └── UseAtm.py├── card.log├── Conf│ ├── __init__.py│ └── Settings.py├── Credit│ ├── CreditCard.py│ └── __init__.py├── CreditAtmMain.py├── Demand├── lock_file├── Market│ ├── __init__.py│ └── UseMarket.py└── pass_file
ATM/UseAtm.py
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 import sys 4 import pickle 5 import re 6 import time 7 8 #导入信用卡模块,调用登录方法 9 from day05.hw05.Credit import CreditCard 10 11 AllCardDict = CreditCard.PayInterface() 12 CardDisct = CreditCard.Login() 13 CardNum = CardDisct[0] 14 15 def TakeCash(): 16 try: 17 #提取账户总额和消费总额 18 AllMoney = CardDisct[2][CardDisct[0]][CardDisct[1]]['GeneralAccount'] 19 Consumption = CardDisct[2][CardDisct[0]][CardDisct[1]]['SpendMoney'] 20 print("You left %s RMB,You can take %s RMB" %(AllMoney,AllMoney)) 21 22 ConTakeMony = True 23 while ConTakeMony: 24 #如果账户余额大于100块,则执行 25 if int(AllMoney) >= 100: 26 TakeMoney = input("Please input you want take money: ") 27 MatchNum = re.findall("\D",TakeMoney) 28 #如果非数字,则重新输入 29 if MatchNum: 30 print("You must only enter a number !") 31 continue 32 #如果不是100的整数,则重新输入 33 elif int(TakeMoney) % 100 != 0: 34 print("You must take an integer of 100 try again...") 35 continue 36 #如果取款的金额大于2000,则重新输入 37 elif int(TakeMoney) > 2000: 38 print("you take must less than 2000,try again...") 39 continue 40 #取款的金额不能大于余额 41 elif int(TakeMoney) > int(AllMoney): 42 print("You can take all of moeny is %s ,try again" %AllMoney) 43 continue 44 else: 45 #余额等于减去取款的金额,消费等于加上取款的金额 46 AllMoney = int(AllMoney) - int(TakeMoney) 47 Consumption += int(TakeMoney) 48 OperateContext = "提取现金" 49 NowTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) 50 LogFile = open('D:\s12\day05\hw05\card.log', 'a') 51 LogFile.write("\n%s\t%s\t-%s\t%s" %(CardNum,OperateContext,TakeMoney,NowTime)) 52 LogFile.close() 53 54 #循环是否退出 55 while True: 56 Answer = input("Do you wanna continue to take cash ? (y|n)") 57 if Answer == "y": 58 break 59 elif Answer == "n": 60 print("You will exit and take away your card !") 61 ConTakeMony = False 62 break 63 else: 64 print("You must choose y or n !") 65 else: 66 print("Sorry,Insufficient account balance!") 67 break 68 #定义卡片自动的总额,消费的金额 69 CardDisct[2][CardDisct[0]][CardDisct[1]]['GeneralAccount'] = AllMoney 70 CardDisct[2][CardDisct[0]][CardDisct[1]]['SpendMoney'] = Consumption 71 #将所有结果通过pickle存储到文件里 72 pickleFile = open('D:\s12\day05\hw05\pass_file', 'wb') 73 pickle.dump(CardDisct[2], pickleFile) 74 pickleFile.close() 75 except: 76 pass 77 78 79 def RepayMent(): 80 try: 81 # 提取账户总额和消费总额 82 ReAllMoney = CardDisct[2][CardDisct[0]][CardDisct[1]]['GeneralAccount'] 83 ReConsumption = CardDisct[2][CardDisct[0]][CardDisct[1]]['SpendMoney'] 84 print("You spend %s RMB,You can Repay %s RMB" % (ReConsumption, ReConsumption)) 85 ConRepayMony = True 86 while ConRepayMony: 87 #如果账单金额大于0,说明要还 88 if ReConsumption > 0: 89 RepayMoney = input("Please input you want repay money: ") 90 ReMatchNum = re.findall("\D", RepayMoney) 91 #如果不是数字,需要重新输入 92 if ReMatchNum: 93 print("You must only enter a number !") 94 continue 95 #如果不能整除100,则需要重新输入 96 elif int(RepayMoney) % 100 != 0: 97 print("You must repay an integer of 100, try agin...") 98 continue 99 #偿还的钱不能大于账单的金额100 elif int(RepayMoney) > int(ReConsumption):101 print("you repay must less than %s " %ReConsumption)102 else:103 #消费账户等于消费金额减去偿还金额,总余额等于加上偿还金额104 ReConsumption = int(ReConsumption) - int(RepayMoney)105 ReAllMoney += int(RepayMoney)106 ReContext = "还款"107 NowTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))108 LogFile = open('D:\s12\day05\hw05\card.log', 'a')109 LogFile.write("\n%s\t%s\t+%s\t%s" % (CardNum, ReContext, RepayMoney,NowTime))110 LogFile.close()111 #循环提示继续输入112 while True:113 if int(ReConsumption) > 0:114 Answer = input("Do you wanna continue to repay cash ? (y|n)")115 if Answer == "y":116 break117 elif Answer == "n":118 print("You will exit and take away your card !")119 ConRepayMony = False120 break121 else:122 print("You must choose y or n !")123 else:124 print("You repay has been done.")125 ConRepayMony = False126 break127 else:128 print("You have no bill to repay!")129 break130 #定义总账户金额,定义消费金额131 CardDisct[2][CardDisct[0]][CardDisct[1]]['GeneralAccount'] = ReAllMoney132 CardDisct[2][CardDisct[0]][CardDisct[1]]['SpendMoney'] = ReConsumption133 #将结果存到文件里134 pickleFile = open('D:\s12\day05\hw05\pass_file', 'wb')135 pickle.dump(CardDisct[2], pickleFile)136 pickleFile.close()137 except:138 pass139 140 def TransPay():141 try:142 #获取当前登录用户账户信息143 TranLeft = CardDisct[2][CardDisct[0]][CardDisct[1]]['GeneralAccount']144 TranSpend = CardDisct[2][CardDisct[0]][CardDisct[1]]['SpendMoney']145 146 #输入需要转入的用户账户147 TransAccount = input("Please input your transfer Account: ")148 print("1")149 ConTrans = True150 print("2")151 while ConTrans:152 print("3")153 #如果账户存在154 print(AllCardDict.keys)155 if TransAccount in AllCardDict.keys():156 print("4")157 for t in AllCardDict[TransAccount].keys():158 TanKey = t159 print("5")160 # 获取接受转账的用户账户信息161 MorauLeft = AllCardDict[TransAccount][TanKey]['GeneralAccount']162 MorauSpend = AllCardDict[TransAccount][TanKey]['SpendMoney']163 TransMoney = input("Please input your wanna transfer money: ")164 if int(TransMoney) <= TranLeft:165 #转出账户总额减去转出金额166 TranLeft -= int(TransMoney)167 #转出账户花费加上转出金额168 TranSpend += int(TransMoney)169 #转入的账户总额加上接受的金额170 MorauLeft += int(TransMoney)171 TranContext = "转账"172 NowTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))173 LogFile = open('D:\s12\day05\hw05\card.log', 'a')174 LogFile.write("\n%s\t%s\t-%s\t%s" % (CardNum, TranContext, TransMoney,NowTime))175 LogFile.close()176 #循环继续输入177 while True:178 if TranLeft > 0:179 Answer = input("Do you wanna continue to trans money ? (y|n)")180 if Answer == "y":181 break182 elif Answer == "n":183 print("You will exit and take away your card !")184 ConTrans = False185 break186 else:187 print("You must choose y or n !")188 else:189 print("You hava no moeny to trans.")190 ConTrans = False191 break192 else:193 print("Sorry, you left money is only %s" % TranLeft)194 continue195 else:196 print("Sorry,you transfer account not found,try again")197 continue198 199 #账户余额变化200 AllCardDict[TransAccount][TanKey]['GeneralAccount'] = MorauLeft201 AllCardDict[CardDisct[0]][CardDisct[1]]['GeneralAccount'] = TranLeft202 AllCardDict[CardDisct[0]][CardDisct[1]]['SpendMoney'] = TranSpend203 #写入到文件204 pickleFile = open('D:\s12\day05\hw05\pass_file', 'wb')205 pickle.dump(AllCardDict, pickleFile)206 pickleFile.close()207 except:208 pass209 210 if "__name__" == "__main__":211 pass
Credit/CreditCard.py
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 import sys 4 import pickle 5 import time 6 7 #定义账户字典 8 CardAccount = { 9 '006195280':{ 10 '629893':{ 11 'GeneralAccount': 30000, 12 'SpendMoney':0, 13 } 14 }, 15 '004035208':{ 16 '889060':{ 17 'GeneralAccount': 20000, 18 'SpendMoney': 0, 19 } 20 } 21 } 22 23 #定义锁字典 24 LockAccount = { 25 '006195280':{ 26 'Lock':0 27 }, 28 '004035208':{ 29 'Lock':0 30 } 31 } 32 33 34 #pickle 将文件持久化到文件中,初始卡 35 def InitialCards(): 36 #CardAccount = {'006195280': '629893'} 37 pickleFile = open('D:\s12\day05\hw05\pass_file', 'wb') 38 pickle.dump(CardAccount, pickleFile) 39 pickleFile.close() 40 41 LockFile = open('D:\s12\day05\hw05\lock_file', 'wb') 42 pickle.dump(LockAccount, LockFile) 43 LockFile.close() 44 45 LogFile = open('D:\s12\day05\hw05\card.log', 'w') 46 LogFile.write("卡号\t交易内容\t金额\t日期") 47 LogFile.close() 48 49 50 #加载卡信息,从pickle文件中加载 51 def LoadCards(): 52 passFile = open('D:\s12\day05\hw05\pass_file', 'rb') 53 CardPassDict = pickle.load(passFile) 54 CardsList = CardPassDict.items() 55 passFile.close() 56 57 #登录模块 58 def Login(): 59 #加载卡信息 60 passFile = open('D:\s12\day05\hw05\pass_file', 'rb') 61 CardPassDict = pickle.load(passFile) 62 CardsList = CardPassDict.items() 63 passFile.close() 64 65 #加载锁字典信息 66 LockFile = open('D:\s12\day05\hw05\lock_file', 'rb') 67 LockDict = pickle.load(LockFile) 68 LockFile.close() 69 70 InputCardNum = input("Please input your card number: ") 71 #检查账户是否被锁定,如果提示KeyError恰好说明这个账户不存在 72 try: 73 isLocked = LockDict[InputCardNum]['Lock'] 74 if isLocked == 1: 75 print("Sorry,you have been locked") 76 return 4 77 except KeyError: 78 print("i can not find you !") 79 return 3 80 #循环三次机会输入密码 81 for i in range(3): 82 InputCardPass = input("Please input your card pass: ") 83 CardDictList = CardPassDict[InputCardNum].keys() 84 for c in CardDictList: 85 CardNum = c 86 if InputCardPass == CardNum: 87 print("Login....it will take a few minute!") 88 time.sleep(3) 89 print("Welcome Login Credit Card center !") 90 #返回卡号、卡密码、卡密码字典 91 return InputCardNum,InputCardPass,CardPassDict 92 else: 93 '''计算剩余机会''' 94 leaveTimes = 2 - i 95 if leaveTimes > 0: 96 print("sorry , you have %s chance!" % leaveTimes) 97 elif leaveTimes == 0: 98 print("hollyshit, you must be reject and be locked!") 99 '''如果三次机会用完,则在密码后加#,锁定用户'''100 LockDict[InputCardNum]['Lock'] = 1101 passFile = open('D:\s12\day05\hw05\lock_file', 'wb')102 pickle.dump(LockDict,passFile)103 passFile.close()104 105 106 def PayInterface():107 #加载信息108 passFile = open('D:\s12\day05\hw05\pass_file', 'rb')109 CardPassDict = pickle.load(passFile)110 #print(CardPassDict)111 passFile.close()112 113 LockFile = open('D:\s12\day05\hw05\lock_file', 'rb')114 LockDict = pickle.load(LockFile)115 #print(LockDict)116 LockFile.close()117 return CardPassDict118 119 def PrintLog():120 LogFile = open('D:\s12\day05\hw05\card.log','r')121 for i in LogFile.readlines():122 print(i)123 LogFile.close()124 125 126 if "__name__" == "__main__":127 pass
CreditAtmMain.py
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 4 #from day05.hw05.ATM import UseAtm 5 #UseAtm.TakeCash() 6 7 OperatDict = { 8 1:"ATM操作", 9 2:"购物",10 3:"查看账单"11 }12 13 AtmDict = {14 1:"取款",15 2:"还款",16 3:"转账"17 }18 19 def PrintList():20 print("操作列表:")21 print("="*30)22 for k,v in OperatDict.items():23 print(k,v)24 25 def PrintATM():26 print("ATM操作列表:")27 print("="*30)28 for i,j in AtmDict.items():29 print(i,j)30 31 32 PrintList()33 try:34 OperatorNum = input("Please input your opterator number: ")35 if OperatorNum == "1":36 print("")37 print("Now you will operator the ATM")38 print("-"*30)39 PrintATM()40 from day05.hw05.ATM import UseAtm41 AtmOptNum = input("Please input ATM number: ")42 if AtmOptNum == "1":43 UseAtm.TakeCash()44 elif AtmOptNum == "2":45 UseAtm.RepayMent()46 elif AtmOptNum == "3":47 UseAtm.TransPay()48 else:49 print("Sorry,you should enter a number in (1 or 2 or 3)")50 elif OperatorNum == "2":51 from day05.hw05.Market import UseMarket52 UseMarket.Shoping()53 elif OperatorNum == "3":54 from day05.hw05.Credit import CreditCard55 CreditCard.PrintLog()56 else:57 print("Sorry,you should enter a number in (1 or 2 or 3)")58 except:59 pass
Market/UseMarket.py
1 #!/usr/bin/env python 2 #-*- coding:utf-8 -*- 3 4 import sys 5 import pickle 6 import time 7 from day05.hw05.Credit import CreditCard 8 ShopCartDict = {} 9 Wallet = [0] 10 11 #定义商品字典包含编号、名称、价格 12 GoodsBuyDict = { 13 '1':{ 14 'ipad':3000 15 }, 16 '2':{ 17 'mac':21000 18 }, 19 '3':{ 20 'car':29000 21 }, 22 '4':{ 23 'bag':1800 24 }, 25 '5':{ 26 'tv':2800 27 }, 28 '6':{ 29 'dress':660 30 }, 31 '7':{ 32 'skirt':280 33 }, 34 '8':{ 35 'umbrella':75 36 } 37 } 38 39 #定义一个打印商品名称的方法 40 def PrintGoods(): 41 print("goods list".center(32, '=')) 42 for Gnum, Gdic in GoodsBuyDict.items(): 43 for Goods, Price in Gdic.items(): 44 print('%s No. is %-5s price is :\t%s' % (Gnum, Goods, Price)) 45 46 #定义一个打印购物车清单的方法 47 def PrintGcart(): 48 print("") 49 print("-" * 30) 50 for i,j in ShopCartDict.items(): 51 print("The %d number of %s prices is %d " %(j[1],i,j[0]*j[1])) 52 print("-"*30) 53 54 def Shoping(): 55 Gbool = True 56 while Gbool: 57 PrintGoods() 58 #循环输入需要购买的商品编号 59 InputNum = input("Please input you wanna buy goods Number: ") 60 61 #定义还能购买的商品列表,初始为空 62 CanBuyDict = {} 63 64 #定义一个方法来收集已经购买的商品并增加到CanBuyDict字典里 65 def CanBuyFunc(): 66 for GoodsPrice in GoodsBuyDict.values(): 67 for Gname, Gprice in GoodsPrice.items(): 68 CanBuyDict[Gname] = Gprice 69 70 #如果输入的序列号存在就开始操作 71 if InputNum in GoodsBuyDict.keys(): 72 for Gk,Gp in GoodsBuyDict[InputNum].items(): 73 #定义重复商品变量,初始为1 74 Overlapping = 1 75 #如果商品没在字典里,则直接添加 76 if Gk not in ShopCartDict: 77 ShopCartDict[Gk] = [Gp,Overlapping] 78 #否则,则修改商品数量值为当前值加1 79 else: 80 Overlapping += 1 81 ShopCartDict[Gk] = [Gp,Overlapping] 82 #钱包余额 83 Wallet[0] += Gp 84 else: 85 #输入的序号不在,则继续循环 86 print("Sorry,You must choose a number in the list !") 87 continue 88 #关于是否继续购买的循环 89 while True: 90 print("") 91 ContinueBuy = input("Do you want continue to by y or n: ") 92 if ContinueBuy == 'y': 93 break 94 elif ContinueBuy == 'n': 95 Gbool = False 96 break 97 else: 98 print("You Must choos y or n !") 99 try:100 #引入登录模块,接受返回值101 MarketPayTup = CreditCard.Login()102 #定义余额,消费金额103 AllMoney = MarketPayTup[2][MarketPayTup[0]][MarketPayTup[1]]['GeneralAccount']104 SpendMoney = MarketPayTup[2][MarketPayTup[0]][MarketPayTup[1]]['SpendMoney']105 CardNum = MarketPayTup[0]106 #如果消费金额小于余额107 if Wallet[0] <= AllMoney:108 PrintGcart()109 #余额等于减去消费金额110 AllMoney -= Wallet[0]111 #消费总额等于加上此次消费金额112 SpendMoney += Wallet[0]113 MarketPayTup[2][MarketPayTup[0]][MarketPayTup[1]]['GeneralAccount'] = AllMoney114 MarketPayTup[2][MarketPayTup[0]][MarketPayTup[1]]['SpendMoney'] = SpendMoney115 #将与额及消费的字典内容存储到文件中116 pickleFile = open('D:\s12\day05\hw05\pass_file', 'wb')117 pickle.dump(MarketPayTup[2], pickleFile)118 pickleFile.close()119 print(MarketPayTup)120 #记录购买日志121 NowTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))122 LogFile = open('D:\s12\day05\hw05\card.log', 'a')123 for GK2,GP2 in ShopCartDict.items():124 OperateContext = "购买%s" %GK2125 LogFile.write("\n%s\t%s\t-%s\t%s" % (CardNum, OperateContext, GP2[0], NowTime))126 LogFile.close()127 else:128 print("Sorry, you can not buy these goods,try to modify the shopping cart!")129 # 如果退出就打印购物车清单并设定循环值为False130 PrintGcart()131 #如果金额超出余额,则需要删除上哦132 ConDel = True133 while ConDel:134 DeleteGoods = input("Which goods do you wanna to delete: ")135 print(Wallet[0])136 #如果删除商品存在购物车字典里137 if DeleteGoods in ShopCartDict.keys():138 #如果商品数目等于1,则直接删除商品139 if ShopCartDict[DeleteGoods][1] == 1:140 ShopCartDict.pop(DeleteGoods)141 #金额减去商品的金额142 Wallet[0] -= ShopCartDict[DeleteGoods][0]143 #否则,对商品数目减去1144 else:145 ShopCartDict[DeleteGoods][1] -= 1146 # 金额减去商品的金额147 Wallet[0] -= ShopCartDict[DeleteGoods][0]148 #循环是否继续149 while True:150 print("")151 ContinueDel = input("Do you want continue to del y or n: ")152 if ContinueDel == 'y':153 break154 elif ContinueDel == 'n':155 ConDel = False156 break157 else:158 print("You Must choos y or n !")159 else:160 print("%s is not in shopcart,try again." %DeleteGoods)161 continue162 #打印购物车列表163 PrintGcart()164 #余额等于减去消费的金额165 AllMoney -= Wallet[0]166 #消费等于加上消费的金额167 SpendMoney += Wallet[0]168 MarketPayTup[2][MarketPayTup[0]][MarketPayTup[1]]['GeneralAccount'] = AllMoney169 MarketPayTup[2][MarketPayTup[0]][MarketPayTup[1]]['SpendMoney'] = SpendMoney170 #文件持久存储171 pickleFile = open('D:\s12\day05\hw05\pass_file', 'wb')172 pickle.dump(MarketPayTup[2], pickleFile)173 pickleFile.close()174 # 记录购买日志175 NowTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))176 LogFile = open('D:\s12\day05\hw05\card.log', 'a')177 for GK3, GP3 in ShopCartDict.items():178 OperateContext = "购买%s" % GK3179 LogFile.write("\n%s\t%s\t-%s\t%s" % (CardNum, OperateContext, GP3[0], NowTime))180 LogFile.close()181 except TypeError:182 pass183 184 if "__name__" == "__main__":185 pass
三、logging模块
3.1.日志级别:
CRITICAL = 50 #FATAL = CRITICALERROR = 40WARNING = 30 #WARN = WARNINGINFO = 20DEBUG = 10NOTSET = 0 #不设置
3.2.日志默认级别为warning,默认输出到终端
import logginglogging.debug('--> debug')logging.info('--> info')logging.warning('--> warning')logging.error('--> error')logging.critical('--> critical')
结果:
3.3.logging全局配置说明
可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。#格式%(name)s:Logger的名字,并非用户名,详细查看%(levelno)s:数字形式的日志级别%(levelname)s:文本形式的日志级别%(pathname)s:调用日志输出函数的模块的完整路径名,可能没有%(filename)s:调用日志输出函数的模块的文件名%(module)s:调用日志输出函数的模块名%(funcName)s:调用日志输出函数的函数名%(lineno)d:调用日志输出函数的语句所在的代码行%(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示%(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数%(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒%(thread)d:线程ID。可能没有%(threadName)s:线程名。可能没有%(process)d:进程ID。可能没有%(message)s:用户输出的消息
可在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。format:指定handler使用的日志显示格式。datefmt:指定日期时间格式。level:设置rootlogger(后边会讲解具体概念)的日志级别stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。format参数中可能用到的格式化串:%(name)s Logger的名字%(levelno)s 数字形式的日志级别%(levelname)s 文本形式的日志级别%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有%(filename)s 调用日志输出函数的模块的文件名%(module)s 调用日志输出函数的模块名%(funcName)s 调用日志输出函数的函数名%(lineno)d 调用日志输出函数的语句所在的代码行%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒%(thread)d 线程ID。可能没有%(threadName)s 线程名。可能没有%(process)d 进程ID。可能没有%(message)s用户输出的消息
定义全局配置指定打印到文件及格式
import logginglogging.basicConfig(filename='ckl.log', format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', level=10)logging.debug('--> debug')logging.info('--> info')logging.warning('--> warning')logging.error('--> error')logging.critical('--> critical')
结果生成ckl.log:
2018-12-01 10:50:54 AM - root - DEBUG - logname: --> debug2018-12-01 10:50:54 AM - root - INFO - logname: --> info2018-12-01 10:50:54 AM - root - WARNING - logname: --> warning2018-12-01 10:50:54 AM - root - ERROR - logname: --> error2018-12-01 10:50:54 AM - root - CRITICAL - logname: --> critical
3.4.打印日志到指定文件
import loggingformatter1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p') #定义日志格式f1=logging.FileHandler('t1.log') #打印内容到指定文件f2=logging.FileHandler('t2.log')f3=logging.FileHandler('t3.log')ch=logging.StreamHandler() #输出到终端f1.setFormatter(formatter1) #关联日志格式#f1.setFormatter(formatter2)f2.setFormatter(formatter1)f3.setFormatter(formatter1)ch.setFormatter(formatter1)logger1=logging.getLogger('CKL') #获得日志对象logger1.setLevel(10) #设置级别logger1.addHandler(f1)logger1.addHandler(f2)logger1.addHandler(f3)logger1.addHandler(ch)logger1.debug('----- THIS IS DEBUG')
终端及文件:
日志过滤级别说明
可以在Logger和handles定义日志级别
import loggingformatter1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p') #定义日志格式ch=logging.StreamHandler() #输出到终端ch.setFormatter(formatter1)ch.setLevel(20) #handler设置日志级别为INFOlogger1=logging.getLogger('CKL') #获得日志对象logger1.setLevel(10) #设置级别logger1.addHandler(ch)logger1.debug('----- THIS IS DEBUG')
日志将不会打印,因为handler的日志级别高于logger的级别,如果都设置为同级别可以打印。
总结:只有高于日志级别的日志才会被打印,logger和handler,都要允许通过才可以。
logging定义范例
"""logging配置"""import osimport logging.config# 定义三种日志输出格式 开始standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'# 定义日志输出格式 结束logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目录logfile_name = 'all2.log' # log文件名# 如果不存在定义的日志目录就创建一个if not os.path.isdir(logfile_dir): os.mkdir(logfile_dir)# log文件的全路径logfile_path = os.path.join(logfile_dir, logfile_name)# log配置字典LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, }, 'filters': {}, 'handlers': { #打印到终端的日志 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'simple' }, #打印到文件的日志,收集info及以上的日志 'default': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', 'filename': logfile_path, # 日志文件 'maxBytes': 1024*1024*5, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { #logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, },}def load_my_logging_cfg(): logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置 logger = logging.getLogger(__name__) # 生成一个log实例 logger.info('It works!') # 记录该文件的运行状态if __name__ == '__main__': load_my_logging_cfg()
调用日志配置文件:
import loggingimport logging_conflogging_conf.load_my_logging_cfg()
结果:
[2018-12-01 12:54:45,145][MainThread:140735208222720][task_id:logging_conf][logging_conf.py:75][INFO][It works!]