函数
函数可以理解为:为一段代码命名,之后可以通过函数名来方便的使用代码。
通过def来定义一个函数:
>>> def PrintHello():
print("Hello")
>>> PrintHello()
Hello
这里建立了一个函数,功能是输出“Hello”,之后通过其函数名调用了它的功能。
函数有一些特殊的性质:
>>> def Create():
a = (1,2,3)
>>> Create()
>>> a[0]
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
a[0]
NameError: name 'a' is not defined
在这里的函数中我们定义了元组a,但在函数执行结束后,我们使用a时,编译器却提示我们a未定义。
因为函数与代码块不同,如果将程序比作一间工作室,那么函数就是工作室里的一间小隔间,函数可以使用工作室里的资源进行工作,最终的成预期的要求,但中途的过程与工作室无关(除非它改变了工作室里的变量),小隔间的工作是独立于工作室的。
>>> def Print():
print(a[0])
>>> a = (1,2,3)
>>> Print()
1
虽然函数定义的时候没有a的存在,但当这个小隔间开始工作时,它会在工作室里找到a来完成自己的工作。
>>> def Print():
print(a[0])
>>> Print()
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
Print()
File "<pyshell#11>", line 2, in Print
print(a[0])
NameError: name 'a' is not defined
如果工作室里没有a将会报错。函数修改已有值的情况:
def NO():
if i == 0:
i = 1
else:
i = 0
>>>
>>> i = 0
>>> NO()
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
NO()
File "<pyshell#19>", line 2, in NO
if i == 0:
UnboundLocalError: local variable 'i' referenced before assignment
!!!居然报错了,之前的函数表明我们的小隔间可以访问工作室里的变量,但函数NO()中对i的值进行判断时出错了。
这里引用两个新概念:全局变量和局部变量。
全局变量就是指在工作室里定义的变量,你可以当其被定义后在程序的如何地方使用。
而局部变量就是指在函数中定义的变量,一旦函数结束局部变量就消失,这也是小隔间工作独立于工作室的原因。
在上面的例子中,我们不仅执行了“i == 0”的语句,还执行了“i = 1”的语句,py把这一句理解为定义局部变量i,使用在i被定义前就使用它自然是会报错的。那我们该怎么做呢,py提供关键字global用于标记变量是全局变量
>>> def NO():
global i
if i == 0:
i = 1
else:
i = 0
>>> i = 0
>>> NO()
>>> if i:
<span style="white-space:pre"> </span>print("victory")
<span style="white-space:pre"> </span>
victory
为函数命名
函数命名第一原则:要求函数名可以反映函数的功能。想想以后写了几百个函数,起来一堆意义不明的名字,用起来是不是很难受。当你遗忘了一个函数是干什么的时候,函数名是帮助你回忆的最好工具。
描述函数
在定义函数之后,如果以一个字符串作为函数的第一部分,py将会把它认为是函数的描述:
>>> def NO():
"""改变i的逻辑值,如果为1就变为0,如果为0就变为1"""
global i
if i == 0:
i = 1
else:
i = 0
>>> NO.__doc__
'改变i的逻辑值,如果为1就变为0,如果为0就变为1'
我们通过函数名(不要加括号)来使用__doc__方法,输出函数的说明。
我们还可以使用注释来帮助理解我们的程序:
>>> def NO():
global i #声明全局变量
if i == 0: #判断i的值
i = 1
else:
i = 0
在井号之后的东西不会对程序产生影响。为函数提供值
我们之前可以让函数使用全局变量来产生效果,但这些值对程序全局可见,这种行为只对小程序有效。
我们可以在函数创建时指明它需要的参数:
<pre name="code" class="python"><pre name="code" class="python">
</pre><pre name="code" class="python">>>> def Print(str):
print(str)
>>> s = "hello"
>>> Print(s)
hello
这里我们定义了一个自己的Print函数,它会输出通过给他的参数。可以为函数设定默认的值:
>>> def Print(str = "hello"):
print(str)
>>> Print()
hello
函数有默认值时可以不提供参数直接使用。
此外函数的参数实质是新建一个变量再将值赋给它,所以在函数中修改参数的值不会影响原变量。
函数返回值
用return来结束函数并返回一个值:
>>> def Min(a,b):
if a > b:
return b
else:
return a
>>> print(Min(100,30))
30
1.有返回值的函数在被调用时就相当于一个变量,值为其计算结果。
2.函数一旦运行到return就结束了。
*和**
有时候我们不知道函数需要多少参数,这时候就需要单星号登场了,单星号参数接受多个参数,并归纳成一个元组:
>>> def fun(a,*b):
print(a)
print("length:%d"%len(b))
for i in b:
print (i)
>>> fun(1,2,3,4,5,6,7,8)
1
length:7
2
3
4
5
6
7
8
说双星号之前先说另一个东西,目前函数的参数是基于顺序来匹配的,其实还可以指明赋值(关键字赋值):
>>> def fun2(a,b):
print(a)
print(b)
>>> fun2(b = 100,a = 20)
20
100
而双星号的作用就是将所有未被使用的关键字整合进一个字典里:
>>> def fun3(a,**b):
for i in b:
print(i)
print(b[i])
>>> fun3(a = 1,d = 4,c = 2)
d
4
c
2
函数的层次
1,函数内也可以调用函数:
>>> def FindMax(a):
flag = 0
for i in range(len(a)-1):
if(a[i] > a[flag]):
flag = i
return flag
>>> def PrintMax(a):
print(a[FindMax(a)])
>>> PrintMax((1,2,3,2,6,3))
6
这里的PrintMax函数就调用了FindMax函数。
2,在函数内定义函数
有时候我们会把一个函数中简单的使用频率高的代码段定义为函数,但我们并不希望这个小函数被程序或其他函数调用,那么可以在把小函数定义在大函数内部:
>>> def CountFruits(a):
def isFtuits(str):
if str == "Apple":
return True
elif str == "Banana":
return True
else:
return False
count = 0
for s in a:
if(isFtuits(s)):
count = count + 1
return count
>>> CountFruits(("Cat","Banana","Apple","Cat","Apple"))
3
此时我们无法调用isFruits进行判断,只能通过CountFruits来使用它。