【Python之旅】第三篇(一):Python函数

说明:

    使用函数可以使程序实现功能模块化,大大简洁我们的程序,这里主要讨论Python中函数的下列内容:

1.函数定义与函数参数
2.局部变量和全局变量
3.函数默认参数和关键参数
4.*Args和**Kargs
5.函数返回值return与yield简单说明
6.lambda函数(匿名函数)
7.Python内置函数

    因为函数部分内容跟C语言中的很多内容都十分相似,所以会结合C语言来进行对比学习。



1.函数定义与函数参数


--基本格式1:不参参数

・定义:

def sayHi():
    print "Hello!"

・调用:

>>> sayHi()
Hello


--基本格式2:带一个参数

・定义:

def sayHi(name):
    print "Hello, %s, how are you?" % name

・调用:

>>> sayHi('xpleaf')
Hello, xpleaf, how are you?


--基本格式3:多个参数

・定义:

def sayHi(name, age):
    print "Hello, %s, how are you?" % name
    print "You are %s years old." % age

・调用:

>>> sayHi('CL', 20)
Hello, CL, how are you?
You are 20 years old.



2.局部变量与全局变量


・看下面一个程序:

#!/usr/bin/env python

age = 29

def sayHi():
        age = 28
        print "function age:%s" % age

sayHi()
print "gloable age:",age

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python fun3.py 
function age:28
gloable age: 29


・Python函数中,作用域的概念与C语言中是一样的,这里不再提及;

・有两点需要注意:

a.通过局部变量改变全局变量,可以在函数中使用global,如下代码:

def sayHi():
        global age
        age = 28
        print "function age:%s" % age

b.全局变量没有定义,在函数中使用global定义,相当于定义全局变量,但不建议这样使用;



4.函数默认参数和关键参数


--函数默认参数

・看下面一个程序:

#!/usr/bin/env python

def users(username, group = 'GDUT'):
        mydict = {}
        mydict[username] = group
        return mydict

print "default argument:", users('xpleaf') #use default argument

print "full argument:", users('xpleaf', 'BAT') #do not use default argument

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py 
default argument: {'xpleaf': 'GDUT'}
full argument: {'xpleaf': 'BAT'}

・定义函数时,参数默认赋值,在使用函数时即可以不对此类参数赋值,即为默认参数;


・使用默认参数的原则:定义函数时,非默认参数在前,默认参数在后;

・如下面即是非法的情况:

#!/usr/bin/env python

def users(group = 'GDUT', name):
        mydict = {}
        mydict[username] = group
        return mydict

print "default argument:", users('xpleaf') #use default argument
#编译器将无法知道'xpleaf'是赋给group变量还是name变量

print "full argument:", users('xpleaf', 'BAT') #do not use default argument

・执行时提示错误:non-default argument follows default argument

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py 
  File "default.py", line 3
    def users(group = 'GDUT', name):
SyntaxError: non-default argument follows default argument


--函数关键参数

・在使用多个默认参数的函数中,如下程序:

#!/usr/bin/env python

def users(name, age, group = 'GDUT', project = 'Python'):
        print '''name:%s
age:%s
group:%s
project:%s''' % (name, age, group ,project)

users('xpleaf', 21)

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py 
name:xpleaf
age:21
group:GDUT
project:Python


-只指定第一个默认参数


・对应的users的代码修改为:

users('xpleaf', 21, 'BAT')

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py
name:xpleaf
age:21
group:BAT
project:Python


-同时指定两个默认参数


・对应的users的代码修改为:

users('xpleaf', 21, 'BAT', 'stupy')

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py
name:xpleaf
age:21
group:BAT
project:stupy


-只需要指定第二个默认参数


・对应的users的代码修改为:

users('xpleaf', 21, project = 'stupy')

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py
name:xpleaf
age:21
group:GDUT
project:stupy

・指定第二个参数,此即为关键参数,可以不按原来参数的顺序(不指定关键参数则达不到目的);

・也可以指定多个默认参数,从而不按原来参数的位置,users代码修改如下:

users(project = 'stupy', name = 'xpleaf', age = 21, group = 'BAT')

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py
name:xpleaf
age:21
group:BAT
project:stupy


-更清晰的例子


・程序代码如下:

#!/usr/bin/env python

def func(a, b=5, c=10):
        print 'a=%s, b=%s, c=%s' % (a, b, c)

func(3, 7)
func(25,c=24 )
func(c=50, a=100)

・执行结果如下:

func(3, 7) # a = 3, b=7,c=10 
func(25, c=24) # a=25, b=5,c=24 
func(c=50, a=100) # a=100,b=5,c=50



4.*Args和**Kargs


・在参数不确定的情况下使用*args和**kargs,前者可以输出参数对应的元组,后者可以输出参数对应的字典;


・*args演示如下:

a.程序代码

def sayHI(*args):
        print args
sayHI('xpleaf',21,'GDUT')

b.执行结果

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python fun2.py 
('xpleaf', 21, 'GDUT')


・**kargs演示如下:

a.程序代码

def sayHi2(**kargs):
        print kargs


sayHi2(name = 'xpleaf', age=21, phone = 5201314)

b.执行结果

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python fun2.py 
{'phone': 34234, 'age': 29, 'name': 'Alex'}

・由于字典是没有次序的,所以输出的顺序会跟输入的不同;

・如果只按照上面的写法,则说明可以不加任何参数,当然,根据此思路,我们也可以定义如def sayHi(name,age,**kargs)等形式的;

・关于该函数参数的说明,更详细的,可以参考廖雪峰老师的相关文档,也是写得非常详细的。



5.函数返回值return与yield简单说明


--return说明

・在函数中添加return语句可以返回函数执行的某些值,但会造成阻塞问题,看下面代码:

def func():
        for i in range(10):
                return i
result = func()
print result

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3/blog$ python func.py 
0

・与C语言类似,函数遇到return即会结束,意味着使用return返回函数值会造成阻塞问题,即不能每执行一次循环,返回一个值,再执行其他操作,然后再去执行函数中的循环;

・可以使用yield来代替return实现上面功能;


--yield说明


-代码改写1

・上面代码改写为:

import time

def func():
        for i in range(10):
                time.sleep(1)
                yield 'Loop', i
result = func()
print result

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3/blog$ python func.py 
<generator object func at 0x7f06d4300c80>

・由前面迭代器的知识,yield实现的就是创建一个迭代器;


-代码改写2

・上面代码改写为:

import time

def func():
        for i in range(10):
                time.sleep(1)
                yield 'Loop', i
result = func()
print result.next()
print result.next()
print result.next()
print result.next()
print result.next()

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3/blog$ python func.py 
('Loop', 0)
('Loop', 1)
('Loop', 2)
('Loop', 3)
('Loop', 4)

・只调用了5次迭代器,因此只产生5个值;


-代码改写3

・上面代码改写为:

import time

def func():
        for i in range(10):
                time.sleep(1)
                yield 'Loop', i
result = func()
print result.next()
print 'Upon:No.1'
print result.next()
print 'Upon:No.2'
print result.next()
print 'Upon:No.3'
print result.next()
print 'Upon:No.4'
print result.next()
print 'Upon:No.5'
print 'None'

・执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3/blog$ python func.py 
('Loop', 0)
Upon:No.1
('Loop', 1)
Upon:No.2
('Loop', 2)
Upon:No.3
('Loop', 3)
Upon:No.4
('Loop', 4)
Upon:No.5
None

・即可以实现前面[跳出函数-->再执行其它操作-->再回到函数]的功能;

・注意事项为:

a.用了yield就不能使用return,用了yield就表示用了迭代器

b.yield要用在函数中,不能直接在循环中写,即在不是函数内的循环中写,如:

for i in range(10):
		time.sleep(1)
		yield 'Loop', i



6.lambda函数(匿名函数)


--关于匿名函数的说明

lambda函数也叫匿名函数,即,函数没有具体的名称。先来看一个最简单例子:
def f(x):
return x**2
print f(4)
Python中使用lambda的话,写成这样
g = lambda x : x**2
print g(4)
那么,lambda表达式有什么用处呢?很多人提出了质疑,lambda和普通的函数相比,就是省去了函数名称而已,同时这样的匿名函数,又不能共享在别的地方调用。其实说的没错,lambda在Python这种动态的语言中确实没有起到什么惊天动地的作用,因为有很多别的方法能够代替lambda。同时,使用lambda的写法有时显得并没有那么pythonic。甚至有人提出之后的Python版本要取消lambda。
回过头来想想,Python中的lambda真的没有用武之地吗?其实不是的,至少我能想到的点,主要有:
1. 使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。
2. 对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。
3. 使用lambda在某些时候让代码更容易理解。


--lambda函数应用1:定义简单函数

・演示如下:

>>> g = lambda x:x**2
>>> g(4)
16

・关于lambda函数与普通函数的简单区别:

a.lambda执行操作时,第一次是引用变量,即引用匿名函数,往后相同操作是引用上一次的指针:

>>> g = lambda x:x**2
>>> g(4)
16
>>> g(4)
16    #直接引用上一次结果的指针
>>> g(6)
36    #新的操作,会重新引用变量

b.普通函数无论是否执行相同操作,都是直接调用函数的功能;


--lambda函数应用2:应用于map函数

・查看map函数的帮助文档:

map(...)
    map(function, sequence[, sequence, ...]) -> list
#即前面第一个参数可以为一个函数,并将sequence交给该函数处理,这时可使用lambda函数

・演示如下:

>>> a = range(10)
>>> b = range(10)
>>> a,b
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> map(lambda x:x**2,a)    #定义1个参数
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> map(lambda x,y:x**y,a,b)    #定义两个参数
[1, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489]


--lambda函数应用3:应用于sorted()排序

・sorted()可对数据类型进行排序,虽然字典无序,但可以有序输出字典中的内容;

・演示如下:

>>> a = {2:'a',4:'f',8:'c',9:'e'}
>>> a
{8: 'c', 9: 'e', 2: 'a', 4: 'f'}
>>> sorted(a.items())
[(2, 'a'), (4, 'f'), (8, 'c'), (9, 'e')]

・通过sorted()结合lambda函数可以选取基于字典中key值或value值的排序:

>>> sorted(a.items(),key=lambda x:x[0])    #基于key值排序
[(2, 'a'), (4, 'f'), (8, 'c'), (9, 'e')]
>>> sorted(a.items(),key=lambda x:x[1])    #基于value值排序
[(2, 'a'), (8, 'c'), (9, 'e'), (4, 'f')]

・sorted()中的key并非特指字典中的key值,这是sorted()函数中的参数关键字:

sorted(...)
    sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list



7.Python内置函数


・Python中内置函数比较多,这里不给出,参考个人的内置函数文档即可,往后学习更深入,内置函数使用更多时会再重新写一篇专门Python内置函数的文章。



你可能感兴趣的:(函数,python)