用户在定义函数时,需要使用关键字def、return。def是开始定义,return 是返回运算结果。def 关键字定义函数的语法如下:
def函数名(参数列表):
程序块
return 返回值列表
其中,参数列表与返回值列表可以为空,也可以为多个以逗号隔开的多个值。函数名必须是合法标识符。
一般程序员使用自定义函数进行编程,是为了降低编程难度与提高代码可复用度。把一个庞大的问题,进行细分,分解为一个一个的小问题,解决掉这些小问题,再组合这些小问题,就可以最终解决这个庞大的问题了。
1.函数形参不需要申明其类型,也不需要指定函数的返回值类型。
2.即使函数不需要接收任何参数,也必须保留一对空的括号。
3.括号后面的冒号必不可少。
4.函数体相对于def保留字必须保持一定的空格缩进hanshu
函数调用和执行的一般形式为:<函数名>(<参数列表>)
此时,参数列表中给出要传入函数内部的参数,这类参数称为实际参数,简称为“实参”
如果在不同源文件之间,调用别的源文件中已有函数,需要首先在源文件中导入这个函数。需要使用from、import关键字。
导入函数的语法如下:
from 位置 import 函数名
关键字return是用来返回程序运算结果的,这个结果可以是任意一个或多个数据类型,也可以返回什么都不返回。“返回什么都不返回”的意思,是在函数中,运算结束后,没有必要返回任何值,于是什么都不返回。
程序调用一个函数需要执行以下四个步骤:
(1)调用程序在调用处暂停执行;
(2)在调用时将实参复制给函数的形参;
(3)执行函数体语句;
(4)函数调用结束给出返回值,程序回到调用前的暂停处继续执行。
调用无参函数时,只需要直接使用函数名;调用有参数的函数时,则需要在函数名之后的括号中依次加入参数。(按照位置顺序依次传递)
有的时候,在编写程序的过程中,频繁的调用函数,有可能会忘记函数的形式参数出现的顺序,Python 给我们提供了关键字参数调用方法。只要在调用函数的过程中,指定函数参数名的关键字,就可以给函数传递值了。
记得参数顺序,就直接根据位置参数的出现顺序进行传递;忘记了顺序,就指定关键字。
在给函数传参数时直接将参数的值一起输入了!设置函数参数的默认值,一般在比较频繁的使用某些参数的固定值进行计算时使用。
一般形式:
def 函数名(.......,形参名=默认值):
函数体
由于函数调用时需要按顺序输入参数,默认参数必须定义在非默认参数的后面,如果在定义函数时某个参数的默认值为另一个变量的值,那么参数的默认值只依赖于函数定义时该变量的值,或者说函数的默认值参数是在函数定义时确定值的,所以只会被初始化一次。
Python允许在传递参数的时候,不给定参数个数,根据需要进行参数传递。可以简单的理解为:使用一些容器进行参数传递,所有的实际参数被一起放入容器中传递给函数,函数再针对容器中所有的参数进行编程。在下一章中,会介绍Python的序列化结构。本节中,仅仅介绍如何传递不定长的参数。生成这样一个容器, 需要使用:“ * ”
在使用过程中也有**parameter的形式,此类型接收显式赋值形式的多个实参并将其放入字典中
def demo(**p):
for item in p.items():
print(item)
demo(x=1,y=2,z=3)
('x', 1)
('y', 2)
('z', 3)
补充说明:
如果传递给函数的是列表、字典、集合或其他自定义的可变序列,并且在函数内部使用下标或序列自身支持的方式对可变序列增加、删除元素或修改元素值时,修改后的结果是可以反映到函数之外的,即实参也得到了相应的修改。
已知Python采用的是基于值的自动内存管理模式,变量并不直接存储值,而是存储值的引用。从这个角度来讲,在Python中调用函数时,实参到形参都是传递的引用,也就是说,Python函数不存在传值调用。
一般来说,在函数内部直接修改形参的值不会影响实参。 然而,列表、字典、集合这样的可变序列类型作为函数参数时,如果在函数内部通过列表、字典或集合对象自身的方法修改参数中的元素时,同样的作用也会体现到实参上。
前面介绍的参数传递的方式在定义函数或调用函数时可以混合使用,但是需要遵循一定的优先级规则,这些方式按照优先级从高到低依次为位置参数传递、按关键字参数传递、默认参数传递、按打包传递。
在定义函数时,带有默认值的参数必须位于普通参数(不带默认值或标识的参数)之后,带有*标识的参数必须位于带有默认值的参数之后,带有**标识的参数必须位于带有*标识的参数之后。
Python的有33个保留字,其中一个是lambda,该保留字用于定义一种特殊的函数——匿名函数,又称lambda函数。
匿名函数并非没有名字,而是将函数名作为函数结果返回,如下:
<函数名> = lambda <参数列表>: <表达式>
lambda函数与正常函数一样,等价于下面形式:
def <函数名>(<参数列表>):
return <表达式>
简单说,lambda函数用于定义简单的、能够在一行内表示的函数,返回一个函数类型,实例如下
>>>f = lambda x, y : x + y
>>>type(f)
>>>f(10, 12)
22
f=lambda x,y,z:x+y+z
f(1,2,3)
g=lambda x,y=2,z=3:x+y+z
g(1)
g(2,z=4,y=5)
L=[(lambda x:x**2),(lambda x:x**3),(lambda x:x**4)]
L[0](2)
L[1](2)
L[2](2)
f=lambda:i #无参数,只有表达式
i=3
f()
i=5
f()
Python中有局部变量与全局变量两种概念。
(1) 如果没有特别声明,函数中的变量,默认都是局部变量,只在本函数中起到作用,变量的作用域 范围被固定在了单个函数中。
(2) 如果使用了关键字“global”修饰了变量,那被修饰的变量就变成了全局变量,变量的作用域范围 扩大到了整个程序。
作为初学者,一般界定使用全局变量还是局部变量,是看这个变量是否被全部程序共同使用。如果没有被全部程序使用到,建议在函数中使用默认的局部变量方式进行数据处理,在函数根据变量进行完运算之后,使用返回值传递运算结果。
不同函数内部可以包含同名的局部变量,这些局部变量的关系类似于不同目录下同名文件的关系,它们相互独立、互不影响。
def test_one():
number=10
print(number)
def test_two():
number=20
print(number)
test_one()
test_two()
全局变量可以在整个程序的范围内起作用,它不会受函数范围的影响。
number=10
def test_one():
print(number)
test_one()
print(number)
#需要注意,全局变量在函数内部只能被访问,而无法直接修改。
number=10
def test_one():
print(number)
number+=1
test_one()
print(number)
函数内部无法直接修改全局变量或在嵌套函数的外层函数声明的变量,但是可以使用global或nonlocal关键字修饰变量以间接修改以上变量。
使用global关键字可以将局部变量声明为全局变量。 一般形式为: global 变量
number=10
def test_one():
global number
number+=1
print(number)
test_one()
print(number)
使用nonlocal关键字可以在局部作用域中修改嵌套作用域中声明的变量,一般形式为:nonlocal 变量
def test_one():
number=10
def test_in():
nonlocal number
number=20
test_in()
print(number)
test_one()
默认的局部变量的作用域范围仅仅局限在函数中,函数中的局部变量没有return的话,就不会被传递到函数之外。而全局变量的作用域范围是超越函数的,从被声明为global的那一刻起,整个源文件中的全局变量都会保持一致
Python函数对变量的作用遵守如下原则:
1.简单数据类型变量无论是否与全局变量重名,仅在函数内部创建和使用,函数退出后变量被释放;
2.简单数据类型变量在用global保留字声明后,作为全局变量;
3.对于组合数据类型的全局变量,如果在函数内部没有被真实创建的同名变量,则函数内部可直接使用并修改全局变量的值;
4.如果函数内部真实创建了组合数据类型变量,无论是否有同名全局变量,函数仅对局部变量进行操作。