当前位置:首页 > 杂谈 > 正文内容

Django 工厂模式导入微信、支付宝等账单

2024-06-18 02:28:20TONY杂谈329

工厂方法是最常用的模式之一它用于仅用一个API创建不同类型的对象,并使用子类来定义将创建哪一个对象。例子:我们将通过导入微信、支付宝等账单到我们自己的的系统中。使用工厂模式的话,我们将构建一个代表微信账单对象和一个支付包账单的对象。img1、分析微信、支付宝账单的csv文件1.1、微信账单表头从16(图中的序号17)行开始:df = pd.readcsv(csvfile, header=16)重命名列索引WECHATRECORDMAP ={ #定义 csv中需要读取的列名:对应序列化器中的字段名收/支:paytype,交易对方:addr,商品:note,支付方式:payway,金额(元):amount,交易类型:categoryid,交易时间:paydate}img1.2、支付宝账单表头从1(图中的序号2)行开始: df = pd.readcsv(csvfile, header=1)重命名列索引ALIPAYRECORDMAP ={收/支:paytype,交易对方:addr,商品说明:note,收/付款方式:payway,金额:amount,交易分类:categoryid,交易时间:paydate}img2、创建账单csv抽象类BillCsvImport代表每种账单csv概念的的抽象类from abc import ABC, abstractmethodclassBillCsvImport(ABC):definit(self, csvfile, columnmap: dict,**kwargs): self.csvfile = csvfile #账单文件 self.columns = columnmap #需要读取的列和对应字段的字典 self.kwargs = kwargs @abstractmethoddefreadcsv(self, csvfile):#读取文件passdefdatatreating(self):"""数据处理""" df = self.readcsv(self.csvfile)# 读取数据 df.columns = df.columns.str.strip()# 去除columns前后空格 df = df.rename(columns=self.columns)# 索引重命名#删除包含nan的列,all全为nan才删除,any包含一个才删除 df = df.dropna(axis=1, how=all)#去除前后空格# df.replace(\s+,, regex=True, inplace=True)# 对整个表去除空格,不太好,去除了字符串之间的空格for column in df.columns:if df[column].dtype ==object: df[column]= df[column].str.strip()#将不同账单通过删除、修改或者替换数据等方式,整理成统一样式的DataFrame df = self.dropupdatedata(df)#通过正则替换paytype列:支出替换成0...,inplace=True:表示直接修改表中数据 df[paytype].replace(regex={支出:, 收入:1, r^[^支收]:3}, inplace=True) df = df.loc[:, self.columns.values()]# 获取指定列数据,return dfdefdropupdatedata(self, df):#不同账单,通过删除、替换等方式,返回统一格式的DataFramereturn df3、定义二个子类一个用于处理微信账单import pandas as pdclassWeChatBill(BillCsvImport): WECHATRECORDMAP ={ #定义 csv中需要读取的列名:对应序列化器中的字段名收/支:paytype,交易对方:addr,商品:note,支付方式:payway,金额(元):amount,交易类型:categoryid,交易时间:paydate}definit(self, csvfile,**kwargs): super(WeChatBill, self).init(csvfile, self.WECHATRECORDMAP,**kwargs)defreadcsv(self, csvfile): super(WeChatBill, self).readcsv(csvfile)# header:指定表头,微信账单从第16行开始 df = pd.readcsv(csvfile, header=16)return dfdefdropupdatedata(self, df): df = super(WeChatBill, self).dropupdatedata(df) df.dropna(subset=[商户单号], inplace=True)# 删除商家订单号为空的数据 df[amount]= df[amount].str.replace(,)# 0.10->0.10去除# 分类设置扫码付款、商户消费->生活消费;微信红包->红包 df[categoryid].replace(regex={商户消费:生活消费,扫二维码付款:生活消费, r.*红包.*:红包}, inplace=True)return df一个用于处理支付宝账单import pandas as pdclassAliPayBill(BillCsvImport): ALIPAYRECORDMAP ={收/支:paytype,交易对方:addr,商品说明:note,收/付款方式:payway,金额:amount,交易分类:categoryid,交易时间:paydate}definit(self, csvfile,**kwargs): super(AliPayBill, self).init(csvfile, self.ALIPAYRECORDMAP,**kwargs)defreadcsv(self, csvfile): super(AliPayBill, self).readcsv(csvfile) df = pd.readcsv(csvfile, header=1#, encoding=gbk)return dfdefdropupdatedata(self, df): df = super(AliPayBill, self).dropupdatedata(df) df.dropna(subset=[商家订单号], inplace=True)# 删除商家订单号为空的数据#去除交易关闭的行 df.drop(df[(df[交易状态]==关闭交易)(df[交易状态]==退款成功)].index, inplace=True)return df4、简单工厂模式如果不使用工厂模式,我们可以使用简单的if-else语句,根据账单类型给出对应的账单对象defgetbill(billtype, csvfile):if billtype ==WeChatBill:return WeChatBill(csvfile)elif billtype ==AliPayBill:return AliPayBill(csvfile)#测试alipaybilldf = getbill(../const/alipaybill.csv,AliPayBill).datatreating()wechatbilldf = getbill(../const/wechatbill.csv,WeChatBill).datatreating()这就是简单的工厂方法,当你需要使用较少数量类型或者较少数量的依赖项时是可以的,但是当类型数量变多时,这就不是一个很好的解决方案。从软件工程的角度分析:1、它违背了开闭原则:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。如果我们要导入其他的账单时,例如:抖音账单,必须在getbill中添加新的分支。2、它违背了依赖倒置原则:抽象不应该依赖于细节,细节应该取决于抽象。把抽象层放在程序设计的高层,并保持稳定,程序的细节变化由低层的实现层来完成。这个方法依赖于类的实现,而不是抽象类。同时当你的代码中存在大量if-else时,你就应该考虑另一种方法了。5、工厂方法模式接下来我们尝试通过遵循这两个原则来改进这个逻辑imgBillFactory类的核心是classmap属性,它是一个简单的字典,用于映射每个具体账单,从RowFactory到BillCsvImport的虚线可以看到,它只依赖于抽象类,遵循依赖倒置原则。createclassmap()函数解析billimport模块,并搜索所有成员判断:是否是一个类、并且不是抽象类、并且是BillCsvImport的子类import billimportfrom inspect import getmembers, isclass, isabstractclassBillImportFactory: classmap =[]definit(self): self.classmap = self.createclassmap()@staticmethoddefcreateclassmap(): classlist =[] concreteclasses = getmembers(billimport, lambda m: isclass(m)andnot isabstract(m)and issubclass(m, billimport.BillCsvImport))for classname, concreteclass in concreteclasses: classlist.append(dict(classname=classname, concreteclass=concreteclass))return classlistdefgetbill(self, classname, csvfile,**kwargs): rowclass = list(filter(lambda elem: elem.get(classname)== classname, self.classmap))if len(rowclass)==:raise Exception(没有找到这个名字的账单)return rowclass[].get(concreteclass)(csvfile,**kwargs)接下来我们就可以使用getbill方法返回一个账单对象下面是一个如何使用这个工厂类来创建对象的例子:billfactory = BillImportFactory()alipaybilldf = billfactory.getbill(AliPayBill,../const/alipaybill.csv).datatreating()wechatbilldf = billfactory.getbill(WeChatBill,../const/wechatbill.csv).datatreating()#接下来我们便可以通过序列化进行批量的创建,保存到我们的数据库中# expenseser = ExpenseImportSerializer(data=alipaybilldf.todict(records), many=True)# expenseser.isvalid(raiseexception=True)# expenseser.save(createdby=request.user)6、结论工厂模式帮助我们创建从同一子类派生的不同类型的对象,并防止修改代码的创建部分。

“Django 工厂模式导入微信、支付宝等账单” 的相关文章

花样滑冰陈虹伊-冰上优美的舞者

花样滑冰陈虹伊-冰上优美的舞者

陈虹伊:冰上舞者陈虹伊,一位在花样滑冰领域崭露头角的年轻运动员,以其出色的技巧和独特的风格赢得了广泛的赞誉。一、早期经历陈虹伊从小就展现出了对花样滑冰的浓厚兴趣。她的家庭氛围熏陶了她的坚韧和毅力,使她在面对困难和挫折时始终保持坚韧不拔的精神。在早期的学习过程中,她不断追求技术的精进和艺术的表现力,为...

江西赣县遭遇罕见冰雹袭击,多地受灾

江西赣县遭遇罕见冰雹袭击,多地受灾

【江西赣县讯】近日,江西省赣县地区突降罕见冰雹,给当地带来严重灾害。据初步统计,冰雹袭击导致多地农作物受灾、房屋受损,当地政府和救援机构迅速行动,展开救援工作。据了解,冰雹袭击发生在当地时间下午,持续时间长达数十分钟。冰雹直径最大达到2厘米,持续半小时,密度极大,给当地带来了严重的灾害。不少地区的农...

寿命长的男人有什么表现?粗略统计:一般都有“3小2高”-寿命较短的男性三个表现

寿命长的男人有什么表现?粗略统计:一般都有“3小2高”-寿命较短的男性三个表现

男人,一般都是心脑血管疾病、肝胆疾病、高血压高血脂等慢性疾病的高发人群,特别是40岁之后的男人,更受这些疾病的“青睐”,这除了与男人承受的重压有关外,更与男性朋友的很多不良生活习惯有关,当然,这也是少部分,很多男性朋友开始注重养生,与长寿自然也不会擦肩而过。...

没工作怎么开工作证明?哪儿能开到工作证明呢?这里就解决-没有工作如何开工作证明

没工作怎么开工作证明?哪儿能开到工作证明呢?这里就解决-没有工作如何开工作证明

没有工作怎么开工作证明呢?如果是正常来说的话没有工作就没有公司可以进行盖章了,无论是工作证明、务工证明等等其实最主要的是有单位进行盖章,这个章不能够是电子章而要现盖上去的。对于没有工作的人怎么能开到工作证明呢?这个时刻呢只好借由咱们了小程序,口袋模板。到那儿就能接洽,各个地区的证明都可以的。网友分享...

琢玉成器是指什么生肖,词语解释落实

琢玉成器是指什么生肖,词语解释落实

琢玉成器指的是生肖猴、生肖羊、生肖马。琢玉成器在十二生肖中代表的是猴、羊、马、猪、牛。生肖猴生肖猴的人自尊心很强,机会变得明朗了,福气享不尽,能够积极与领导老板协商解决问题,喜欢在与人交往之中了解对方的思想观点,财星青睐,贵人扶持,事业飞黄腾达,能展现才华,让自己一飞冲天,生肖猴的人做事十分认真,他...

老司机良心分享的搜索网站,纯净无广告,还能搜你意想不到的资源-老司机会闯红灯吗

老司机良心分享的搜索网站,纯净无广告,还能搜你意想不到的资源-老司机会闯红灯吗

如今我们想要获取资料,都离不开搜索引擎,搜索引擎的质量决定了我们获取信息的效率。但是有一些搜索引擎,首页几乎全部都是广告和无用信息,真正有用的信息都在第2页以后,这要是遇到什么急事,非得被它气哭! 所以,我整理了几个纯净、无广告的搜索引擎给大家,目的就是让...