【懒惰即是美德】
抽象意味着良好的可读性:说明你在努力做什么,而不是给出你正在如何做的细节。
【抽象和结构】
程序应该是非常抽象的,就像“下载网页、计算频率、打印每个单词的频率”一样易懂。翻译成程序就是:
page = download_page() freqs = compute_frequencies(page) for word.freq in freqs: print word.freq
【创建函数】
def hello(name): return 'Hello,' + name + '!'
>>> print (hello('world')) Hello,world!
记录函数
1、实例:
def hello(name): 'This is a hello world program!' return 'Hello,' + name + '!'
访问方式1:内建的help函数。
>>> help(hello) Help on function hello in module test: hello(name) This is a hello world program!
访问方式2:用hello._doc_访问失败。
>>> hello._doc_ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'function' object has no attribute '_doc_'
已解决:doc两边的下划线有两个!!!即__doc__
并非真正函数的函数=返回None的函数
【Parameter magic(参数魔法)】
值从哪里来?
我能改变参数吗(指改变实参)? - 在函数内为参数赋予新值不会改变任何外部变量的值,将可变的数据结构比如列表作为参数时实际是传递引用!
1、为什么要改变参数?- 抽象化程序的好方式。
可以利用这个特点编写函数来改变数据结构。
一个简单的例子:
def init(data): data['first'] = {} data['middle'] = {} data['last'] = {}
之后可以利用这个函数来初始化变量的数据结构。如下:
>>> from test import init >>> lovepython = {} >>> lovepython # 变量原始结构 {} >>> init(lovepython) >>> lovepython # 通过函数改变后的结构 {'first': {}, 'last': {}, 'middle': {}}
2、如果我的参数不可变呢?- 考虑传入数组。
关键字参数和默认参数
1、之前所用的参数都叫做“位置参数”,因为它们的位置很重要——甚至比它们的名字还要重要!
2、程序规模越大,关键字参数和默认参数的作用越大!
3、例如在下面的程序中,能辨别出谁是谁吗?
hi(1, 2, 4, 5)
但是如果使用关键字参数,就一目了然。(当然只是举例)
hi(name=1, age=2, city=4, born=5)
4、关键字参数更厉害地方在于可以给函数提供默认值。
5、混用位置参数和关键字参数的注意点:位置参数一定要放在前面!(尽量避免出现混用的情况)
收集参数
def f(k, *params);星号的意思就是“收集其余的位置参数,放进一个元组中(在这里这个元组叫做params)”。
但是有个问题是*params并不能收集关键字参数,那么如何收集关键字参数呢?答案是使用**params将关键字参数收集成字典:
def f(*collec_pospar, **collec_keypar): print(collec_pospar) print(collec_keypar)
>>> f(1, 2, 3, a=1, b=2, c=3) (1, 2, 3) {'b': 2, 'a': 1, 'c': 3}
反转过程
这个标题指的是“将参数收集为tuple和dict”的逆过程,也就是将dict和tuple分解成关键字参数和单个的参数。
例如,假设params = (1, 2, 4):
在作为函数参数的时候*params的结果是 1, 2, 4
对于dict也是同样的道理,只不过前置符号改为**罢了。
练习使用参数
【作用域】
【递归】
【小结】