defsum_naturals(n): """Return the sum of the first n natural numbers >>> sum_naturals(10) 55 >>> sum_naturals(100) 5050 """ total, k = 0, 1 while k <= n: total, k = total + k, k + 1 return total
调用如下,globals返回全局变量的表示,需要它来求解表达式,正常运行应该不返回结果:
1 2
from doctest import run_docstring_examples run_docstring_examples(sum_naturals,globals())
在文件中编写python,可以用下面命令启动文档中所有doctest:
1
python3 -m doctest <python_source_file>
高阶函数
观察下列求和函数,可以看到相似的求和过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
defsum_naturals(n): total, k = 0, 1 while k <= n: total, k = total + k, k + 1 return total
defsum_cubes(n): total, k = 0, 1 while k<=n: total, k = total + pow(k,3), k+1 return total
defpi_sum(n): total, k = 0,1 while k<=n: total, k = total + 8/(k*(k+2)), k+4 return total
对于相似的过程,我们可以将其抽象出来,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
defdo_sum(n,term,next): total,k = 0,1 while k<=n: total, k = total + term(k),next(k) return total
defmake_instance(cls): defget_value(name): if name in attributes: return attributes[name] else: value = cls["get"](name) return bind_method(value,instance)
defbind_method(value,instance): ifcallable(value): defmethod(*args): return value(instance,*args) return method else: return value
如果入参为可调用的,则绑定到instance,如果不是,则返回对应值。
注意这里的instance本质还是一个字典,在后续的成员函数的使用上会看到这一点。
在关注完创建对象之后我们再来关注创建类,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
defmake_class(attributes,base_class=None): defget_value(name): if name in attributes: return attributes[name] elif base_class isnotNone: return base_class["get"](name)
defset_value(name,value): attributes[name] = value
defdeposit(self_instance, amount): """Increase the account balance by amount and return the new balance.""" new_balance = self_instance['get']('balance') + amount self_instance['set']('balance', new_balance) return self_instance['get']('balance')
defwithdraw(self_instance, amount): """Decrease the account balance by amount and return the new balance.""" balance = self_instance['get']('balance') if amount > balance: return'Insufficient funds' self_instance['set']('balance', balance - amount) return self_instance['get']('balance') return make_class({'__init__': __init__, 'deposit': deposit, 'withdraw': withdraw, 'interest': 0.02})