《转》Python学习(17)-python函数基础部分
http://www.cnblogs.com/BeginMan/p/3171977.html
一、什么是函数、方法、过程
推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html
一般程序设计语言包含两种基本的抽象:过程抽象和数据抽象。过程抽象有时也称控制抽象。
子程序在1950年以前就发明了,作为一种抽象那时候并未被完全接受。相反,最初它被看做是一种节省代码的机制,但很快子程序就被认可为过程抽象的一种方式。意识到子程序可以作为一种抽象机制,这产生了三个重要结果。
- 人们发明了一些语言,支持各种参数传递机制
- 奠定了「结构化程序设计」的基础,语言开始支持嵌套的子程序(如JS的function,Java的inner class)
- 诞生了「结构化程序设计」,为试图构建大型系统提供了指导,利用子程序作为基本构建块
子程序是最主要过程抽象机制。面向对象语言中的方法与子程序的概念十分相似,不同在于它们的调用以及它们与类或对象关联的方式。
二、Python函数基础
1、基础一:
函数是对程序逻辑进行结构化和过程化的一种编程方式。
过程是简单、特殊、没有返回值的函数
从后面的内容可知Python的过程就是函数,因为解释器会隐式的返回默认值None
2、基础二:
2.1、关于没有返回值:
如果什么也不返回的话,在C中默认的是void返回类型,而在Python中是none返回类型。
- >>> def hello():
- print 'hello world'
- >>> res = hello()
- hello world
- >>> print res
- None
- >>> type(res)
- <type 'NoneType'>
- >>>
2.2、关于有返回值:
函数的返回值只有一个。那为什么有的会出现多个呢?这里的”多个“并不是多个返回值而已,比如返回一列表,里面包含很多值。举个例子就是:”只能带走一个东西,但是允许把一些东西装到塑料袋里面看做一个东西带走,这是允许的。“
如在Js中:
- <script type="text/javascript">
- function foo(){
- return 'xya','abc',123,true;
- }
- function bar(){
- return ['xya','abc',123,true];
- }
- var s1 = foo();
- var s2 = bar();
- alert(s1); //输出true
- alert(s2); //输出xya,abc,123,true
- </script>
同理,Python中也一样。
- >>> def foo():
- return ['xyz',123,True]
- >>> def bar():
- return 'abc',456,False
foo()返回一个列表;bar()返回一个元祖(元祖语法上不需要一定要带上圆括号),所以让人真以为可以返回多个对象。当然,我们为了方便可读性,最好加上圆括号。
- >>> aTuple = bar()
- >>> x,y,z = bar()
- >>> (x,y,z) = bar()
- >>> aTuple
- ('abc', 456, False)
- >>> x,y,z
- ('abc', 456, False)
- >>> (x,y,z)
- ('abc', 456, False)
注意:
三、函数调用
- >>> def foo(x,y):
- return x,y
- >>> foo(1,2)#标准调用
- (1, 2)
- >>> foo('a','b')
- ('a', 'b')
- >>> foo(x=1,y=2)#参数化调用
- (1, 2)
- >>>
四、创建函数
- def function_name(arguments):
- """function documention_string"""
- function_body_suite
1、声明与定义:
2、前向引用
和其他高级语言类似,Python不允许在函数未声明之前对它引用或调用。
3、函数的属性
比如创建两个Py文件,test1.py;test2.py,如下:
- test1.py
- --------------------------
- ST = 'test1'
- def bar():
- '''This is bar'''
- print 'ok'
- test2.py
- --------------------------------------
- import test1
- print test1.ST
- print test1.bar()
- #-----------输出
- #test1
- #ok
- #None
- #-----------记得过程是返回值None的函数
- def foo():
- '''This is foo'''
- print 'foo'
- print foo.__doc__ #This is foo
4、嵌套函数
- >>> def foo():
- def bar():
- print 'bar() is called'
- print 'foo() is called'
- bar()
- >>> foo()
- foo() is called
- bar() is called
- >>> bar()
- Traceback (most recent call last):
- File "<pyshell#5>", line 1, in <module>
- bar()
- NameError: name 'bar' is not defined
因为bar()的作用域在foo()里面,在外面不能引用bar。
5、函数(方法)的装饰器
见:http://www.cnblogs.com/BeginMan/p/3173328.html
五、传递函数
1、其他变量可做函数的别名,因为对象的引用
所有对象都是通过引用来传递的,函数也不例外,当对一个变量赋值时,实际上是将相同对象的引用赋值给了这个变量。如果对象是函数的话,这个对象的所有别名都是可调用的。
- def foo():
- print 'foo'
- bar = foo #函数对象的引用
- bar() #函数对象的调用
- #输出foo
注意:foo:函数对象的引用;foo():函数对象的调用
2、函数作为参数传入其他函数来调用
时刻要记住:函数对象、引用与调用的区别,这几个关键字眼。
- def foo():
- print 'foo'
- def bar(argfunc):
- print 'in bar()'
- argfunc()
- bar(foo) #把函数作为参数传入其他函数来调用
- #输出:
- #in bar()
- #foo
局部变量argfunc就相当于函数对象foo的别名
在如下:
- #内建函数int()/float()/long()转换、实现函数的传递与调用
- def convert(argfunc,seq):
- return [argfunc(obj) for obj in seq]
- lis = [123,15.23,-6.2e5,99999999L]
- print convert(int, lis) #[123, 15, -620000, 99999999]
- print convert(float,lis)#[123.0, 15.23, -620000.0, 99999999.0]
- print convert(long, lis)#[123L, 15L, -620000L, 99999999L]
六、Formal Arguments
1、位置参数
以函数定义的准确顺序来传递,如果没有任何默认参数的下,传入参数个数也要一致。
常见错误如下:
takes no arguments (1 given)
takes exactly 2 arguments (1 given)等等
2、默认参数
- def foo(arg,default1 = 'Python',default2 = 'Django'):
- pass
每一个默认参数后面都紧跟一个默认值的赋值语句,如果在函数调用时没有给出值,则使用默认的值。
默认参数最好写在最后
3、关键字参数
- def foo(arg,obj1='good',obj2=10):
- return arg,obj1,obj2
- print foo(arg='BeginMan') #('BeginMan', 'good', 10)
- print foo('BeginMan') #('BeginMan', 'good', 10)
- print foo('BeginMan','Python') #('BeginMan', 'Python', 10)
- #print foo(arg='BeginMan',100) #出错
- print foo(arg='BeginMan',obj2=100) #('BeginMan', 'good', 100)
- print foo(obj2=100,arg='BeginMan',obj1='Ok') #('BeginMan', 'Ok', 100)
七、可变长度的参数
1、变长参数与非变长参数
强烈推荐:http://blog.csdn.net/qinyilang/article/details/5484415
- """在参数名之前使用一个星号,就是让函数接受任意多的位置参数"""
- def multiply(*args):
- total = 1
- for arg in args:
- total+=arg
- return total
- print multiply() #1
- print multiply(1,2) #4
- print multiply(4,5,6) #
- """python在参数名之前使用2个星号来支持任意多的关键字参数"""
- def multiply2(**kwargs):
- for key,value in kwargs.items():
- print '%s=>%s' %(key,value)
- multiply2()
- multiply2(name='beginman') #name=>beginman
- multiply2(name='beginman',age='22',tel=110)
- #顺序
- def complex_function(a,b=None,*args,**kwarg):
- pass
- #测试
- def add(a,b,c):
- return a+b+c
- print add(a=10,b=10,c=10)
- args=(2,3)
- print add(1,*args) #6
- kwargs={'b':100,'c':200}
- print add(100,**kwargs) #400
- print add(a=100,**kwargs) #400
- #print add(a=100,*args) #TypeError: add() got multiple values for keyword argument 'a'
- print add(1,2,c=3) #6
- print add(1,2,b=3) # add() got multiple values for keyword argument 'b'
引用如下:
过量的参数
在运行时知道一个函数有什么参数,通常是不可能的。另一个情况是一个函数能操作很多对象。更有甚者,调用自身的函数变成一种api提供给可用的应用。
对于这些情况,python提供了两种特别的方法来定义函数的参数,允许函数接受过量的参数,不用显式声明参数。这些“额外”的参数下一步再解释。
注意args和kwargs只是python的约定。任何函数参数,你可以自己喜欢的方式命名,但是最好和python标准的惯用法一致,以便你的代码,其他的程序员也能轻松读懂。
位置参数在参数名之前使用一个星号,就是让函数接受任意多的位置参数。
- >>> def multiply(*args):
- ... total = 1
- ... for arg in args:
- ... total *= arg
- ... return total
- ...
- >>> multiply(2, 3)
- 6
- >>> multiply(2, 3, 4, 5, 6)
- 720
python把参数收集到一个元组中,作为变量args。显式声明的参数之外如果没有位置参数,这个参数就作为一个空元组。
关键字参数
python在参数名之前使用2个星号来支持任意多的关键字参数。
- >>> def accept(**kwargs):
- ... for keyword, value in kwargs.items():
- ... print "%s => %r" % (keyword, value)
- ...
- >>> accept(foo='bar', spam='eggs')
- foo => 'bar'
- spam => 'eggs'
注意:kwargs是一个正常的python字典类型,包含参数名和值。如果没有更多的关键字参数,kwargs就是一个空字典。
混合参数类型
任意的位置参数和关键字参数可以和其他标准的参数声明一起使用。混合使用时要加些小心,因为python中他们的次序是重要的。参数归为4类,不是所有的类别都需要。他们必须按下面的次序定义,不用的可以跳过。
1)必须的参数
2)可选的参数
3)过量的位置参数
4)过量的关键字参数def complex_function(a, b=None, *c, **d):
这个次序是必须的,因为*args和**kwargs只接受那些没有放进来的其他任何参数。没有这个次序,当你调用一个带有位置参数的函数,python就不知道哪个值是已声明参数想要的,也不知道哪个被作为过量参数对待。
也要注意的是,当函数能接受许多必须的参数和可选的参数,那它只要定义一个过量的参数类型即可。
传递参数集合
除了函数能接受任意参数集合,python代码也可以调用带有任意多数量的函数,像前面说过的用星号。这种方式传递的参数由python扩展成为参数列表。以便被调用的函数
不需要为了这样调用而去使用过量参数。python中任何可调用的,都能用这种技法来调用。并且用相同的次序规则和标准参数一起使用。
- >>> def add(a, b, c):
- ... return a + b + c
- ...
- >>> add(1, 2, 3)
- 6
- >>> add(a=4, b=5, c=6)
- 15
- >>> args = (2, 3)
- >>> add(1, *args)
- 6
- >>> kwargs={'b': 8, 'c': 9}
- >>> add(a=7, **kwargs)
- 24
- >>> add(a=7, *args)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: add() got multiple values for keyword argument 'a'
- >>> add(1, 2, a=7)
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: add() got multiple values for keyword argument 'a'
注意这个例子的最后几行,特别留意当传递一个元组作为过量的位置参数时,是否要显式的传递关键字参数。因为python使用次序规则来扩展过量的参数,那位置参数要放在前面。这个例子中,最后两个调用是相同的,python不能决定那个值是给a的。
《转》Python学习(17)-python函数基础部分的更多相关文章
- Python学习-17.Python中的错误处理(二)
错误是多种多样的,在 except 语句中,可以捕获指定的异常 修改代码如下: import io path = r'' mode = 'w' try: file = open(path,mode) ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
- Python学习day05 - Python基础(3) 格式化输出和基本运算符
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- python学习之路-day2-pyth基础2
一. 模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...
- Python学习一:序列基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...
- Python学习day09 - Python进阶(3)
figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...
- Python学习:5.函数以及基础语句
函数 一.创建函数 Python的函数的学习是Python基础的一个重要部分,函数可以重复利用,减少代码量,接下来我们就学习一下如何创建一个函数,以及函数的使用. 1.创建一个函数的基本格式 def ...
- 小白学 Python(17):基础数据类型(函数)(下)
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- Python学习笔记—Python基础1 介绍、发展史、安装、基本语法
第一周学习笔记: 一.Python介绍 1.Python的创始人为吉多·范罗苏姆.1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言 ...
随机推荐
- iText操作PDF读取JPEG图片ArrayIndexOutOfBoundsException异常
iText版本:itextpdf-5.5.1.jar 问题描述 读取本地JPEG图片文件的代码: com.itextpdf.text.Image image = com.itextpdf.text.I ...
- Invalid input for operation: physical_network 'physnet1' unknown for flat provider network.
在devstack中 按照这个教程给bare metal创建flat network,一切都配置好之后, 执行net-create时遇到错误: Invalid input for operation ...
- LAMP一体环境快速安装
(一)安装Apache 1.下载安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 yum install zlib-devel -y wget http://m ...
- js 闭包实例
var db = (function() { // 创建一个隐藏的object, 这个object持有一些数据 // 从外部是不能访问这个object的 var data = {}; // 创建一个函 ...
- 最近输入法的问题:关于ctrl + space 无法开关闭输入法的问题
输入法无法切换最好解决方法首先任务栏上的输入法图标上点右键选择设置. 然后选择键设置,双击第一个“在不同的输入语言之间切换”先勾选“切换输入语言”下面选择左手ALT.取消右边“切换键盘布局”前的勾. ...
- FXAA
无抗锯齿 SSAA 硬件抗锯齿,OpenGL自带,4x FXAA 从图中可以看出 FXAA抗锯齿,没有硬件MSAA抗锯齿效果好
- SharePoint 2013 地址栏_layouts/15/start.aspx#
大家在使用SharePoint2013的时候是否发现,地址栏中显示的URL不再变得友好,多出这么一段“_layouts/15/start.aspx#”,怎么看怎么别扭. 如果要取消这段路径的显示,需要 ...
- kafka学习之-集群配置及安装
1.软件版本 kafka2.10_0.9.0.0 zookeeper_3.4.6 2.集群节点 一共有3台机器. 192.168.14.100 slave-01 192.168.14.105 slav ...
- koa使用koa-passport实现路由进入前登录验证
现在的项目需求很简单,当进入一个页面的时候,如果没登录,则跳转到登录页面,如果登录了则直接到对应页面. koa2写的项目,使用koa-passport,koa-session,根据koa-passpo ...
- Java虚拟机(JVM)你只要看这一篇就够了!
1. Java 内存区域与内存溢出异常 1.1 运行时数据区域 根据<Java 虚拟机规范(Java SE 7 版)>规定,Java 虚拟机所管理的内存如下图所示. 1.1.1 程序计数器 ...