Python快速学习第五天

第五天:抽象

1、    函数

检测函数是否可调用:callable

>>> import math

>>> y=math.sqrt

>>> callable(y)

True

>>> x=1

>>> callable(x)

False

   注意:Python3.0不在支持callable,需要使用表达式hasattr(func,_call_call_)代替

   创建函数:def functionname(params):

>>>def fibs(num):

...     ‘Get fibonaqi sequnce! ‘

...     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]

用于def后面的‘Getfibonaqi sequnce! ‘添加文档字符串,相当于注释#,使用help()可以查询函数的文档字符串

help(fibs)

Help on function fibs in module __main__:

fibs(num)

Getfibonaqi sequnce!

...skipping...

Help on function fibs in module __main__:

fibs(num)

Getfibonaqi sequnce!

return后不加值,只表示函数的结束,而没有返回值,这样可以避免应该返回序列时,意外返回None

>>> def test():

...     print ‘tanggao‘

...     return

...     print ‘tanggao isgood‘

...

>>> x=test()

tanggao

>>> print x

None

2、   参数对外部变量影响

函数内给参数赋值,不会改变外部变量的值,参数存储在局部作用域中

>>> def try_to_change(n):

...     n=3

...

>>> t=4

>>> try_to_change(t)#虽然在函数内部重新赋值,但外部不变

>>> t

4

但是对于可改变的数据结构,如列表,参数的内部赋值会改变外部变量的值

内部参数与外部变量指向同一个列表,所以会被修改

若不想改变外部列表,可以传进一个副本

>>> def change(n):

...    n[0]=‘tanggao‘

...

>>> names=[‘hello‘,‘world‘]

>>> change(names)

>>> names

[‘tanggao‘, ‘world‘]

>>>  #采用普通方法进行模拟

...

>>> names=[‘hello‘,‘world‘]

>>> n=names

>>> n[0]=‘tanggao‘

>>> names

[‘tanggao‘, ‘world‘]

完整示例——存储名字,并能用名字、中间名或姓来查找联系人

若名字为‘MagusLie Hetland‘存储格式类似

data = {

‘first‘:{ ‘Magus‘: ‘Magus Lie Hetland‘},

‘middle‘:{‘Lie‘: ‘Magus Lie Hetland‘},

‘last‘:{‘Hetland‘: ‘Magus Lie Hetland‘}

}

注意insert(index,value)函数,在列表的索引位置插入值

Python代码  

1.  >>> def init(data):  #data作为存储表,初始化

2.      data[‘first‘] = {}

3.      data[‘middle‘] = {}

4.      data[‘last‘] = {}

5.

6.  >>> def store(data, full_name): #存储,将全名存储到表中

7.      names = full_name.split()  #将名字按空格(即first,middle,last)分开,返回列表,如‘Ma Li He‘返回[‘Ma‘, ‘Li‘, ‘He‘]

8.      if len(names) == 2: names.insert(1, ‘‘)#若无中间名,则插入空来表示中间名[‘Mr‘, ‘Zha‘]返回[‘Mr‘, ‘‘, ‘Zha‘]

9.      labels = ‘first‘, ‘middle‘, ‘last‘  #元组

10.     for label, name in zip(labels, names):  #元组与序列间也可使用zip

11.         people = lookup(data, label, name)

12.         if people:

13.             people.append(full_name)

14.         else:

15.             data[label][name] = [full_name] #当键不存在时,自动添加键值对,

16.                                                                          #但如果输出不存在键对应值,则报错

17.

18. >>> def lookup(data, label, name): #查找,根据label查找是name的中间人

19.     return data[label].get(name)

20.

21.

22. >>> MyNames = {}

23. >>> init(MyNames)

24. >>> store(MyNames, ‘Magnus Lie Hetland‘)

25. >>> lookup(MyNames, ‘middle‘, ‘Lie‘)

26. [‘Magnus Lie Hetland‘]

27. >>> store(MyNames, ‘Robin Hood‘)

28. >>> store(MyNames, ‘Robin Locksley‘)

29. >>> lookup(MyNames, ‘first‘, ‘Robin‘)

30. [‘Robin Hood‘, ‘Robin Locksley‘]

31. >>> store(MyNames, ‘Mr. Gumby‘)

32. >>> lookup(MyNames, ‘middle‘, ‘‘)

33. [‘Robin Hood‘, ‘Robin Locksley‘, ‘Mr. Gumby‘]

例2. 不可变的数字和可改变的参数

Python代码  

1.  >>> def inc(x): return x + 1

2.

3.  >>> foo = 10

4.  >>> inc(foo)

5.  11

6.  >>> foo #外部变量未发生变化

7.  10

8.  >>> foo = inc(foo) #将foo重新赋值

9.  >>> foo

10. 11

使用列表外部变量foo改变了

Python代码  

1.  >>> def inc(x): x[0] = x[0] + 1

2.

3.  >>> foo = [10]

4.  >>> inc(foo)

5.  >>> foo

6.  [11]

3. 关键字参数和默认值

位置:是指根据参数的对应位置传参,如def a(a,b,c):,调用a(1,2,3),1传给a,2传给b,3传给c,这样参数位置容易记混。

关键字参数,适用于大规模程序,清晰

Python代码  

1.  >>> def hello(name, greeting):

2.      print ‘%s, %s!‘ %(greeting, name)

3.

4.

5.  >>> hello(‘sun‘, ‘Hello‘)  #位置参数

6.  Hello, sun!

7.  >>> hello(name = ‘Sun‘, greeting = ‘Hello‘)  #关键字参数

8.  Hello, Sun!

9.  >>> hello(greeting = ‘Hello‘, name = ‘Sun‘) #关键字参数,不必关心位置

10. Hello, Sun!

默认值

Python代码  

1.  >>> def hello(name = ‘world‘, greeting = ‘Hello‘):

2.      print ‘%s, %s!‘ %(greeting, name)

3.

4.

5.  >>> hello()

6.  Hello, world!

7.  >>> hello(‘Sun‘)

8.  Hello, Sun!

9.  >>> hello(greeting = ‘Hi‘)

10. Hi, world!

位置参数与关键字参数混用,将位置参数放在前面。尽量避免这么用,容易引起混乱。

Python代码  

1.  >>> def hello(name, greeting = ‘Hello‘, punc = ‘!‘):

2.      print ‘%s, %s%s‘ %(greeting, name, punc)

3.

4.

5.  >>> hello(‘Sun‘)

6.  Hello, Sun!

7.  >>> hello(‘Sun‘, ‘Hi‘)

8.  Hi, Sun!

9.  >>> hello(‘Sun‘, punc = ‘..‘)

10. Hello, Sun..

11. >>> hello()   #因为name是必须要有,若有默认值,则可没有

12.

13. Traceback (most recent call last):

14.   File "<pyshell#385>", line 1, in <module>

15.     hello()

16. TypeError: hello() takes at least 1 argument (0 given)

17. >>>

4. 收集参数——在定义时使用*或**,用来收集参数,允许使用不定数量的参数

*:收集其余的位置参数并作为元组 返回

Python代码  

1.  >>> def print_params2(title, *params):

2.      print title

3.      print params

4.

5.

6.  >>> print_params2(‘Param:‘, 1, 2, 3)

7.  Param:

8.  (1, 2, 3)  #以元组形式返回

9.  >>> print_params2(‘Param:‘) #不提供收集元素时,返回空元组

10. Param:

11. ()

12. >>> print_params2(‘Param:‘, 1)

13. Param:

14. (1,) #只有一个元素时,仍为元组

**:收集其余的关键字参数并作为字典 返回,可与其他混用

Python代码  

1.  >>> def print_params3(x, y, z = 3, *pospar, **keypar):

2.      print x, y, z

3.      print pospar

4.      print keypar

5.

6.

7.  >>> print_params3(1,2,3,4,5,6,7, fool = 1, bar = 2)

8.  1 2 3

9.  (4, 5, 6, 7)

10. {‘fool‘: 1, ‘bar‘: 2}

11. >>> print_params3(1,2)

12. 1 2 3

13. ()

14. {}

5. 收集参数的翻转过程——在调用时使用*或**,将参数分配到定义的参数中,用于字典或列表分割时

用于列表

Python代码  

1.  >>> def add(x,y): return x + y

2.

3.  >>> params = (1,2)

4.  >>> add(*params)

5.  3

用于字典

Python代码  

1.  >>> def hello(name, greeting):

2.      print ‘%s, %s!‘ %(greeting, name)

3.

4.

5.  >>> params = {‘name‘: ‘Sir Robin‘, ‘greeting‘: ‘Welcome‘}

6.  >>> hello(**params)

7.  Welcome, Sir Robin!

8.

9.

参数使用实例

Python代码  

1.  #模拟步长大于0的range()

2.  >>> interval(10)

3.  start = 0 stop = 10 step =  1

4.  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

5.  >>> def interval(start, stop=None, step=1):

6.      ‘Imitates range() for step > 0‘

7.      if stop is None: #若未给stop指定值

8.          start, stop = 0, start #多个赋值,0赋值给start,start的值赋值给stop

9.      result = []

10.     i = start

11.     while i < stop:

12.         result.append(i)

13.         i += step

14.     return result

15.

16. #

17. >>> def story(**kwds):

18.     return ‘%(job)s called %(name)s.‘ %kwds

19.

20. >>> def power(x, y ,*others):

21.     if others:

22.         print ‘Received redundant parameters:‘,others

23.     return pow(x,y)

24.

25. #使用

26. >>> params = {‘job‘:‘language‘,‘name‘:‘python‘}

27. >>> print story(**params) #调用时分割字典,定义中收集

28. language called python.

29. >>> del params[‘job‘]

30. >>> print story(job=‘test‘, **params)

31.

32. >>> power(2,3,‘test‘)

33. Received redundant parameters: test

34.

35. >>> params = (5,) * 2 #即(5,5)

36. >>> power(*params) #先分割,在赋给x,y

37. 3125

6.作用域

x = 1, 将名字x引用到值1上,类似字典

内建函数vars()返回这个字典

Python代码  

1.  >>> x = 1

2.  >>> scope = vars()

3.  >>> scope[‘x‘]

4.  1

5.  >>> scope[‘x‘] += 1 #一般情况下,vars()返回的字典不能修改

6.  >>> x

7.  2

局部变量,全局变量

函数内部访问全局变量,慎用!

Python代码  

1.  >>> def com(para): print para + external

2.

3.  >>> external = ‘external‘

4.  >>> com(‘param ‘)

5.  param external

若全局变量与局部变量名字相同,会被局部变量覆盖,可使用global()类似vars(),获得全局变量的字典

Python代码  

1.  >>> def com(para): print para + globals()[‘para‘]

2.

3.  >>> para = ‘berry‘

4.  >>> com(‘test ‘)

5.  test berry

重绑定全局变量,将变量引用到其他新值——函数内部声明全局变量

Python代码  

1.  >>> x = 1

2.  >>> def change_global():

3.      global x

4.      x = x + 1

5.

6.

7.  >>> change_global()

8.  >>> x

9.  2

嵌套作用域——函数中定义函数,例如闭包

外部作用域中的变量一般不能被改变,但是用闭包,每次调用外层函数,内部函数都会被重新绑定,也即外部作用域factor每次都有一个新值

Python代码  

1.  >>> def multiplier(factor):

2.      def multiplyByFactor(number):

3.          return number * factor

4.      return multiplyByFactor  #返回一个函数,这时并未调用

5.

6.  >>> double = multiplier(2)  #double是一个函数

7.  >>> double   #double是一个函数

8.  <function multiplyByFactor at 0x0214C6F0>

9.  >>> double(5)  #调用multiplyByFactor(number)

10. 10

11. >>> multiplier(2)(5) #效果同上

12. 10

7. 递归——每调用一个函数,都会创建一个新的命名空间,意味着当函数调用自身时,实际上调用的是两个不同的函数

阶乘

Python代码  

1.  >>> def factorial(n):

2.      if n == 1:

3.          return 1

4.      else:

5.          return n * factorial(n-1)

6.

7.  >>> factorial(5)

8.  120

Python代码  

1.  >>> def power(x, n):

2.      if n == 0:

3.          return 1

4.      else:

5.          return x * power(x, n - 1)

6.

7.

8.  >>> power(2,3)

9.  8

递归实例——二元搜索

前提:排好序

若上下限相同,则那就是数字所在位置,返回;

否则,找到两者的中间,查找数字是在左侧还是右侧,继续查找数字所在的那半部分。

Python代码  

1.  >>> def search(sequence, number, lower = 0, upper = None):

2.      if upper is None: upper = len(sequence) - 1

3.      if lower == upper:

4.          assert number == sequence[upper]

5.          return upper

6.      else:

7.          middle = (lower + upper) // 2

8.          if number > sequence[middle]:

9.              return search(sequence, number, middle + 1, upper)

10.         else:

11.             return search(sequence, number, lower, middle)

12.

13.

14. >>> seq = [34, 67, 8, 123, 4, 100, 95]

15. >>> seq.sort()

16. >>> seq

17. [4, 8, 34, 67, 95, 100, 123]

18. >>> search(seq, 34)

19. 2

总结:

元组输出格式化,直接使用键,而不需要加引号

Python代码  

1.  >>> d = {‘a‘:1, ‘b‘:2}

2.  >>> print ‘%(a)s corresponds to %(b)s.‘ %d #注意a有括号,无引号

3.  1 corresponds to 2.

时间: 2024-08-07 16:38:25

Python快速学习第五天的相关文章

60分钟Python快速学习(转)

60分钟Python快速学习(给发哥一个交代) 阅读目录 第一步:开发环境搭建: 第一个Python功能:初识Python 02.Python中定义变量不需要数据类型 03.在Pythod中定义方法 04.在Python中书写自己的类 60分钟Python快速学习 之前和同事谈到Python,每次下班后跑步都是在听他说,例如Python属于“胶水语言啦”,属于“解释型语言啦!”,是“面向对象的语言啦!”,另外没有数据类型,逻辑全靠空格缩进表示等. 今天自己用了60分钟快速学习了下Python的语

Python快速学习09: 函数的参数

前言 系列文章:[传送门] 继续干起来!! 正文 我们已经接触过函数,函数是可以被引用的(访问或者以其他变量作为其别名),也作为参数传入函数,以及作为列表和字典等等容器对象的元素(function)的参数(arguments)传递. 传递函数 形式参数       位置参数 默认参数 关键字变量参数 位置传递 例子: def f(a,b,c): return a+b+c print(f(1,2,3)) #在调用f时,1,2,3根据位置分别传递给了a,b,c. 形式参数 关键字传递 用位置传递会感

60分钟Python快速学习(给发哥一个交代)

60分钟Python快速学习 之前和同事谈到Python,每次下班后跑步都是在听他说,例如Python属于“胶水语言啦”,属于“解释型语言啦!”,是“面向对象的语言啦!”,另外没有数据类型,逻辑全靠空格缩进表示等. 今天自己用了60分钟快速学习了下Python的语法.和大家分享下,也算是自己这一个小时的学习总结吧! 第一步:开发环境搭建: PyCharm 4.5.4 下载地址:http://www.jetbrains.com/pycharm/download/ 支持多种类型的操作系统,我这次是在

Python快速学习10: 循环的对象及设计 (生活的规律)

前言 系列文章:[传送门] 生活逐渐规律,按时睡觉.今天写博客,明天补时间看会书.慢慢的时间很珍惜 我很喜欢! 时钟就像个循环体,我们将它融入生活. 正文 循环对象的并不是随着Python的诞生就存在的,但它的发展迅速,特别是Python 3x的时代,循环对象正在成为循环的标准形式. 灵活的循环方式 (我晚饭后爱上了萨克斯,因为这是生活的一部分.属于我的特殊循环对象,它的按键就像循环方式,然后出来一首美丽的歌曲) 我的萨克斯偶像 循环对象 循环对象是这样一个对象,它包含有一个next()方法(_

Python入门学习第五周:字符串·作业

python学习第五周字符串相关学习内容总结与作业 第五周主要是对字符串相关操作的学习包括 字符串的定义字符的序列 基本字符运算 求长度len(str)函数 拼接+str = str1 + 'pinjie' 重复*name * 3 就是把name的字符串内容输出三次 成员运算in判断一个字符串是否是另一个字符串的子串 for语句 枚举字符串中的每个字符 字符串索引每个字符串都有一个索引值索引从0前向或-1后向开始索引运算符[] 切片操作选择字符串的子序列语法 [start : finish] s

python dlib学习(五):比对人脸

前言在前面的博客中介绍了,如何使用dlib标定人脸(python dlib学习(一):人脸检测),提取68个特征点(python dlib学习(二):人脸特征点标定).这次要在这两个工作的基础之上,将人脸的信息提取成一个128维的向量空间.在这个向量空间上,同一个人脸的更接近,不同人脸的距离更远.度量采用欧式距离,欧氏距离计算不算复杂.二维情况下:distance=(x1−x2)2+(y1−y2)2−−−−−−−−−−−−−−−−−−√distance=(x1−x2)2+(y1−y2)2 三维情

Python个人学习笔记五

                                    本节主要学习Python语言的文件处理相关知识 一 第一种python有一系列API默认直接可以引用的函数,这里文件读取函数open在下列表 The Python interpreter has a number of functions and types built into it that are always available. They are listed here in alphabetical order.

Python快速学习第七天

魔法方法.属性和迭代器 本文内容全部出自<Python基础教程>第二版 在Python中,有的名称会在前面和后面都加上两个下划线,这种写法很特别.前面几章中已经出现过一些这样的名称(如__future__),这种拼写表示名字有特殊含义,所以绝不要在自己的程序中使用这样的名字.在Python中,由这些名字组成的集合所包含的方法称为魔法(或特殊)方法.如果对象实现了这些方法中的某一个,那么这个方法会在特殊的情况下(确切地说是根据名字)被Python调用.而几乎没有直接调用它们的必要. 本章会详细讨

Python快速学习第八天

本文内容全部出自<Python基础教程>第二版 10.1 模块 现在你已经知道如何创建和执行自己的程序(或脚本)了,也学会了怎么用import从外部模块获取函数并且为自己的程序所用: >>> import math >>> math.sin(0) 0.0 让我们来看看怎样编写自己的模块. 10.1.1 模块是程序 任何Python程序都可以作为模块导入.假设你写了一个代码清单10-1所示的程序,并且将它保存为hello.py文件(名字很重要). 代码清单10