python 学习笔记 4 -- 函数篇

时间:2021-01-23 17:12:43
本文主要是针对python的函数定义做的笔记,详细记录各种需要了解的知识,比如规范、参数、返回值、局部变量、全局变量以及doc_string的相关知识,使用大量简单例子作为解释更容易理解!

1.定义函数

函数通过def关键字定义。def关键字后跟一个函数的 标识符 名称,然后跟一对圆括号(圆括号之中可以包括一些变量名) ,该行以冒号结尾。接下来是一块语句,它们是函数体(因为python的语法,所以在冒号后面接着的函数题需要缩进!!)。下面这个例子将说明这事实上是十分简单的:
def sayHello():
print 'Hello World!'           # 缩进的函数体是对函数的具体操作


2.函数形参 

     参数在函数定义的圆括号对内指定,用逗号分割。当我们调用函数的时候,我们以同样的方式提供值。

注: 函数中的参数名称为 形参 而你提供给函数调用的值称为实参 。说简单点可以认为在定义函数时的参数叫做形参,在正式使用函数时给函数传递的参数叫做实参!

x(a, b):                      # 在定义函数printMax时传递形参a和b(以逗号分割),
a、b用以在定义函数操作的函数体内使用,用以描述函数的使用参数的操作!而在使用时被
实参替代后,真实的操作逻辑会在实参上运行并打印与实参对应的结果!
if a > b: # 定义函数体中使用if判断,当然if判断的
缩进也是必需的!
print a, 'is maximum'
else:
print b, 'is maximum'

注: Python 的形参可不只是这么普通!python的参数比较有特色的是可以传递多值!这也与给整个python传递多个参数有类似之处!下面我们来一个一个分析:

2.1 Python 脚本传递参数

此处的脚本指的是你写的.py程序,你知道如果你想运行这个argv.py你只需要使用" python argv.py "即可,那么如果你想给脚本带入参数可以参照下面方法:

# -*- coding: utf-8 -*-                                             # 还记得他是干啥的不?
from sys import argv # import语句是将python的功能引入你的脚本中,python不会将所有的功能都给你,而是你指定要什么它才给你什么!
script,first,second,third = argv # 本局将几个参数分别赋值给script,first,second,third ,script得到的就是这个脚本!first,second,third 分别得到的是你带入的第一个第二个第三个参数!
# 注意下面这四个打印语句,我分别用了不一样的方法,大家参照运行结果观察打印语句的不同!
print"The script name is ",script # 本句直接使用print 接一个双引号的字符串再接一个变量
print"The first parameter is %s " % first # 本句使用大家很熟悉的%s参数,注意python的不同是在变量前还需要添加一个%!
print"The second parameter is %r " % second # 本句使用的%r参数比较特殊,它一般用于debug,所以它会打印带入的详细信息,而不会优化一些内容!比如打印 \n 他就直接打印'\n'而不会自动转换成换行符!
print"The third parameter is "+third # 本句和第一句类似,只不过使用+链接字符串和一个变量!

运行结果是这样的!~
long@zhouyl:~$ vim /tmp/test.pylong@zhouyl:~$ python /tmp/test.py you he meThe script name is  /tmp/test.pyThe first parameter is youThe second parameter is 'he'The third parameter is me


2.2 定义函数时传递参数

这么神奇的带入脚本参数会不会影响函数的形参带入?答案是 Yes! 上面提到的def printMax(a, b): 只是最普通的带参!下面这个会吓尿你:

# -*- coding: utf-8 -*- 
def print_two(*args): # 关注下这个函数,我带入的是一个以*开头的args参数,其实这个*args与指针比较类似,可以理解为把所有的参数接受后存入一个args的列
表中(列表在后面的博客中会提到)
arg1,arg2 = args # 是不是与上面的脚本参数比较类似?
print "args1:%r,arg2:%r" % (arg1,arg2)

def print_two_again(rg1,arg2):
print "args1:%r,arg2:%r" % (arg1,arg2)

def print_one(arg1):
print "args1:%r" % arg1

def print_none():
print "I got nothing"

print_two("Zhou","Zhang")
print_two_again("Zhou","Zhang")
print_one("Zhang")
print_none()

运行起来你可以想象一下:

long@zhouyl:~/python_test/lpthw$ python ex18.py
arg1:'Zhou',arg2:'Zhang'
arg1:'Zhou',arg2:'Zhang'
arg1:'Zhang'
I got nothing



2.3.默认参数值

对于一些函数,你可能希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。

def say(message, times = 1):
print message * times

注: 只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明有默认值的形参而后声明没有默认值的形参。 这是因为赋给形参的值是根据位置而赋值的。例如,def func(a, b=5)是有效的,但是def func(a=5, b)是 无效 的。

2.4.关键参数

如果你的某个函数有许多参数,而你只想指定其中的一部分,那么你可以通过命名来为这些参数赋值——这被称作 关键参数 ——我们使用名字(关键字)而不是位置(我们前面所一直使用的方法)来给函数指定实参。
这样做有两个 优势 :
(1) 由于我们不必担心参数的顺序,使用函数变得更加简单了。

(2) 假设其他参数都有默认值,我们可以只给我们想要的那些参数赋值。

def func(a, b=5, c=10):
print 'a is', a, 'and b is', b, 'and c is', c
func(3, 7)
func(25, c=24)
func(c=50, a=100)



3.返回值

python的函数返回值与其他语言类似,使用return做返回值的关键字。而且……有了这么奇葩的参数,返回值当然也不甘寂寞了!可以返回多个值哦

不信?请看示例:

# -*- coding: utf-8 -*- 
def secret_formula(started): # 定义一个函数,做了简单运算!
jelly_beans = started * 500
jars = jelly_beans / 1000
crates = jars / 100
return jelly_beans, jars, crates # 返回多个值!


start_point = 10000
beans, jars, crates = secret_formula(start_point) # 使用这种方法接收返回值!是
不是感脚与上面讲的参数比较类似


print "With a starting point of: %d" % start_point
print "We'd have %d beans, %d jars, and %d crates." % (beans, jars, crates) # 分
别打印我们接受到的几个返回值


start_point = start_point / 10
print "We can also do that this way:"
print "We'd have %d beans, %d jars, and %d crates." % secret_formula(start_point) # 其实~灵活的python可以直接打印返回值的啦!
运行结果可以想象:

$ python ex24.py
With a starting point of: 10000
We'd have 5000000 beans, 5000 jars, and 50 crates.
We can also do that this way:
We'd have 500000 beans, 500 jars, and 5 crates.



4.局部变量

当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的。这称为变量的 作用域 。所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开始。


5.全局变量

如果你想要为一个定义在函数外的变量赋值,那么你就得告诉Python这个变量名不是局部的,而是全局 的。我们使用global语句完成这一功能。没有global语句,是不可能为定义在函数外的变量赋值的。

你可以使用定义在函数外的变量的值(假设在函数内没有同名的变量)。然而,我并不鼓励你这样做,并且你应该尽量避免这样做,因为这使得程序的读者会不清楚这个变量是在哪里定义的。使用global语句可以清楚地表明变量是在外面的块定义的。


6.DocStrings

你可以使用__doc__(注意双下划线)调用定义函数的文档字符串属性(属于函数的名称)。如下例子所示:

# -*- coding: utf-8 -*-
def printMax(x, y):
'''Prints the maximum of two numbers.
The two values must be integers.'''
print"x=%s,y=%s" % (x, y)
if x > y:
print "%s is more bigger than %s" % (x, y)
else:
print "%s is more bigger than %s" % (y,x)

printMax(3, 5) # 正常使用函数
print "This is the doc message about printMax function:\n"+printMax.__doc__ # 打印函数的doc信息

运行结果是这样的!
long@zhouyl:~/python_test/lpthw$ python doc.pyx=3,y=55 is more bigger than 3This is the doc message about printMax function:Prints the maximum of two numbers.    The two values must be integers.


7.Lambda函数

Python支持一种有趣的语法,它允许你快速定义单行的最小函数,这些叫做lambda的函数,是从Lisp中借用来的,可以用在任何需要函数的地方。
eg.
    >>> def f(x):       # 普通的函数定义,返回值为参数乘2    ...     return x*2
...
>>> f(3) # 普通定义的函数定义,使用函数名加参数,最普通不过
6
>>> g = lambda x:x*2 # 这就是我们所说的lambda函数,说完成的功能与上面的普通函数一样。
# 注意:1、整个函数定义在一行内完成
# 2、参数列表周围没有括号,而且忽略了return关键字(隐含存在,因为整个函数只有一行),提一下:lambda函数可以接收任意多个参数(也可以使用可选参数)并且返回单个表达式的值。
# 3、该行数没有函数名称,但是可以将它赋给一个变量,这个变量就相当于函数名,从下面调用此函数可以看出!
>>> g(3)
6
>>> (lambda x:x*2)(3) # 使用lambda函数时可以不赋值给变量(通过变量调用),直接带参使用,这也展示了lambda函数是一个内联函数。
6

Lambda函数是一种代码风格,不一定要使用它们,而且任何能够它们的地方,都可以定义一个单独的普通函数来实现。