注:这是一系列基于实验楼网络培训的python学习日记,内容零散,只是便于我自己回顾,有需要请了解www.shiyanlou.com。
8. 实验7:文件处理
文件的打开用open(filename, "w"),有四种模式:r(默认只读),w,a(追加模式),b。
程序执行结束后需要用close()关闭,否则占用内存,可能造成数据丢失。实际应用中使用with语句处理文件对象,在使用完文件后自动关闭:with open(“path”) as file:...
命令行写入文件时输入时注意 > 和 >> 的使用。
read()可能对因为文件太大不能读取,readline()可以逐行读取,readlines()读取所有行返回一个列表。
序列化:将内存中的对象转化为可以存储的格式,比如用文本文件保存一个python对象。python中通常用两种方式进行序列化:pickle 模块 和 json格式。
pickle:用“wb”,“rb”格式读写,pickle.dump和pickle.load存储/载入。
json:javascript object notation,一种轻量级数据交换格式,可以作为不同服务组件传输数据的格式,互联网应用提供的各种api接口返回值基本都是json格式。用“w”,“r”格式读写,通过json.dumps和json.loads序列化和反序列化。
os.path.各种函数(filename) 获取处理文件和文件夹属性。
9. 挑战3 挑战:工资计算器读写数据文件
设置文件 text.cfg:
JiShuL = 2193.00 JiShuH = 16446.00 YangLao = 0.08 YiLiao = 0.02 ShiYe = 0.005 GongShang = 0 ShengYu = 0 GongJiJin = 0.06
员工工号和工资 user.csv
101 3500 203 5000 309 15000
输入
python3 calculator.py -c .../test.cfg -d .../user.csv -o .../gongzi.csv
根据答案改进自己代码所得如下:
1 # -*- coding: utf-8 -*- 2 3 import sys 4 import csv 5 6 class Args(object): 7 8 def __init__(self, args): 9 self.args = args 10 def __parse_arg(self, arg): 11 try: 12 argStr = self.args[self.args.index(arg)+1] 13 except: 14 argStr = None 15 return argStr 16 def get_arg(self, arg): 17 argStr = self.__parse_arg(arg) 18 if argStr is None: 19 print("argument error") 20 return argStr 21 22 class Config(object): 23 24 def __init__(self, filename): 25 self.JL, self.JH, self.rateSs = self.__parse_config(filename) 26 def __parse_config(self, filename): 27 JL = 0 28 JH = 0 29 rateSs = 0 30 with open(filename) as f: 31 for line in f: 32 key, value = line.split("=") 33 key = key.strip() 34 try: 35 value = float(value.strip()) 36 except: 37 print ("config value error") 38 if key == "JiShuL": 39 JL = value 40 elif key == "JiShuH": 41 JH = value 42 else: 43 rateSs += value 44 45 return JL, JH, rateSs 46 47 class UserData(object): 48 49 def __init__(self, filename): 50 self.data = self._read_users_data(filename) 51 def _read_users_data(self, filename): 52 data = [] 53 with open(filename) as f: 54 for line in f: 55 empeeId, income = line.split(",") 56 try: 57 empeeInfo = (int(empeeId), int(income)) 58 except: 59 print("employee data error") 60 data.append(empeeInfo) 61 return data 62 def __iter__(self): # 这里需要特别注意,__iter__使实例可以像迭代器一样使用 63 return iter(self.data) 64 65 class IncomeTaxCalculator(object): 66 taxTable = [ 67 (80000, 0.45, 13505), 68 (55000, 0.35, 5505), 69 (35000, 0.3, 2755), 70 (9000, 0.25, 1005), 71 (4500, 0.2, 555), 72 (1500, 0.1, 105), 73 (0, 0.03, 0),] 74 75 def __init__(self, config): 76 self.config = config 77 def calculate(self, data_item): 78 empeeId, income = data_item 79 if income < self.config.JL: 80 taxSs = self.config.JL * self.config.rateSs 81 elif income > self.config.JH: 82 taxSs = self.config.JH * self.config.rateSs 83 else: 84 taxSs = income * self.config.rateSs 85 86 incomeDeSs = income - taxSs 87 taxableIncome = incomeDeSs - 3500 88 if taxableIncome < 0: 89 tax = 0 90 else: 91 for item in self.taxTable: 92 if taxableIncome > item[0]: 93 tax = taxableIncome * item[1] - item[2] 94 break 95 incomeReal = incomeDeSs - tax 96 return str(empeeId),str(income),"{:.2f}".format(taxSs),"{:.2f}".format(tax),"{:.2f}".format(incomeReal) 97 98 class Exporter: 99 100 def __init__(self, filename): 101 self.filename = filename 102 def export(self, data): 103 content = "" 104 for item in data: 105 line = ",".join(item) + "\n" 106 content += line 107 with open(self.filename, "w") as f: 108 f.write(content) 109 110 if __name__ == "__main__": 111 args = Args(sys.argv[1:]) 112 config = Config(args.get_arg("-c")) 113 empeeData = UserData(args.get_arg("-d")) 114 exporter = Exporter(args.get_arg("-o")) 115 calculator = IncomeTaxCalculator(config) 116 117 results = [] 118 for item in empeeData: 119 result = calculator.calculate(item) 120 results.append(result) 121 exporter.export(results)
写入文件 gongzi.csv:
101,3500,577.50,0.00,2922.50 203,5000,825.00,20.25,4154.75 309,15000,2475.00,1251.25,11273.75