使用 Mockito Mock 方法式,一直以为可以用anyString(),any(Foo.class)等匹配null值,其实不行,null值必须显式的用null, 或eq(null)来匹配。anyString(),anyInt()等只能匹配非null值,查看它们的返回值实际是 "" 和 0 等, 而更为特别的是any(Foo.class)看到的是null, 仍然不能匹配null值。进一步用Mockito.mockingDetails(mock).printInvocations()打印出的内容,anyString(),any(Foo.class)都会显示为null值。
说的有点罗嗦,看下面的例子, 被测试类 UserDao,sql 和 sqlArguments 由各自的 setter 方法来控制,默认它们都为nullRead More
Python 集合的遍历,推导及 filter/map/reduce 操作 中讲了对集合的 filter, map 和 reduce 操作,那还有 sort 排序呢?像 Java 一样,Python 也提供了 sort() 和 sorted() 方法。
sort() 是 list 的实例方法, sorted() 是一个内置函数。Python 中也是只有 list 才有顺序。list.sort() 方法
查看 Python 3 中的list.sort()方法(help(list.sort))Help on method_descriptor:
Python 的 list.sort() 方法和 Java List.sort() 方法一样的,都是
sort(self, /, *, key=None, reverse=False)
Stable sort *IN PLACE*.IN PLACE排序,没有返回值。实际看下各种排序场景 Read More
冒泡和选择排序的简单粗暴也许在某些人眼里都不能称作算法,现在要进入一种更优雅的排序算法,快速排序。它使用分而治之(Divide and Conquer, D&G) 的策略,要应用到递归调用。快速排序敢说自己快速,也确实比选择排序快很多很多。冒泡和选择排序,尤其是选择排序是非常自然的排序算法,而快速排序就不是一般人会随意想出来的。
快速排序的演绎需要用递归来思考循环的问题,然而我之前总是在及力用循环来避免递归调用,有趣的是诸如 Haskell 等函数式编译语言根本没有循环,只能用递归来编写循环的效果。来看一个简单的例子,比如要从 1 加到 100,我们很自然会用循环从 1 累加到 100,如果换成递归,看下面的代码1def summary(arr): 2 if len(arr) == 0: 3 return 0 4 else: 5 return arr[0] + summary(arr[1:]) 6 7 8print(summary(list(range(1, 101)))) # 5050
递归有助于我们把大问题分解为小问题,上面代码的思维是数组的和总是很一个元素加上剩下元素列表的和,直到最后元素列表为空(和为 0)。 Read More
看到本文标题也许要奇怪了,Python 的 print 难道不是也上可以看到结果的吗?在 Python shell 下只要>> print('Hello world!')
不就立马能看到控制台输出的 "Hello world!" 吗。或者是一个 Python 脚本文件 hello.py
Hello world!import time
然后执行
for i in range(3):
print('Hello {}'.format(i))
time.sleep(3)python hello.py的话,我们也同样能看到在控制台下在预定的每 3 秒输出一行Hello 0
但执行下面的命令试图重定向输出到文件时的效果就不一样了 Read More
Hello 1
Hello 2
以下内容完全毫无章序,是阅读 《redis设计与实现(第二版)》一书所划的一些自己助记用的重点。本不访放到博客上来,只称放在个人 Evernote 当中,于此纯粹为了自己往后查阅,所以请不要读它。OBJECT ENCODING key 可以查数据存储的底层结构类型如redis> SADD numbers 1 3 5 7 9redis> OBJECT ENCODING numbers"intset"redis> ZADD fruit-price 5 bananaredis> OBJECT ENCODING fruit-price"quicklist"Redis 的对象带有访问时间记录信息,该信息可用于计算数据库键的空转时长redis> type msg 返回值对象的类型字符串对象编码可用 int,raw 或者 embstrRead More
Redis 自 2.6 版本起加入了服务端的 Lua 脚本支持,即增添了EVAL,EVALSHA,SCRIPT相关命令。Lua 为何物,Lua 是一个非常轻量级,强大,高效,可内嵌的脚本语言; 产自于巴西,源码和二进制包都只有 200 多 KB。当前版本的 Redis 5.0.5 中 Lua 引擎版本是 Lua 5.1(自 Redis 2.6 起就没变,当前 Lua 为 5.3.5),可用 Redis 命令eval "return _VERSION" 0查看到。
本文就要探究一下如何在 Redis 中使用 Lua 脚本,以及如何简化与 Redis 的交互。比如说在 Redis 中要先获一个值,然后根据这个值再去 Redis 中获得另一个相关联的值,如果不使用 Lua 脚本就会有两次与 Redis 交互,引入 Lua 脚本可以只用一次操作。
本文不具体讲述 Lua 语言本身,只涉及到与 Redis 相关的 Lua 特性。现在来体验下 Lua 中嵌入 Lua 脚本的基本操作。 Read More
在 Python 中如果把函数定义写在调用的下方可能会出错,例如下面的代码
1foo() 2 3def foo(): 4 print("hello")执行时会报出错误
NameError: name 'foo' is not defined
这时候要把
foo()调用代码放到该函数的声明后面1def foo(): 2 print("hello") 3 4foo()这样执行就一切正常了。这仿佛像是 C 语言中的函数调用需要提前声明一般,例如在 C 语言中要调用后头的定义的函数要写成 Read More

本文紧承上一篇 Python 常用日期处理,因制于篇幅的大小需求才临时分立新篇,这里要简单提到 calendar 和 dateutil 模块的使用,其中 calendar 是 Python 内置的。相比于上一篇而言,此处主旨会更明确一些,只记录三个应用案例,分别是
- 用 dateutil 灵活的解析 datetime 字符串
- 给定起始日期后的连续日期
- 给定起始日期后连续的月末日期
dateutil 灵活的解析 datetime 字符串
使用 Python 内容的 date 或 datetime, 构造它们的实例时需要逐个的传入年月日或时分秒,或者要调用
fromisoformat()方法解析严格的字符串表示格式。而 dateutil.parser 的 parse() 方法就显得特别的聪明和随意,它可以智能的解析更丰富的字符串表示方式。详细的支持格式请参考官方文档的 parse examples,恐怕官方文档也未列举完全,只要觉得合理的时间字符串就可以尝试去解析。下方是一些例子 Read More
仅以此篇记录一下个人常用的 Python 处理日期的库与函数,主要涉及的类库有 Python 自带的 datetime, time 和 calendar,以及第三方的 dateutil。说到日期处理基本上要覆盖的概念有 date, time, datetime, timezone, calendar, 时间的比较与差值,解析与格式化显示等。
在 datetime 模块中类之间的继承关系如下:
object
├── date
│ └── datetime
├── time
├── timedelta
└── tzinfo
└── timezone我们着重体验一下前面粗体显示的 datetime, date, time, timedelta 对象, timezone 也不是不重要,有时候也可能只需要处理本地时间。 Read More
本文为阅读 《Python Tricks: The Book》一书的 3.5 Function Argument Unpacking 的笔记与扩充理解。函数参数拆解是定义可变参数(VarArgs)*args和**kwargs的反向特性。*args和**kwars是函数可定义一个形参来接收传入的不定数量的实参。
而这里的函数参数拆解是形参定义多个,在调用时只传入一个集合类型对象(带上 * 或 ** 前缀),如list,tuple,dict, 甚至是generator, 然后函数能自动从集合对象中取得对应的值。
如果能理解下面赋值时的参数拆解和 Python 3.5 的新增***操作,那么于本文讲述的特性就好理解了。
唯一的不同时作为参数的集合传入函数时必须前面加上*或**, 以此宣告该参数将被拆解,而非一个整体作为一个函数参数。加上*或**与 Java 的@SafeVarargs有类似的功效,最接近的是 Scala 的 `foo(Array[String]("d", "e") : _*)` 写法。参见:Java 和 Scala 调用变参的方式 Read More