# ((Python基础教程))学习笔记 | 第06章 | 抽象

2014-09-23

------

```>>> fibs=[0,1]
>>> for i in range(8):
fibs.append(fibs[-2]+fibs[-1]) #fibs[-2]+fibs[-1]后两位数,append往后添加

#运行后，包含10个斐波那契数列的10个数字是
>>> fibs
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]```

```>>> fibs = [0,1]
>>> num = input(&#39;Enter number here:&#39;)
Enter number here:10
>>> for i in range(num-2):
fibs.append(fibs[-2]+fibs[-1])
>>> fibs
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]```

```num = input(&#39;How many numbers do you want? &#39;)
print fibs(num)```

```page  = download_page()
freqs = compute_frequencies(page)
for word,freq in freqs:
print word, freq```

------

```>>> import math
>>> x = 1
>>> y = math.sqrt
>>> callable(x)
False
>>> callable(y)
True```
Note:callbale()在Python3.0里面会用hasattr(func.__call__)来代替

```>>> def hello(name):
return &#39;Hello,&#39; + name + &#39;!&#39;
>>> hello(&#39;Jerry&#39;)
&#39;Hello,Jerry!&#39;```

```>>> def fibs(num):
result = [0,1]
for i in range(num-2):
result.append(result[-2]+result[-1])
return result

>>> fibs(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]```

Note:

1. return 语句非常重要，是用来从函数中返回&#20540;的，如果没有的话，返回None

```>>> def sum(x,y):
result = x + y
>>> print sum(1,2)
None```

2. return 相当于程序中的break.比如说下面的:

```def test():
print &#39;This is 1 line.&#39;
return
print &#39;This is 2 line&#39;
test()
#输出结果
>>>This is 1 line.```

------

```>>> def square(x):
&#39;Calculates the square of the number x&#39;
return x*x```

```>>> square.__doc__
&#39;Calculates the square of the number x&#39;```

```>>> dir(square)
[&#39;__annotations__&#39;, &#39;__call__&#39;, &#39;__class__&#39;, &#39;__closure__&#39;, &#39;__code__&#39;, &#39;__defaults__&#39;, &#39;__delattr__&#39;, &#39;__dict__&#39;, &#39;__dir__&#39;, &#39;__doc__&#39;, &#39;__eq__&#39;, &#39;__format__&#39;, &#39;__ge__&#39;, &#39;__get__&#39;, &#39;__getattribute__&#39;, &#39;__globals__&#39;, &#39;__gt__&#39;, &#39;__hash__&#39;, &#39;__init__&#39;, &#39;__kwdefaults__&#39;, &#39;__le__&#39;, &#39;__lt__&#39;, &#39;__module__&#39;, &#39;__name__&#39;, &#39;__ne__&#39;, &#39;__new__&#39;, &#39;__qualname__&#39;, &#39;__reduce__&#39;, &#39;__reduce_ex__&#39;, &#39;__repr__&#39;, &#39;__setattr__&#39;, &#39;__sizeof__&#39;, &#39;__str__&#39;, &#39;__subclasshook__&#39;]```
```>>> help(square)
Help on function square in module __main__:

square(x)
Calculates the square of the number x```

------

```>>> def try_to_change(n):
n = &#39;Mr, Gumby&#39;
>>> name = &#39;Mrs, Smith&#39;
>>> try_to_change(name) #将name作为实参传给try_to_change函数
>>> name                #全局变量值不变
&#39;Mrs, Smith&#39;```

```>>> def change(n):
n[0] = &#39;Mr. Gumby&#39;
>>> name = [&#39;Mrs. Smith&#39;,&#39;Mr. Jing&#39;]
>>> change(name)
>>> name                #值已经发生了变化
[&#39;Mr. Gumby&#39;, &#39;Mr. Jing&#39;]```

```>>> name = [&#39;Mrs. Smith&#39;,&#39;Mr. Jing&#39;]
>>> n    = name         #模拟传参数
>>> n[0] = &#39;Mr. Gumby&#39;  #改变列表
>>> name
[&#39;Mr. Gumby&#39;, &#39;Mr. Jing&#39;]```

```>>> storage={}
>>> storage[&#39;first&#39;]={}
>>> storage[&#39;middle&#39;]={}
>>> storage[&#39;last&#39;]={}
>>> storage
{&#39;middle&#39;: {}, &#39;last&#39;: {}, &#39;first&#39;: {}}```
#storage这种字典的存储方式，有3个键'first','middle','last'.

```>>> storage[&#39;first&#39;][&#39;Magus&#39;]=[me]
>>> storage[&#39;middle&#39;][&#39;Lei&#39;]=[me]
>>> storage[&#39;last&#39;][&#39;Hetland&#39;]=[me]
>>> storage
{
&#39;middle&#39;:   {&#39;Lei&#39;: [&#39;Magnus Lei Hetland&#39;]},
&#39;last&#39;: {&#39;Hetland&#39;: [&#39;Magnus Lei Hetland&#39;]},
&#39;first&#39;: {&#39;Magus&#39;:  [&#39;Magnus Lei Hetland&#39;]}
}```

>>> storage['middle']['Lei']
['Magnus Lei Hetland']

```>>> my_sister=&#39;Anne Lei Hetland&#39;
>>> storage[&#39;first&#39;].setdefault(&#39;Anne&#39;,[]).append(my_sister)
>>> storage[&#39;middle&#39;].setdefault(&#39;Lei&#39;,[]).append(my_sister)
>>> storage[&#39;last&#39;].setdefault(&#39;Hetland&#39;,[]).append(my_sister)
>>> storage[&#39;first&#39;][&#39;Anne&#39;]
[&#39;Anne Lei Hetland&#39;]
>>> storage[&#39;middle&#39;][&#39;Lei&#39;]
[&#39;Magnus Lei Hetland&#39;, &#39;Anne Lei Hetland&#39;]```

```>>> def init(data):
...     data[&#39;first&#39;]={}
...     data[&#39;middle&#39;] = {}
...     data[&#39;last&#39;] = {}
...
>>> init(storage)
>>> storage
{&#39;middle&#39;: {}, &#39;last&#39;: {}, &#39;first&#39;: {}}```

```>>> def inc(x): return x+1
...
>>> i = 10
>>> i = inc(i)
>>> i
11```

```>>> def inc(x):
...     x[0] = x[0] + 1
...
>>> foo = [10]
>>> inc(foo)
>>> foo
[11]```

------

```>>> def hello_1(greeting,name):
print "%s,%s!"%(greeting,name)
...
>>> def hello_2(name,greeting):
print "%s,%s!"%(name,greeting)
...```

```>>> hello_1(&#39;hello&#39;,&#39;world&#39;)
hello,world!
>>> hello_2(&#39;hello&#39;,&#39;world&#39;)
hello,world!```

```>>> hello_1(greeting=&#39;Hi&#39;, name=&#39;Jerry&#39;)
Hi,Jerry!```

```>>> hello_2(name=&#39;Jerry&#39;,greeting=&#39;Hi&#39;)
Jerry,Hi!```

```store(&#39;Mr. Smith&#39;,10,20,13,5)
store(patient=&#39;Mr. Smith&#39;,hour=10,minutes=20,day=13,month=5)```

```>>> def hello_3(greeting=&#39;Hello&#39;,name=&#39;World&#39;):
...     print &#39;%s,%s!&#39; % (greeting,name)
...
>>> hello_3()           #如果不加参数的话，就用默认值
Hello,World!
>>> hello_3(&#39;greeting&#39;) #带参数的话，按参数顺序赋值
greeting,World!
>>> hello_3(&#39;greeting&#39;,&#39;universe&#39;) #按提供的顺序
greeting,universe!
# 如果只想提供name，而让greeting默认
>>> hello_3(name=&#39;Sherry&#39;)
Hello,Sherry!```

Note:

```>>> def hello_4(name,greeting=&#39;Hello&#39;,punctuation=&#39;!&#39;):
...     print &#39;%s, %s%s&#39; % (greeting,name,punctuation)
...
>>> hello_4(&#39;Jerry&#39;)
Hello, Jerry!
>>> hello_4(&#39;Jerry&#39;,&#39;Howdy&#39;)
Howdy, Jerry!
>>> hello_4(&#39;Jerry&#39;,&#39;Howdy&#39;,&#39;...&#39;)
Howdy, Jerry...
>>> hello_4(&#39;Jerry&#39;,punctuation=&#39;.&#39;)
Hello, Jerry.
>>> hello_4(&#39;Jerry&#39;,greeting=&#39;Top of the morning to ya&#39;)
Top of the morning to ya, Jerry!
>>> hello_4()
Traceback (most recent call last):
File "", line 1, in ?
TypeError: hello_4() takes at least 1 argument (0 given)```

#如果最后一个name也用默认&#20540;的话，就不会产生上面的异常.

------

```>>> def print_parms(*parms):
...     print parms
...```
#1个参数的话，会作为元祖打印出来，里面还有逗号
```>>> print_parms(&#39;Hello&#39;)
(&#39;Hello&#39;,)
>>> print_parms(1,2,3)
(1, 2, 3)```
#parms前面的*号，将所有的参数放到一个元祖里面，然后使用。

```>>> def print_parms_2(title,*parms):
...     print title
...     print parms
...
>>> print_parms_2(&#39;Parms:&#39;,1,2,3)
Parms:
(1, 2, 3)```
#在这里，*变成了收集其余的位置参数
```>>> print_parms_2(&#39;Nothing:&#39;)
Nothing:
()```

```>>> print_parms_2(&#39;hmm...&#39;,someting=42)
Traceback (most recent call last):
File "", line 1, in ?
TypeError: print_parms_2() got an unexpected keyword argument &#39;someting&#39;```

```>>> def print_parms_3(**parms):
...     print parms
...
>>> print_parms_3(x=1,y=2,z=3)
{&#39;y&#39;: 2, &#39;x&#39;: 1, &#39;z&#39;: 3}```
#返回的是字典而不是元祖

```>>> def print_parms_4(x,y,z=3,*pospar,**keypar):
...     print x,y,z
...     print pospar
...     print keypar
...
>>> print_parms_4(1,2,3,5,6,7,foo=1,bar=2)
1 2 3
(5, 6, 7)
{&#39;foo&#39;: 1, &#39;bar&#39;: 2}```

------

```>>> def add(x,y): return x+y
...
>>> parms=(1,2)
#下面这样会报错
Traceback (most recent call last):
File "", line 1, in ?
TypeError: add() takes exactly 2 arguments (1 given)
#必需这样，前面加个*号
3```
#字典方面的调用
```>>> def hello_3(greeting=&#39;Hello&#39;,name=&#39;World&#39;):
...     print &#39;%s,%s!&#39; % (greeting,name)
...
>>> params = {&#39;name&#39;:&#39;Sir Robin&#39;,&#39;greeting&#39;:&#39;Well met&#39;}
>>> hello_3(**params)
Well met,Sir Robin!```
#再看下面的，看加双*和没加**
```>>> def with_star(**kwd):
...     print kwd[&#39;name&#39;],&#39;is&#39;,kwd[&#39;age&#39;],&#39;years old!&#39;
...
>>> def without_star(kwd):
...     print kwd[&#39;name&#39;],&#39;is&#39;,kwd[&#39;age&#39;],&#39;years old!&#39;
...
>>> args = {&#39;name&#39;:&#39;Mr. Gumby&#39;,&#39;age&#39;:35}
>>> with_star(**args)
Mr. Gumby is 35 years old!
>>> without_star(args)
Mr. Gumby is 35 years old!```
#可以看出两者情形一样，所以*只在定义函数(允许不定数目的参数)

Note:

```>>> def foo(x,y,z,m=0,n=0):
...     print x,y,z,m,n
...
>>> def call_foo(*arg,**kwds):
...     print &#39;Calling foo&#39;
...     foo(*arg,**kwds)```
------

```def story(**kwds):
return &#39;Once upon a time. There was a &#39; \
&#39;%(job)s called %(name)s.&#39; % kwds

def power(x,y,*others):
if others:
return pow(x,y)

def interval(start,stop=None,step=1):
&#39;Imitates range() for step>0&#39;
if stop is None:
start,stop = 0,start
result = []
i = start
while i < stop:
result.append(i)
i +=step
return result

print story(job=&#39;king&#39;,name=&#39;Gumby&#39;)
print story(name=&#39;Jerry&#39;,job=&#39;king&#39;)
params = {&#39;job&#39;:&#39;language&#39;,&#39;name&#39;:&#39;Python&#39;}
print story(**params)
del params[&#39;job&#39;]
print story(job=&#39;stroke of genius&#39;,**params)
print power(2,3)
print power(3,2)
print power(y=3,x=2)
params =(5,)*2
print power(*params)
print power(2,3,&#39;Hello,World!&#39;)
print interval(10)
print interval(1,5)
print interval(3,12,4)
print power(*interval(3,7))```

D:\>python Python.py

```Once upon a time. There was a king called Gumby.
Once upon a time. There was a king called Jerry.
Once upon a time. There was a language called Python.
Once upon a time. There was a stroke of genius called Python.
8
9
8
3125
8
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4]
[3, 7, 11]
81```

------

```>>> x = 1
>>> scope = vars()
>>> scope[&#39;x&#39;]
1
>>> scope[&#39;x&#39;] +=1
>>> x
2```
#只在函数体内有效
```>>> def foo(): x = 42
...
>>> x = 1
>>> foo()
>>> x
1
>>> def output(x): print x
...
>>> x = 1
>>> y = 2
>>> output(y)
2```
#函数体内使用外部变量
```>>> def combine(param): print param+external
...
>>> external = &#39;berry&#39;
>>> combine(&#39;Shrub&#39;)
Shrubberry```
WARN:像这样引用变量是很多错误的原因:

```>>> def comb(param):
...     print param + globals()[&#39;param&#39;]
...
>>> param=&#39;Sherry&#39;
>>> comb(&#39;Jerry->&#39;)
Jerry->Sherry```

```>>> x = 1
>>> def change_global():
...     global x
...     x +=1
...
>>> x
1
>>> change_global()
>>> x
2```

------

```>>> def foo():
...     def bar():
...         print &#39;Hello,World!&#39;
...     bar()
...
>>> foo()
Hello,World!```

```>>> def multiplier(factor):
...     def multiplyByFactor(number):
...         return number*factor
...     return multiplyByFactor
...
>>> double = multiplier(2)
>>> double(5)
10
>>> triple = multiplier(3)
>>> triple(3)
9
>>> multiplier(5)(4)
20```
#再来看一个
```>>> def A(x):
def B(y):
def C(z):
return x+y+z
return C
return B
>>> A(1)(2)(3)
6
```

------

```>>>def A():
return A()
>>>A() #无限循环，等消耗掉所有内存资源后，报最大递归深度的错误，类似于while True
File "", line 2, in A
return A()
RuntimeError: maximum recursion depth exceeded```
#break,return合并使用，避免无限循环

#每次函数调用时，生成新的命名空间，意味着当函数调用自身，会有两个函数同时运行。

n*(n-1)*(n-2)...2*1,可以用普通函数来实现

```>>> def factorial(n):
result = n
for i in range(1,n):
result *=i
return result

>>> factorial(3)
6```

```>>> def factorial(n):
if n == 1:   #1的阶乘为1
return 1
else:        #大于1的阶乘是n*(n-1)!
return n*factorial(n-1)```

```>>> def power(x,n):  #一般的实现
result = 1
for i in range(n):
result *=x
return result
>>> power(2,3)
8```
```>>> def power(x,n):  #阶乘实现
if n == 0:
return 1
else:
return x*power(x,n-1)
>>> power(2,3)
8```
------

map(func,seq[,seq,]) 对序列中的每个元素应用函数

filter(func,seq) 返回其函数为真的元素的列表

reduce(func,seq[,initial]) 等同于func(func(func(seq[0],seq[1],seq[2],...)))

sum(seq) 返回seq中所有元素的和

apply(func[,args[,kwargs]]) 调用函数，可以提供参数

------

------