函数

简介及定义

简介

函数是可重用的程序段

它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次地运行这个语句块。

函数作用:最大程度重用和最小化代码冗余,流程分解

定义

使用def可以声明一个函数,完整的函数由函数名,参数以及函数实现语句组成。

一般形式:

def <函数名> (参数列表):
   <函数语句>
   return <返回值>

其中参数和返回值非必须

注意,没有返回值的return语句等价于return None

示例

def hello():
    print 'hello world'

hello()

l = [1,2,3,]
def sum(List)
    result = 0
    for i in List:
        result = result+i
    return result
sum(l)

注意:

  • def是可执行代码

def可以出现在任一语句可以出现的地方,甚至是嵌套在其他语句中

  :::python
  if test:
     def func():
       …..
  else:
     def func():
       ….
  • def创建一个函数对象并将其赋值给一个变量

函数可以赋值给一个变量,类似别名,othername = func,在需要时再调用
return将结果对象发送给调用者
函数是通过赋值传递的(对象引用)
* 参数,返回值及变量并不不要类型声明

参数

简介
参数类型

主要明确几个概念

  • 形参实参

函数中参数的名称位形参

调用函数提供给函数的调用值位实参

def sum(a, b):  #a, b形参
    return a + b

sum(1, 5)  # 1, 5实参
  • 位置参数

默认情况下,函数参数位位置参数,即通过位置指定实参

格局传递位置确认值

def sum(a, b):
    return a + b
sum(1, 2)   # a=1, b=2
sum(2, 1)   # a=2, b=1
  • 默认参数

对于一些函数,你可能希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值

def sum(a, b=1): #b为默认参数
    return a + b
sum(1,2) #3
sum(1)   #2

注意,默认参数定义必须在位置参数之后。

def sum(a, b=1) #有效
def sum(b=1, a) #无效

特别注意,默认参数值只计算一次,当值为可变对象时需特别注意:

>>> def sum(a, b=[]):
...     b.append(a)
...     return b
...
>>> sum(1)
[1]
>>> sum(2)
[1, 2]

#若是不想缺省值在连续调用中被保留
def sum(a, b=None):
    if not b:
        b = []
    b.append(a)
    return b
  • 关键参数

使用名字(关键字)而不是位置来给函数指定实参,keyword = value形式

可以通过命名为参数赋值

def sum(a=0, b=0):
    return a + b
sum()  # 0 + 0
sum(a=1) # 1 + 0
sum(b=1) # 0 + 1
sum(a=1, b=2) # 1 + 2
sum(b=1, a=2) # 2 + 1
  • 可变长参数

具有任意个参数,而不必将所有参数定义

参数开头以*

*seq 序列位置参数,接收一个元组,包含了所有没有出现在形式参数列表中的参数值

>>> def test(*seq):
...     print seq
...
>>> test(1,2,3,4)
(1, 2, 3, 4)
>>> test(*[1,2,3])
(1, 2, 3)

**dic 关键参数,接收一个字段,包含了所有未出现在形式参数列表中的关键字参数

>>> def test2(**dic):
...     print dic
...
>>> test2(a=1,b=2)
{'a': 1, 'b': 2}
>>> test2(**{'a':1, 'b':2})
{'a': 1, 'b': 2}
参数匹配

参数匹配方式:

定义:

在函数定义中,参数顺序:

任何一版参数name,默认参数name=value,之后*name,之后任何name,最后**name

def func(name) 位置或变量名匹配
def func(name=value) 参数存在默认值,若是没有传入,使用默认值
def func(*name) 匹配并收集在元组中所有包含位置的参数
def func(**name) 匹配并收集在字典中所有包含位置的参数
def func(*args,name)参数必须在调用中按照关键字传递

调用:

在函数调用中,参数出现顺序:

位置参数value,关键字参数name=value,*sequence形式组合,最后是**dict

func(value) 常规,位置匹配
func(name = value) 关键字匹配,通过变量名
func(*sequence) 以name传递所有对象,并作为独立的基于位置的参数
func(**dict) 以name传递所有关键字/值,并作为独立的关键字参数

可以混合定义和传递多种类型参数,参数匹配顺序:

位置分配分关键字->匹配变量名->而外非关键字分配到*name->额外关键字参数分配到**name中->默认值分配给头部未得到匹配的参数

#!/usr/bin/env python
# encoding: utf-8


def test(a, b, c=1, d=2, *tp, **dp):
    print 'a', a
    print 'b', b
    print 'c', c
    print 'd', d
    print 'tp', tp
    print 'dp', dp
    print "=========="

test(1, 2)

test(1,2,d=3)

test(1,2,3,4,5,e=6,f=7)

结果:

a 1
b 2
c 1
d 2
tp ()
dp {}
==========
a 1
b 2
c 1
d 3
tp ()
dp {}
==========
a 1
b 2
c 3
d 4
tp (5,)
dp {'e': 6, 'f': 7}
==========
参数传递

不可变参数“通过值”进行传递,整数,字符串通过对象引用,而非拷贝一份,指向同一内存,效果很像创建拷贝

>>> a = 1
>>> def p(param):
...     param = 2
...
>>> a
1
>>> p(a)
>>> a
1

可变对象通过“指针”进行传递的,改变函数的可变对象参数的值也许会对调用者造成影响

>>> b
[1, 2, 3]
>>>
>>> def d(param):
...     param.append(9)
...
>>> b
[1, 2, 3]
>>> d(b)
>>> b
[1, 2, 3, 9]

特别注意:

实参为可变对象,传递传引用,形参改变对象引用不会对实参造成影响

>>> b = [1, 2, 3]
>>> def c(param):  #执行到这里,param赋值,param和b指向同一内存位置
...     param = [4, 5, 6]  #param再次被赋值,指向另一位置,不会对原先造成影响
...
>>> b
[1, 2, 3]
>>> c(b)

lambda

特殊的声明函数方式,用于创建新的函数对象,并且在运行时返回它们【返回函数对象】

lambda是一个表达式,而不是一个语句

lambda主体是一个单个的表达式,而不是一个代码块

用于定义小型的函数,在函数中仅包含单一的参数表达式,而不能包含其他语句,但是可以调用其他函数

语法:

#lambda 参数列表:表达式
lambda arg1,arg2,…argN: expression using args

为什么使用:函数速写,GUI

例子:

>>> result = lambda x:x**2
>>> result(3)
9

函数设计概念

指导原则:

  • 耦合性:对于输入使用参数并且对于输出使用return 语句,让函数独立于它外部的东西
  • 耦合性:只有在真正必要的情况下使用全局变量使用参数和返回值
  • 耦合性:不要改变可变类型参数,除非调用者希望如此
    特殊,不友好,不可预料的改变
  • 聚合性:每个函数都应该有一个单一的,统一的目标
  • 大小:每个函数都应该相对较小,一个函数只做一件事,保持简单,保持简短
  • 耦合:避免直接改变在另一个模块文件中的变量

内置函数

常用且有点多,独立一章说明


The end!

To be continue

wklken

Email: wklken@yeah.net

Blog: http://blog.csdn.net/wklken

2013-03-16

转载请注明出处,谢谢