Python基础教程之第6章 抽象
来源:互联网 发布:js frame 编辑:程序博客网 时间:2024/04/29 03:34
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32Type "copyright", "credits" or "license()" for more information.#6.1 懒惰即美德>>> fibs = [0,1]>>> for i in range(8):fibs.append(fibs[-2]+fibs[-1])>>> fibs[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]# 你甚至可以将用户输入的数字作为动态范围的长度使用, 从而改变for语句块循环的次数fibs=[0,1]num = input('How many Fibonacci numbers do you want? ')for i in range(num-2):fibs.append(fibs[-2] + fibs[-1])print fibsdef fibs(num):result = [0,1]for i in range(num-2):result.append(result[-2] + result[-1])return resultprint fibs(10)print fibs(15)#[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]#[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]#6.2 抽象和结构#page = download_page()#freqs = compute_frequencies(page)#for word,freq in freqs:#print word,freq#6.3 创建函数>>> import math>>> x=1>>> y=math.sqrt>>> callable(x)False>>> callable(y)True>>> del hello(name):SyntaxError: invalid syntax>>> def hello(name):return 'Hello, ' + name + '!'>>> print hello('world')Hello, world!>>> print hello('Jonathan')Hello, Jonathan!>>> 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]>>> fibs(15)[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]#6.3.1 给函数写文档>>> def square(x):... 'Calculates the square of the number x.'... return x*x...>>> square.__doc__'Calculates the square of the number x.'>>> help(square)Help on function square in module __main__:square(x) Calculates the square of the number x.#6.3.1 Python的有些函数并不返回任何东西(其实返回None)>>> def test():... print 'This is printed'... return... print 'This is not'...>>>>>> x=test()This is printed>>> x>>> print xNone#6.4.1 值从哪里来#6.4.2 我能改变参数吗#参数只是变量而已. 在函数内为参数赋值不会改变外部任何变量的值#参数存储在局部作用域(local scope)内#字符串(以及数字和元组)是不可变的, 即无法被修改(也就是说只能用心的值覆盖).#但考虑一下如果将可变的数据结构如列表用作参数时会发生什么>>> def try_to_change(n):... n = 'Mr. Gumby'...>>> name = 'Mrs. Entity'>>> try_to_change(name)>>> name'Mrs. Entity'>>>>>> name='Mrs. Entity'>>> n = name #这句的作用基本上等于传参数>>> n = 'Mr. Gumby' # 在函数内部完成的>>> name'Mrs. Entity'>>> def change(n):... n[0] = 'Mr. Gumby'...>>> names = ['Mrs. Entity', 'Mrs. Thing']>>> change(names)>>> names['Mr. Gumby', 'Mrs. Thing']>>>>>> names = 'Mrs. Entity', 'Mrs. Thing'] File "<stdin>", line 1 names = 'Mrs. Entity', 'Mrs. Thing'] ^SyntaxError: invalid syntax>>> names = ['Mrs. Entity', 'Mrs. Thing']>>> n = names # 再来一次, 模拟传参行为>>> n[0] = 'Mr. Gumby' # 改变列表内容>>> names['Mr. Gumby', 'Mrs. Thing']>>>>>> names = ['Mrs. Entity','Mrs. Thing']>>> n = names[:]>>> n is namesFalse>>> n is not namesTrue>>> n == namesTrue>>> n === names File "<stdin>", line 1 n === names ^SyntaxError: invalid syntax>>> n[0]='Mr. Gumby'>>> n['Mr. Gumby', 'Mrs. Thing']>>> names['Mrs. Entity', 'Mrs. Thing']>>> change(names[:])>>> names['Mrs. Entity', 'Mrs. Thing']# 为什么我想要修改参数>>> storage={}>>> storage['first']={}>>> storage['middle']={}>>> storage['last']={}>>> me = 'Magnus Lie Hetland'>>> storage['first']['Magnus']=[me]>>> storage['middle']['Lie']=[me]>>> storage['last']['Hetland']=[me]>>> storage['middle']['Lie']['Magnus Lie Hetland']>>>>>> my_sister='Anne Lie Hetland'>>> storage['first'].setdefault('Anne', []).append(my_syster)Traceback (most recent call last): File "<stdin>", line 1, in <module>NameError: name 'my_syster' is not defined>>> storage['first'].setdefault('Anne', []).append(my_sister)>>> storage['middle'].setdefault('Lie', []).append(my_sister)>>> storage['last'].setdefault('Hetland', []).append(my_sister)>>> storage['first']['Anne']['Anne Lie Hetland']>>> storage['middle']['Lie']['Magnus Lie Hetland', 'Anne Lie Hetland']>>>>>> def init(data):... data['first']={}... data['middle']={}... data['last']={}...>>> storage = {}>>> init(storage)>>> storage{'middle': {}, 'last': {}, 'first': {}}>>>>>> def lookup(data, label, name):... return data[lable].get(name)...>>> lookup(storage, 'middle', 'Lie')Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in lookupNameError: global name 'lable' is not defined>>> def lookup(data, label, name):... return data[label].get(name)...>>> lookup(storage, 'middle', 'Lie')>>> print lookup(storage, 'middle', 'Lie')None>>> def store(data, full_name):... names = full_name.split()... if len(names) == 2: names.insert(1, '')... labels = 'first', 'middle', 'last'... for label, name in zip(labels, names) File "<stdin>", line 5 for label, name in zip(labels, names) ^SyntaxError: invalid syntax>>> def store(data, full_name):... names = full_name.split()... if len(names) == 2: names.insert(1, '')... labels = 'first', 'middle', 'last'... for label, name in zip(labels, names):... people = lookup(data, label, name)... if people:... people.append(full_name)... else:... data[label][name] = [full_name]...>>> MyNames = {}>>> init(MyNames)>>> store(MyNames, 'Magnus Lie Hetland')>>> lookup(MyNames, 'middle', 'Lie')['Magnus Lie Hetland']>>>>>> store(MyNames, 'Robin Hood')>>> store(MyNames, 'Robin Locksley')>>> lookup(MyNames, 'first', 'Robin')['Robin Hood', 'Robin Locksley']>>> store(MyNames, 'Mr. Gumby')>>> lookup(MyNames, 'middle, '') File "<stdin>", line 1 lookup(MyNames, 'middle, '') ^SyntaxError: EOL while scanning string literal>>> lookup(MyNames, 'middle','')['Robin Hood', 'Robin Locksley', 'Mr. Gumby']>>> def inc(x): return x+1...# 如果我的参数不可变呢# 这个时候你应该从函数中返回所有你需要的值(如果值多于一个就以元组形式返回)>>> foo = 10>>> foo = inc(foo)>>> foo11# 如果真的想改变参数, 那么可以使用一点小技巧, 即将值放置在列表中>>> def inc(x): x[0] = x[0] + 1...>>> foo = [10]>>> inc(foo)>>> foo[11]#6.4.3 位置参数, 关键字参数 和 默认值>>>>>> def hello_1(greeting, name):... print '%s, $s!' % (greeting, name)...>>> def hello_2(name, greeting):... print '%s, %s!' % (name, greeting)...>>> hello_1('Hello','world')Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in hello_1TypeError: not all arguments converted during string formatting>>> def hello_1(greeting, name):... print '%s, %s!' % (greeting, name)...>>> hello_1('Hello','world')Hello, world!>>> hello_2('Hello','world')Hello, world!>>> hello_1(greeting='Hello', name='world')Hello, world!>>> hello_1(name='world',greeting='Hello')Hello, world!>>> hello_2(name='world',greeting='Hello')world, Hello!>>> # store('Mr. Brainsample', 10, 20, 13, 5)...>>> # store(patient='Mr. Brainsample', hour=10, minute=20, day=13, month=5)...>>> def hello_3(greeting='Hello', name='world'):... print '%s, %s!' % (greeting, name)...>>> hello_3()Hello, world!>>> hello_3('Greetings')Greetings, world!>>> hello_3('Greetings', 'universe')Greetings, universe!>>> hello_3(name='Gumby')Hello, Gumby!>>>>>> def hello_4(name, greeting='Hello', punctuation='!'):... print '%s, %s%s' % (greeting, name, punctuation)...>>> hello_4('Mars) File "<stdin>", line 1 hello_4('Mars) ^SyntaxError: EOL while scanning string literal>>> hello_4('Mars')Hello, Mars!>>> hello_4('Mars', 'Howdy')Howdy, Mars!>>> hello_4('Mars', 'Howdy', '...')Howdy, Mars...>>> hello_4('Mars','...')..., Mars!>>> hello_4('Mars', punctuation = '...')Hello, Mars...>>> hello_4('Mars', punctuation = '.')Hello, Mars.>>> hello_4('Mars', greeting='Top of the morning to ya')Top of the morning to ya, Mars!>>> hello_4()Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: hello_4() takes at least 1 argument (0 given)#6.4.4 收集参数>>> # store(data, name1, name2, name3)...>>> def print_params(*params):... print params...>>> print_params('Testing')('Testing',)>>> print_params(1,2,3)(1, 2, 3)>>> def print_params_2(title, *params) File "<stdin>", line 1 def print_params_2(title, *params) ^SyntaxError: invalid syntax>>> def print_params_2(title, *params):... print title... print params...>>> print_params('Params:', 1,2,3)('Params:', 1, 2, 3)>>> print_params_2('Params:', 1,2,3)Params:(1, 2, 3)>>> print_params_2('Nothing')Nothing()>>> print_params_2('Nothing:')Nothing:()>>> print_params_2('Hmm...', something=42)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: print_params_2() got an unexpected keyword argument 'something'>>> def print_params_3(**params):... print params...>>> print_params_3(x=1, y=2, z=3){'y': 2, 'x': 1, 'z': 3}>>> def print_params_4(x, y, z=3, *pospar, **keypar):... print x,y,z... print pospar... print keypar...>>> print_params_4(1,2,3,5,6,7,foo=1,bar=2)1 2 3(5, 6, 7){'foo': 1, 'bar': 2}>>> print_params_4(1,2)1 2 3(){}>>> def store(data, *full_names); File "<stdin>", line 1 def store(data, *full_names); ^SyntaxError: invalid syntax>>> def store(data, *full_names):... for full_name in full_names:... names = full_name.split()... if len(names) == 2: names.insert(1,'')... labels = 'first', 'middle', 'last'... for label, name in zip(labels, names):... people = lookup(data, label, name)... if people:... people.append(full_name)... else:... data[label][name] = [full_name]...>>> d = {}>>> init(d)>>> store(d, 'Han Solo')>>> store(d, 'Luke Skywalker', 'Anakin Skywalker')>>> lookup(d, 'last', 'Skywalker')['Luke Skywalker', 'Anakin Skywalker']#6.4.5 反转过程#如何将参数收集为 元组 和 字典 已经讨论过了, 但是事实上, 如果使用 * 和 **的话, 也可以执行相反的操作. 那么参数收集的逆过程是什么样的?>>> def add(x,y): return x+y...>>> params = (1,2)>>> add(*params)3>>> params = {'name':'Sir Robin', 'greeting':'Well met'}>>> def hello_3(greeting='Hello', name='world'):... print '%s, %s!' % (greeting, name)...>>> hello_3(**params)Well met, Sir Robin!>>> def with_stars(**kwds):... print kwds['name'], 'is', kwds['age'], 'years old'...>>> def without_stars(kwds):... print kwds['name'], 'is', kwds['age'], 'years old'...>>> args={'name':'Mr. Gumby', 'age':42}>>> with_stars(**args)Mr. Gumby is 42 years old>>> without_stars(args)Mr. Gumby is 42 years old>>>>>> def foo(x,y,z,m=0,n=0):... print x,y,z,m,n... def call_foo(*args, **kwds): File "<stdin>", line 3 def call_foo(*args, **kwds): ^SyntaxError: invalid syntax>>> def call_foo(*args, **kwds):... print 'Calling too!'... foo(*args, **kwds)...#6.4.6 练习使用参数#coding=utf-8def story(**kwds):return 'Once upon a time, there was a ' \'%(job)s called %(name)s. ' % kwdsdef power(x, y, *others):if others:print 'Received redundant parameters: ', othersreturn pow(x,y)def interval(start, stop=None, step=1):'Imatates range() for step > 0'if stop is None:#如果没有为stop提供值start,stop = 0,start #指定参数, 连锁赋值result = []i = start#计算start索引while i < stop:#直到计算到stop的索引result.append(i)#将索引添加到result内...i += step#用step(>0)增加索引i...return resultprint story(job='king', name='Gumby')print story(name='Sir Robin', job='brave knight')params = {'job':'language', 'name':'Python'}print story(**params)del params['job']print story(job='stroke of genius', **params)print power(2,3)print power(3,2)print power(y=3,x=2)params = (5,) * 2print power(*params)print power(3, 3, 'Hello, world')print interval(10)print interval(1, 5)print interval(3,12,4)print power(*interval(3,7))#Once upon a time, there was a king called Gumby.#Once upon a time, there was a brave knight called Sir Robin.#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#Received redundant parameters: ('Hello, world',)#27#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]#[1, 2, 3, 4]#[3, 7, 11]#Received redundant parameters: (5, 6)#81#6.5 作用域#到底什么是变量? 你可以把它们看做是值的名字. 当然, 变量和所对应的值所用的是个"不可见"的字典. 内建的vars()函数可以返回这个字典>>> x=1>>> scope=vars()>>> scope['x']1>>> scope['x'] += 1>>> x2>>> def foo(): x=42...>>> x=1>>> foo()>>> x1>>> def output(x): print x...>>> x=1>>> y=2>>> output(y)2>>> def combine(parameter): print parameter + external...>>> external = 'berry'>>> combine('Shrub')Shrubberry>>># 屏蔽(Shadowing)的问题>>> def combine(parameter):... print parameter + globals()['parameter']...>>> parameter='berry'>>> combine('straw')strawberry>>>>>> x=1>>> def change_global():... global x... x += 1...>>> change_global()>>> x2# 嵌套作用域# Python的函数是可以嵌套的.>>> def foo():... def bar():... print "Hello, world!"... bar()...>>> 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#6.6 递归# 有用的递归函数包含以下几部分:# 1) 当函数直接返回值时有 基本实例 (最小可能性问题);# 2) 递归实例, 包括一个或多个问题最小部分的递归调用.#6.6.1 两个经典: 阶乘 和 幂次运算>>> def recursion():... return recursion()...>>> def factorial(n):... result = n... for i in range(1,n):... result *= i... return result...>>> factorial(10)3628800>>> def factorial(n):... if n==1:... return 1... else:... return n * factorial(n-1)...>>> factorial(10)3628800>>> def power(x,n):... result = 1... for i in range(n):... result *= x... return result...>>> def power(x,n):... if n==0:... return 1... else:... return x * power(x, n-1)...>>> power(2,3)8>>># 6.6.2 另外一个经典: 二元查找# 提示: 标准库中的bisect模块可以非常有效地实现二元查找def search(sequence, number, lower=0, upper=None):if upper is None: upper = len(sequence)-1if lower == upper:assert number == sequence[upper]return upperelse:middle = (lower + upper) // 2if number > sequence[middle]:return search(sequence, number, middle+1, upper)else:return search(sequence, number, lower, middle)seq = [4, 8, 34, 67, 95, 100, 123]seq.sort()print search(seq, 34)#2print search(seq, 100)#5# Python在应对这类"函数式编程"方面, 有一些有用的函数: map, filter 和 reduce 函数(Python3.1中这些都被移到functools模块中)# map和filter函数可以使用 列表推导式 代替>>> [str(i) for i in range(10)]['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']>>> map(str, range(10))['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']>>> seq = ["foo", "x41", "?!", "***"]>>> def func(x):... return x.isalnum()...>>> filter(func, seq)['foo', 'x41']>>> [x for x in seq if x.isalnum()]['foo', 'x41']>>> filter(lambda x: x.isalnum(), seq)['foo', 'x41']>>> numbers = [72,101,108,108,111,44,32,119,111,114,108,100,33]>>> reduce(lambda x, y: x+y, numbers)1161sum(numbers)1161>>> sum=0>>> for i in numbers:... sum += i...>>> sum1161#6.7 小结: 关于抽象的常识以及函数的特殊知识# 抽象:抽象是隐藏多余细节的艺术. 定义处理细节的函数可以让程序更抽象# 函数定义: 函数使用def语句定义.# 参数: 位置参数 和 关键字参数. 参数在给定默认值时是可选的# 作用域: 变量存储在作用域(也叫做 命名空间). 全局作用域 和 局部作用域. 作用域可以嵌套.# 递归: 函数可以调用自身. 一切用递归实现的功能都可以用循环实现, 但有时递归函数更易读.# 函数式编程: 包括lambda表达式, 以及map, filter 和 reduce函数#6.7.1 新函数#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]])调用函数, 可以提供函数
0 0
- Python基础教程之第6章 抽象
- Python基础教程之第7章 更加抽象
- 《Python基础教程》读书笔记(1)之第6章抽象(关键词:Python/抽象/函数/参数/作用域)
- Python基础教程(6)抽象
- <<Python基础教程>>学习笔记 | 第06章 | 抽象
- <<Python基础教程>>学习笔记 | 第07章 | 更加抽象
- 《Python基础教程》读书笔记(2)之第7章更加抽象(关键词:Python/面向对象/多态/封装/方法/继承)
- Python基础教程之第1章 基础知识
- Python基础教程之第8章 异常
- 【Python基础教程】第6章 函数
- Python基础教程第4-6章笔记
- 【书山有路】Python基础教程 第6章
- python 第6章抽象
- Python基础教程之第2章 列表和元组
- Python基础教程之第3章 使用字符串
- 【Python基础教程】第5章
- python基础教程第9章
- python 基础教程第21章
- Java线程面试题 Top 50
- Windows下手动完全卸载Oracle
- [ExtJS5学习笔记]第十一节 Extjs5MVVM模式下系统登录实例
- Python基础教程之第5章 条件, 循环和其他语句
- 垃圾收集,火车算法
- Python基础教程之第6章 抽象
- Linux setitimer()函数实现单个定时器
- Python基础教程之第7章 更加抽象
- android 主线程和子线程交互方式
- C++ GUI QT4编程——拖放
- Python基础教程之第8章 异常
- 微机接口习题
- 如何获取androi手机中的歌曲信息
- Python基础教程之第9章 魔法方法, 属性和迭代器