python中利用少量代码快速实现从类对象中抽取所需属性的一种实践
项目中有可能会碰到这样一种场景:
根据一个id,查询得到和id对应的完整数据信息存储对象,比如书籍id到书籍详细信息,用户id到用户详细信息等,详细信息字段可能包括几十甚至上百个数据字段,真正需要返回给调用方的字段实际上却只占其中一小部分,这是出于性能和带宽的考虑(甚至在有些场景中,处于隐私或者安全考虑,强制要求不能返回非协议定义的信息字段,比如第三方登录一般只返回用户昵称、性别等少量信息),一般会从详细的数据对象中抽取出所需要的信息组装一个新的简化对象。
今天碰到这样一个问题,需要将一个存储多个详细信息对象的list转化为一个简化对象的list返回给主调方,尝试了数种方法后,通过使用列表推导、字典推导以及getattr内置函数这三者,用数行代码即达到了这一目的,
原始数据结构定义:
class detail_info(object):
def __init(self):
self.id = ''
self.title = ''
self.name = ''
self.url = ''
self.avatar = ''
self.p1 = None
self.p2 = None
self.p3 = None
self.p4 = None
self.p5 = None
self.p6 = None
self.p7 = None
self.p8 = None
...
实际所需要返回的信息字段为id,title,url和p1,放入一个字典即可,如下为针对一个长度为5的list执行的结果,经过字典推导+列表推导,并通过getattr动态获取类的属性值,两行代码即实现了将所需字段抽取出来形成一个以dict为元素的list。
>>> needed_keys = ['id', 'title', 'url', 'p1']
>>> [{k: getattr(x, k) for k in needed_keys} for x in alist]
[{'url': 'url_0', 'p1': 'p1_0', 'id': 'id_0', 'title': 'title_0'}, {'url': 'url_1', 'p1': 'p1_1', 'id': 'id_1', 'title': 'title_1'}, {'url': 'url_2', 'p1': 'p1_2', 'id': 'id_2', 'title': 'title_2'}, {'url': 'url_3', 'p1': 'p1_3', 'id': 'id_3', 'title': 'title_3'}, {'url': 'url_4', 'p1': 'p1_4', 'id': 'id_4', 'title': 'title_4'}, {'url': 'url_5', 'p1': 'p1_5', 'id': 'id_5', 'title': 'title_5'}]
如果要直接返回一个类似如下的简化结构:
class SimpleInfo(object):
def __init__(self):
self.id = ''
self.title = ''
self.url = ''
self.p1 = None
也只需要预先定义一个和alist等长的存储SimpleInfo结构的等长blist,组合zip函数的使用,稍加改动即可:
>>> blist = [SimpleInfo() for i in range(0, len(alist))]
>>> needed_keys = ['id', 'title', 'url', 'p1']
>>> [[setattr(y, k, getattr(x, k)) for k in needed_keys] for x, y in zip(alist,blist)]
[[None, None, None, None], [None, None, None, None], [None, None, None, None], [None, None, None, None], [None, None, None, None]]
>>> blist[0].__dict__
{'url': 'url_0', 'p1': 'p1_0', 'id': 'id_0', 'title': 'title_0'}
这里列表推导的代码使用setattr对blist中的SimpleInfo对象属性赋值,由于函数返回值为None,所以列表推导的结果是一个元素为None的list,通过查看blist[0]的信息,可以确认实际要赋值的属性已经通过setattr赋值给blist中对应的对象了。
python中利用少量代码快速实现从类对象中抽取所需属性的一种实践的更多相关文章
- Myeclipse中把java代码导成UML类图
Myeclipse中把java代码导成UML类图 1.右键点击项目名称,选择New-------àUML2 Model 2.给类图命名 3.导成类图 1)如果要把整个项目导成类图,则把整个项目拖到类图 ...
- SpingMVC中利用BindingResult将错误信息返回到页面中
SpingMVC中利用BindingResult将错误信息返回到页面中. ActionFrom中: private String name; private String password; get( ...
- java中,方法可以访问他的类对象的任何私有特性
java中,方法可以访问他的类对象的任何私有特性 读一本书(Core Java for the Impatient)时,发现这个注意,以前的时候没有在意,今天仔细想想发现记忆不深刻.记录一下 下面代码 ...
- class中new与未new的区别 类对象占用空间--转载
转载自http://blog.sina.com.cn/shuiwuhendeboke 颗颗的博客 (1)作用域不同 不用new:作用域限制在定义类对象的方法中,当方法结束时,类对象也被系统释放了 ...
- WPF中利用后台代码实现窗口分栏动态改变
在WPF中实现窗口分栏并能够通过鼠标改变大小已经非常容易,例如将一个GRID分成竖排三栏显示,就可以将GRID先分成5列,其中两个固定列放GridSplitter. <Grid Backgrou ...
- 用python将项目中的所有代码(或txt)合并在一个文件中
设计模式开卷考试给的例子代码都是一个类一个java,实在太恶心了,所以写了一个python脚本. import os fileansdir=r'C:\Users\tonyson_in_the_rain ...
- Python的高级特性8:你真的了解类,对象,实例,方法吗
Python的高级特性1-7系列是本人从Python2过渡3时写下的一些个人见解(不敢说一定对),接下来的系列主要会以类级为主. 类,对象,实例,方法是几个面向对象的几个基本概念,其实我觉得很多人并不 ...
- 在pycharm中自定义模板代码,快速输出固定代码块
pycharm中有时会经常输出固定一段代码,为避免每次重复输入,可以自定义一段模板代码,请看以下图教程: 1. 点击 file 里面的 setting 2. 在搜索框输入live,就会显示出 ...
- jsp中利用java代码换行
从数据库中取出的10条商品数据分两行显示,每行5条. <% for(int i=0; i<latestProducts.size(); i++) { Product p = latestP ...
随机推荐
- SQLi-db 批量注入工具+教程
这款工具在中国还没人发.所以我发来给大家玩玩:顺便带了教程. 关键字:inurl:article.asp?id= inurl:article.php?id=inurl:article.jsp?id=( ...
- tp3.2中的 I () 方法
I('get.id'); // 相当于 $_GET['id']
- Junit应用代码(读取mysql表数据)
1. 封装连接数据库的类: import java.sql.ResultSet; import java.sql.Connection; import java.sql.DriverManager; ...
- MFC中用户自定义类响应自定义消息
这篇技术文章不是讨论经典的MFC中的消息工作机理的,讨论消息工作原理.方式和路径的文章在网上和书本中随处可见.网上众多的讨论都是关于如何响应并进行用户自定义消息映射的:网上还有一些文章介绍如何在自定义 ...
- Entity Framework code first设置不在数据库中生成外键
你现在用的EF是什么版本?我用EF6,你可以重写SqlServerMigrationSqlGenerator的生成外键和更新外键的方法,把不需要的表都过滤掉不就ok了? public class Ex ...
- Nlog日志出坑合集
.net core框架下nlog不记录: 1.安装NLog.Web.AspNetCore 2.在Startup.cs文件的方法public void Configure(IApplicationBui ...
- mysql事务隔离
一.事务的特性 原子性.一致性.隔离性.持久性 二.事务的隔离级别 1.未提交读 (Read Uncommitpeatableted) 臭名昭著的脏读 ,事务A读到事务B未提交的数据 2.提交读RC( ...
- 霍金:AI或许能根除疾病和贫穷,但也可能摧毁人类 | GMIC 2017
在我的一生中,我见证了社会深刻的变化.其中最深刻的,同时也是对人类影响与日俱增的变化,是人工智能的崛起.简单来说,我认为强大的人工智能的崛起,要么是人类历史上最好的事,要么是最糟的.我不得不说,是好是 ...
- Layered Architecture 分层架构
分层的价值在于每一层都只代表程序中的某一特定方面.这种限制使每个方面的设计都更具有内聚性,更容易解释. 大多数成功的架构使用的都是包括下面这四个概念层的某个版本
- 19-3-5Python中列表、元组、以及range
一.列表: 为什么要学列表? 因为字符串存在缺点: 1) 只能存储少量的数据. 2) 数据类型无论索引.切片 获取的都是字符串类型,类型过于单一,转化成它原来的类型还需要进一步转换 ...