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

说明:

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


1

2

3

4

5

6

7

1.函数定义与函数参数

2.局部变量和全局变量

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

4.*args和**kwargs

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

6.lambda函数(匿名函数)

7.Python内置函数

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


1.函数定义与函数参数

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

·定义:


1

2

def sayHi():

    print "Hello!"

·调用:


1

2

>>> sayHi()

Hello

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

·定义:


1

2

def sayHi(name):

    print "Hello, %s, how are you?" % name

·调用:


1

2

>>> sayHi('xpleaf')

Hello, xpleaf, how are you?

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

·定义:


1

2

3

def sayHi(name, age):

    print "Hello, %s, how are you?" % name

    print "You are %s years old." % age

·调用:


1

2

3

>>> sayHi('CL'20)

Hello, CL, how are you?

You are 20 years old.


2.局部变量与全局变量

·看下面一个程序:


1

2

3

4

5

6

7

8

9

10

#!/usr/bin/env python

 

age = 29

 

def sayHi():

        age = 28

        print "function age:%s" % age

 

sayHi()

print "gloable age:",age

·执行结果如下:


1

2

3

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python fun3.py 

function age:28

gloable age: 29

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

·有两点需要注意:

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


1

2

3

4

def sayHi():

        global age

        age = 28

        print "function age:%s" % age

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


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

--函数默认参数

·看下面一个程序:


1

2

3

4

5

6

7

8

9

10

#!/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

·执行结果如下:


1

2

3

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py 

default argument: {'xpleaf''GDUT'}

full argument: {'xpleaf''BAT'}

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

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

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


1

2

3

4

5

6

7

8

9

10

11

#!/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


1

2

3

4

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

--函数关键参数

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


1

2

3

4

5

6

7

8

9

#!/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)

·执行结果如下:


1

2

3

4

5

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py 

name:xpleaf

age:21

group:GDUT

project:Python

-只指定第一个默认参数


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


1

users('xpleaf'21'BAT')

·执行结果如下:


1

2

3

4

5

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py

name:xpleaf

age:21

group:BAT

project:Python

-同时指定两个默认参数

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


1

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

·执行结果如下:


1

2

3

4

5

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py

name:xpleaf

age:21

group:BAT

project:stupy

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


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


1

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

·执行结果如下:


1

2

3

4

5

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py

name:xpleaf

age:21

group:GDUT

project:stupy

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

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


1

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

·执行结果如下:


1

2

3

4

5

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python default.py

name:xpleaf

age:21

group:BAT

project:stupy

-更清晰的例子


·程序代码如下:


1

2

3

4

5

6

7

8

#!/usr/bin/env python

 

def func(a, b=5, c=10):

        print 'a=%s, b=%s, c=%s' % (a, b, c)

 

func(37)

func(25,c=24 )

func(c=50, a=100)

·执行结果如下:


1

2

3

func(37) # 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和**kwargs

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

·*args演示如下:

a.程序代码


1

2

3

def sayHI(*args):

        print args

sayHI('xpleaf',21,'GDUT')

b.执行结果


1

2

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python fun2.py 

('xpleaf'21'GDUT')

·**kwargs演示如下:

a.程序代码


1

2

3

4

5

def sayHi2(**kwargs):

        print kwargs

 

 

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

b.执行结果


1

2

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python fun2.py 

{'phone'5201314'age'21'name''xpleaf'}

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

·由于kwargs是以字典的方式获取函数中的参数,这也意味前,如果原来函数就没有参数,而且在使用函数时又没有使用关键字参数的方式执行函数,是会有问题的:


1

2

3

4

5

6

7

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

Traceback (most recent call last):

  File "<stdin>", line 1in <module>

TypeError: sayHi2() takes exactly 0 arguments (3 given)

 

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

{'phone'5201314'age'21'name''xpleaf'}

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

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

·*args和**kwargs同时使用:


1

2

3

4

>>> def func(*args, **kwargs):

...   print "args is:", args

...   print "kwargs is:", kwargs

...

·演示如下:


1

2

3

4

5

6

7

>>> func(name="xpleaf", age=22, hobby="Python")

args is: ()

kwargs is: {'hobby''Python''age'22'name''xpleaf'}

 

>>> func("cl", name="xpleaf", age=22, hobby="Python")

args is: ('cl',)

kwargs is: {'hobby''Python''age'22'name''xpleaf'}

·需要说明的时,由于*args参数在前,**kwargs参数在后,所以在执行函数时应该要按照这个顺序填写参数,否则会报错:


1

2

3

>>> func(name="xpleaf", age=22, hobby="Python""clyyh")

  File "<stdin>", line 1

SyntaxError: non-keyword arg after keyword arg


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

--return说明

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


1

2

3

4

5

def func():

        for in range(10):

                return i

result = func()

print result

·执行结果如下:


1

2

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

0

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

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

--yield说明

-代码改写1

·上面代码改写为:


1

2

3

4

5

6

7

8

import time

 

def func():

        for in range(10):

                time.sleep(1)

                yield 'Loop', i

result = func()

print result

·执行结果如下:


1

2

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

<generator object func at 0x7f06d4300c80>

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

-代码改写2

·上面代码改写为:


1

2

3

4

5

6

7

8

9

10

11

12

import time

 

def func():

        for 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()

·执行结果如下:


1

2

3

4

5

6

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

('Loop'0)

('Loop'1)

('Loop'2)

('Loop'3)

('Loop'4)

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

-代码改写3

·上面代码改写为:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

import time

 

def func():

        for 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'

·执行结果如下:


1

2

3

4

5

6

7

8

9

10

11

12

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要用在函数中,不能直接在循环中写,即在不是函数内的循环中写,如:


1

2

3

for in range(10):

        time.sleep(1)

        yield 'Loop', i


6.lambda函数(匿名函数)

--关于匿名函数的说明


1

2

3

4

5

6

7

8

9

10

11

12

lambda函数也叫匿名函数,即,函数没有具体的名称。先来看一个最简单例子:

def f(x):

return x**2

print f(4)

Python中使用lambda的话,写成这样

= 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:定义简单函数

·演示如下:


1

2

3

>>> g = lambda x:x**2

>>> g(4)

16

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

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


1

2

3

4

5

6

7

>>> g = lambda x:x**2

>>> g(4)

16

>>> g(4)

16    #直接引用上一次结果的指针

>>> g(6)

36    #新的操作,会重新引用变量

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

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

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


1

2

3

map(...)

    map(function, sequence[, sequence, ...]) -> list

#即前面第一个参数可以为一个函数,并将sequence交给该函数处理,这时可使用lambda函数

·演示如下:


1

2

3

4

5

6

7

8

>>> a = range(10)

>>> b = range(10)

>>> a,b

([0123456789], [0123456789])

>>> map(lambda x:x**2,a)    #定义1个参数

[0149162536496481]

>>> map(lambda x,y:x**y,a,b)    #定义两个参数

[1142725631254665682354316777216387420489]

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

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

·演示如下:


1

2

3

4

5

>>> 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值的排序:


1

2

3

4

>>> 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()函数中的参数关键字:


1

2

sorted(...)

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


7.Python内置函数

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

时间: 2024-09-17 07:00:46

【Python之旅】第三篇(一):Python函数的相关文章

【Python之旅】第二篇(三):基于列表处理的购物清单程序

1.基本需求     编写一个购物小程序,要求实现如下功能: (1)让用户输入工资: (2)输出购物菜单及产品价格: (3)计算用户是否可支付: (4)输出用户剩余的钱,问用户是否继续购物,如果选择继续,则继续进行,否则退出程序: (5)若钱不够,输出用户还需要工作多久才能买得起(这里暂不实现此功能). 2.实现基本思路     基本思路可如下所示:     在编写程序的时候即以该思路为主线,具体细节下面再提及. 3.实现细节     基于友好用户界面的原则,实现的细节可总结如下: (1)用户输

【Python之旅】第一篇:基于文件处理的登陆接口

1.基本需求     编写登陆接口,实现如下需求: (1)输入用户名密码 (2)认证成功后显示欢迎信息 (3)输错三次后锁定 2.实现细节 ·每添加一个用户,需要手动添加三个文件 文件 功能 username_count.txt 记录用户输错密码的次数,最大为3次,如果用户密码输入正确,则重置为0,默认为0 username_lock.txt 记录用户是否被锁定,1表示锁定,0表示未锁定,默认为0 username_passwd.txt 记录用户的密码 ·注:username是指该用户的用户名,

【Python之旅】第二篇(五):基于列表、字典和元组的员工信息处理接口

1.基本需求     编写一个查询员工信息表的程序,实现如下功能: (1)让用户输入不小于3个字符查询员工信息 (2)通过员工号或员工个人信息可以精确或模糊查询到员工信息 (3)输出员工信息 2.实现代码与注释    首先提供员工信息的txt文件: 1 2 3 4 xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ more student_info.txt  stu1101 mingjia.xu 275896019@qq.com 263 SystemAdm

【Python之旅】第二篇(四):字典

说明:     显然Python中字典的学习过程与列表是一样的,主要是围绕下面的函数来进行重点学习: 1 2 3 4 5 6 7 8 9 10 11 >>> xpleaf. xpleaf.clear( xpleaf.copy( xpleaf.get( xpleaf.has_key( xpleaf.items( xpleaf.keys( xpleaf.pop( xpleaf.popitem( xpleaf.setdefault( xpleaf.update( 1.基本操作 --创建一个字典

【Python之旅】第二篇(二):列表与元组

说明:     Python中的列表类似于其它高级语言中的数组,不过Python的列表操作起来要轻松很多.     Python中列表的学习主线主要是围绕对列表参数的操作使用上,重点关注的应该有如下这些: 1 2 3 4 5 6 7 8 9 names.append( names.count( names.extend( names.index( names.insert( names.pop( names.remove( names.reverse( names.sort(     下面的内容

【Python之旅】第二篇(一):Python文件处理

说明:     主要是file()和open()函数的使用,但在查open()函数的帮助时,会有下面的说明: 1 2 3 >>> help(open) -- Open a file using the file() type, returns a file object.     因此,两个函数其实都是一样的,下面只用file().     在列举file()的作用时,使用help即是很好的方法,下面则是应重点关注的内容: 1 2 3 4 5 6 7 8 9 10 11 12 13 14

【Python之旅】第二篇(九):迭代器

说明:关于Python中迭代器的解释     Iterator是迭代器的意思,它的作用是一次产生一个数据项,直到没有为止.这样在 for 循环中就可以对它进行循环处理了.那么它与一般的序列类型(list, tuple等)有什么区别呢?它一次只返回一个数据项,占用更少的内存.但它需要记住当前的状态,以便返回下一数据项.它是一个有着next()方法的对象.而序列类型则保存了所有的数据项,它们的访问是通过索引进行的.     举个前面的例子来说就像readlines和xreadlines的区别,rea

【Python之旅】第二篇(七):集合

说明: ·类似于数学中学的集合,Python中的集合可以实现去重的功能,通过set()函数来实现: ·sets支持x in set, len(set)和 for x in set: ·作为一个无序的集合,sets 不记录元素位置或者插入点,因此,sets不支持indexing, slicing,或其它类序列(sequence-like)的操作: ·学习集合,主要是学习集合的一系列标准操作:集合创建.集合添加.集合删除.交并差集等: 1.创建集合:set() 1 2 3 4 5 6 7 8 9 1

【Python之旅】第二篇(六):enumerate枚举

1.普通情况下打印列表中索引号及其对应元素     使用下面的循环: 1 2 3 4 5 6 7 8 >>> L = ['a', 'b', 'c', 'd'] >>> for i in L: ...   print L.index(i),i ...  0 a 1 b 2 c 3 d 2.使用enumerate在循环时同时访问索引     可以使用enumerate实现上面的功能: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

【Python之旅】第二篇(八):zip拉链与map拉链

1.zip拉链 ·功能:将两个列表合并起来,成为一个元素为元组的列表: ·演示如下: 1 2 3 4 5 6 7 8 9 10 >>> a = range(0,5) >>> b = range(5,10) >>> a [0, 1, 2, 3, 4] >>> b [5, 6, 7, 8, 9] >>> zip(a,b) [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)] >>&