title: 可爱的豆子——使用Beans思想让Python代码更易维护

toc: false

comments: true

date: 2016-06-19 21:43:33

tags: [Python, Java, 经验]

category: Python

我曾经是一个对Java非常反感的人,因为Java的语法非常啰嗦。而用惯了动态类型的Python再使用静态类型的Java就会觉得多出了很多的工作量。

因为工作的关系,我开始使用Java来做项目。在这个过程中,我发现Java在某些方面确实和Python不一样。

有一句话说的好:

语言决定了世界观。

当我Java用的越来越多的时候,我渐渐发现我不是那么讨厌它了。

今天我要讲的,是我从Java里面学到的,一个被称为JavaBeans的东西。

In computing based on the Java Platform, JavaBeans are classes that encapsulate many objects into a single object (the bean). They are serializable, have a zero-argument constructor, and allow access to properties using getter and setter methods.

一句话概括起来: 当一些信息需要使用类似于字典套字典套列表这种很深的结构来储存的时候,请改用类来储存。

在Python里面,我以前会写这样的代码:

person_list = [{
'name': 'kingname',
'age': 23,
'sex': 'male'
'detail': {
'address': 'xxx',
'work': 'engineer',
'salary': 100000
}
},
{
'name': 'xiaoming',
'age': 65,
'sex': 'male'
'detail': {
'address': 'yyy',
'work': 'pm',
'salary': 0.5
}
}]

由于Python动态类型的特点,字典里面的value经常是包含了各种类型,有时候,字典里面包含了字典,里面的字典里面还有列表,这个内部字典里面的列表里面又包含了字典……

当我刚刚开始写Java代码的时候,也会保留了这个坏习惯,于是我定义的一个变量类似于这样:

public Map<String, List<Map<String, Map<String, Object>>>> info = .....

并且由于Java是静态类型语言,有时候Map里面的Value类型还不一致,需要使用Object来代替,等要使用的时候再做类型转换。

对于这样的写法,真可谓是写代码一时爽,调试代码火葬场。我过几天读自己的代码,自己都不知道这个字典里面有哪些内容,也不知道它们有哪些类型,必须到定义的地方去看。

我的Mentor看了我的Java代码以后,让我去用一下JavaBeans,于是我的世界瞬间就简洁多了。后来我将JavaBeans的思想用到Python中,果然Python代码也变得好看多了。

使用上面person_list这个复杂的结构为例,我用JavaBeans的思想,在Python里面重构它:

class Person(object):
def __init__(self, name='', age=0, sex='', detail=None):
self._name = name
self._age = age
self._sex = sex
self._detail = detail @property
def name(self):
return self._name @name.setter
def name(self, new_name):
self._name = new_name @property
def age(self):
return self._age @age.setter
def age(self, new_age):
self._age = new_age @property
def sex(self):
return self._sex @sex.setter
def sex(self, new_sex):
self._sex = new_sex @property
def detail(self):
return self._detail @detail.setter
def detail(self, new_detail):
self._detail = new_detail
class Detail(object):
def __init__(self, address='', work='', salary=0):
self._address = address
self._work = work
self._salary = salary @property
def address(self):
return self._address @address.setter
def address(self, new_address):
self._address = new_address @property
def work(self):
return self._work @work.setter
def work(self, new_work):
self._work = new_work @property
def salary(self):
return self._salary @salary.setter
def salary(self, new_salary):
self._salary = new_salary

从这里可以看到,我把字典变成了类。于是,当我想保存我自己的信息和小明的时候,我就可以这样写:

detail_kingname = Detail(address='xxx', work='engineer', salary=10000),
kingname = Person(name='kingname', age=23, sex='male', detail=detail_kingname) detail_xiaoming = Detail(address='yyy', work='pm', salary=0.5),
xiaoming = Person(name='xiaoming', age=65, sex='male', detail=detail_xiaoming) person_list = [kingname, xiaoming]

这样写,虽然说代码量确实翻了不止一倍,但是当我们后期维护的时候或者遇到问题来调试代码,我们就能发现这样写的好处。

举一个很简单的例子,在写了代码一年以后,我已经对这段代码没有多少印象了,现在我得到了变量person_list, 我想查看每个人的工资。首先,由于PersonDetail这两个类是已经定义好的,分别放在Person.pyDetail.py两个文件中,于是我点开它们,就知道,原来工资是保存在Detail这个类中的,关键词是salary, 而Detail又是保存在Person中的,关键词是detail

所以要查看每个人的工资,我可以这样写:

for person in person_list:
detail = person.detail
salary = detail.salary
print(salary)

但是如果我使用的是最上面字典的那种方式,那么情况就没有这么简单了。因为我不知道工资是在这个字典的什么地方。于是我首先要找到person_list是在哪里初始化的,然后看它里面有什么。在这个例子中,我是一次性把整个列表字典初始化完成的,直接找到列表初始化的地方就知道,原来这个person_list下面有很多个字典,字典有一个key 叫detail,这个detail的value本身又是一个字典,它下面的keysalary保存了工资的信息。这似乎还比较方便。但是如果字典里面的信息不是一次性初始化完成的呢?万一detail这一个key是后面再加的呢?于是又要去找detail初始化的地方……

第二个好处,使用Beans的时候,每个关键字是定义好的,salary就只能叫做salary,如果写成了salarv, 集成开发环境会立刻告诉你,Detail没有salarv这个属性。但是如果使用字典的方式,我在给字典赋值的时候,一不小心:

detail['salarv'] = 0.5

由于这里的salarv是字符串,所以集成开发环境是不会报错的,只有等你运行的时候,尝试读取detail['salary']里面的值,Python会告诉你:

Traceback (most recent call last):
File "xxx.py", line 1, in <module>
KeyError: 'salary'

总结

将JavaBeans的思想用在Python中,避免字典套字典这种深层嵌套的情况,对于一些需要反复使用的字典,使用类来表示。这样做,别人读代码的时候会更加的容易,自己开发的时候,也会避免出现问题。

本文首发地址: http://kingname.info/2016/06/19/bean-in-python/ 转载请注明出处。

可爱的豆子——使用Beans思想让Python代码更易维护的更多相关文章

  1. 让 Python 代码更易维护的七种武器——代码风格(pylint、Flake8、Isort、Autopep8、Yapf、Black)测试覆盖率(Coverage)CI(JK)

    让 Python 代码更易维护的七种武器 2018/09/29 · 基础知识 · 武器 原文出处: Jeff Triplett   译文出处:linux中国-Hank Chow    检查你的代码的质 ...

  2. 程序员需要掌握的七种 Python 代码更易维护的武器

    检查你的代码风格 PEP 8 是 Python 代码风格规范,它规定了类似行长度.缩进.多行表达式.变量命名约定等内容.尽管你的团队自身可能也会有稍微不同于 PEP 8 的代码风格规范,但任何代码风格 ...

  3. pythonic-让python代码更高效

    何为pythonic? pythonic如果翻译成中文的话就是很python.很+名词结构的用法在中国不少,比如:很娘,很国足,很CCTV等等. 我的理解为,很+名词表达了一种特殊和强调的意味.所以很 ...

  4. 让Python代码更快运行的 5 种方法

    不论什么语言,我们都需要注意性能优化问题,提高执行效率.选择了脚本语言就要忍受其速度,这句话在某种程度上说明了Python作为脚本语言的不足之处,那就是执行效率和性能不够亮.尽管Python从未如C和 ...

  5. Pycharm配置autopep8让Python代码更符合pep8规范

    一.何为pep8? PEP 8官方文档 -- Style Guide for Python Code PEP8中文翻译(转) 二.Pycharm中配置pep8 Pycharm本身是有pep8风格检测的 ...

  6. 一些你需要知道的Python代码技巧

    被人工智能捧红的 Python 已是一种发展完善且非常多样化的语言,其中肯定有一些你尚未发现的功能.本文或许能够让你学到一些新技巧.   Python 是世界上最流行.热门的编程语言之一,原因很多,比 ...

  7. 教你一招,提升你Python代码的可读性,小技巧

    Python的初学者,开发者都应该知道的代码可读性提高技巧,本篇主要介绍了如下内容: PEP 8是什么以及它存在的原因 为什么你应该编写符合PEP 8标准的代码 如何编写符合PEP 8的代码 为什么我 ...

  8. python代码风格-PEP8

    转载自http://www.douban.com/note/134971609/ Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下 ...

  9. 【转】python代码风格-PEP8

    转载自http://www.douban.com/note/134971609/ Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下 ...

随机推荐

  1. jQuery的append和appendTo

    这两个关键词,Insus.NET刚开始学习jQuery时,也被它弄得不好理解.现用得多了,运行与理解也不难了. 查了英文词典append的意思是“添加,附加”: 而后者appendTo意思是“ 添加至 ...

  2. 在某些情况下明明添加了引用,为何VS还报错&quot;XXX&quot;不存在类型或命名空间(是否缺少程序集引用)

    程序主结构:两个程序集DLL,一个OpticalAlarm(主程序),一个OpticalAlarm.Common 问题描述:搭建程序框架时,使用了log4net进行日志处理,在OpticalAlarm ...

  3. org.springframework.dao.EmptyResultDataAccessException

    public Wcrash getWcrashInfo(int id) { String sql = "select plateform_id,android_version,app_ver ...

  4. []: secureCRT连接ubuntu问题- The remote system refused the connection

    secureCRT连接ubuntu问题- The remote system refused the connection http://jxyang.iteye.com/blog/1484915 解 ...

  5. php模式设计之 策略模式

    策略模式: 策略模式设计帮助构建的对象不必自身包含逻辑,而是能够根据需要利用其他对象中的算法. 使用场景: 例如有一个CD类,我们类存储了CD的信息. 原先的时候,我们在CD类中直接调用getCD方法 ...

  6. 使用jquery-qrcode在页面上生成二维码,支持中文

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. CentOS7配置FTP服务器增强版~(零基础学会FTP配置)

    ps:原文不知出处,但是原文也不能正常启动,这里做了一些修改!如果能正常配置请在下方留言让更多的人看到,因为之前我本人照着网上的教程安装卸载了十多次也无法正常使用,不希望后面的兄弟继续浪费时间,如果不 ...

  8. Centos7安装Splash

    前言 最近在用Scrapy抓取一个网站数据,其中有个页面需要执行js脚本才能加载,所以需要用到Splash. 官网地址:https://splash.readthedocs.io/en/stable/ ...

  9. Eclipse SVN 合并分支/主干

    可以从主干合并到分支,也可以从分支合并到主干,根据需要可以选择合适的选项,如下图:

  10. acm2024

    /**  * C语言合法标识符  */ import java.util.*; public class acm2024 { public static void main(String[] args ...