一、什么是函数、方法、过程

推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html

一般程序设计语言包含两种基本的抽象:过程抽象数据抽象。过程抽象有时也称控制抽象

子程序在1950年以前就发明了,作为一种抽象那时候并未被完全接受。相反,最初它被看做是一种节省代码的机制,但很快子程序就被认可为过程抽象的一种方式。意识到子程序可以作为一种抽象机制,这产生了三个重要结果。

  1. 人们发明了一些语言,支持各种参数传递机制
  2. 奠定了「结构化程序设计」的基础,语言开始支持嵌套的子程序(如JS的function,Java的inner class)
  3. 诞生了「结构化程序设计」,为试图构建大型系统提供了指导,利用子程序作为基本构建块

子程序是最主要过程抽象机制。面向对象语言中的方法与子程序的概念十分相似,不同在于它们的调用以及它们与类或对象关联的方式。

点击继续阅读

二、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
"""python在参数名之前使用2个星号来支持任意多的关键字参数"""
def multiply2(**kwargs):
    for key,value in kwargs.items():
        print '%s=>%s' %(key,value)

multiply2()
multiply2(name='beginman')                  #name=>beginman
multiply2(name=',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入门笔记(18):Python函数(1):基础部分的更多相关文章

  1. Python入门笔记(20):Python函数(3):关于lambda

    一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称,而用def创建的方法是有名称的.如下: """命名的foo函数&q ...

  2. Python入门笔记(22):Python函数(5):变量作用域与闭包

    一.全局变量与局部变量 一个模块中,最高级别的变量有全局作用域. 全局变量一个特征就是:除非被删除,否则他们存活到脚本运行结束,且对于所有的函数都可访问. 当搜索一个标识符(也称变量.名字等),Pyt ...

  3. Python入门笔记(21):Python函数(4):关于函数式编程的内建函数

    一.关于函数式编程的内建函数 apply()逐渐被舍弃,这里不讨论 1.filter() #filter(func,seq) """纯Python描述filter函数&q ...

  4. Python入门笔记(19):Python函数(2):函数/方法装饰器

    一.装饰器(decorators) 装饰器的语法以@开头,接着是装饰器函数的名字.可选参数. 紧跟装饰器声明的是被装饰的函数和被装饰的函数的可选参数,如下: @decorator(dec_opt_ar ...

  5. Python入门笔记(14):Python的字符编码

    一.字符编码中ASCII.Unicode和UTF-8的区别 点击阅读:http://www.cnblogs.com/kingstarspe/p/ASCII.html 再推荐一篇相关博文:http:// ...

  6. Python学习笔记之常用函数及说明

    Python学习笔记之常用函数及说明 俗话说"好记性不如烂笔头",老祖宗们几千年总结出来的东西还是有些道理的,所以,常用的东西也要记下来,不记不知道,一记吓一跳,乖乖,函数咋这么多 ...

  7. python入门学习:7.函数

    python入门学习:7.函数 关键点:函数 7.1 定义函数7.2 传递实参7.3 返回值7.4 传递列表7.5 传递任意数量的实参7.6 将函数存储在模块中 7.1 定义函数   使用关键字def ...

  8. Python入门篇-高阶函数

    Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数  1>.First Class Object 函数在Python中是一等公民 函数也 ...

  9. PYTHON 学习笔记1 PYTHON 入门 搭建环境与基本类型

    简介 Python,当然大家听到这个名词不再是有关于像JAVA 一样的关于后台,我们学习Python 的目的在于对于以后数据分析和机器学习AI 奠定基础,Python 在数据分析这一块,可谓是有较好的 ...

随机推荐

  1. android Studio NDK

    官方文档地址: https://developer.android.com/studio/projects/add-native-code.html#download-ndk 最近推出CMake方式集 ...

  2. 用 Jenkins 打包 iOS

    需要安装插件: 1.GIT plugin 2.Xcode integration   1.新建 Job 填入“Item名称”,选择“构建一个自由风格的软件项目”,OK:   2.填入“项目名称”   ...

  3. c# 垮线程调用控件

    http://www.cnblogs.com/TankXiao/p/3348292.html

  4. 【Android】如何写一个JsBridge

    JsBridge 简介 Android JsBridge 就是用来在 Android app的原生 java 代码与 javascript 代码中架设通信(调用)桥梁的辅助工具. 原文地址点这里 gi ...

  5. 如何使用 App Studio 快速定制你自己的 Universal Windows App

    之前我为大家介绍过 App Studio 这只神器可以帮助大家快速制作一个 Windows Phone 8 的应用,今天之所以在写一篇关于 App Studio 的文章是因为,App Studio 经 ...

  6. [转]mac 10.9.4下配置apache

    出处:http://yjmyzz.cnblogs.com mac 10.9.x已经自带了apache,可按如下步骤开启: 1.启动 sudo apachectl start 启动后,访问 http:/ ...

  7. LeetCode:4_Median of Two Sorted Arrays | 求两个排序数组的中位数 | Hard

    题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  8. IIS7 php wordpress 中文url 标签tag中文URL404解决方法

    新建重写规则: <rule name="ChineseURL" stopProcessing="true"> <match url=" ...

  9. 突破短板,传统桌面程序 使用webapi 扩展迎合web和移动端融合的需求

    传统桌面程序不能完全被web和移动端替代,但是需要改造.这里要说的是巧用webapi把以前用dll和com组件,ocx等方式做接口,做分布式开发的方式,改成restful 风格api的方式实现跨平台, ...

  10. S5PV210之Sate210-F DIY硬件,移植uboot,kernel,android 活动现在已经进入实施阶段吗,欢迎广大网友参与 !

    大家一起来diy 超低价四核的exynos4412或者Cortex A8S5pv210开源开发板 商业版Sate210已经完成了好久了.Sate4412 也已经出来.但是这两个接口非常全,主要是针对企 ...