函数
定义函数
语法
# def + 函数的名字 + (参数)
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]
举个例子:
def sum( a,b ):
c = a + b
return c
这个函数的意思就是,接受两个参数a
和b
,在函数中定义一个变量c
,令这个变量c等两个参数之和,最后把这个c
返回。
所以这个函数本质上是用于返回一个数
,不知道什么是返回值看下面的调用。
调用函数
def sum( a,b ):
c = a + b
return c
number = sum(1,2)
print(number)
# 2
同样这里需要注意缩进
可以看到,这里直接让number=sum(1,2)
,把这两个参数代入一开始定义的函数当中去,会发现这个时候c=2
,也就是说这一条赋值的语句的真正意思应该是number = c =2
。但是这里直接把c省略,所以这里number直接就等于2.
定义空函数
如果想定义一个什么事也不做的空函数,可以用pass语句:
def nop():
pass
返回多个值
def move(x, y, step ):
nx = x + step
ny = y + step
return nx, ny
x,y =move(1,2,3)
print(x,y)
# 4 5
参数传递(重点)
可更改和不更改对象
在 python 中,**字符串, 元组, 和数字**
是不可更改的对象,而 **数组,字典**
等则是可以修改的对象。
- 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
- 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
- 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响。
简单来说,字符串, 元组, 和数字 作为参数传入的时候,不改变参数原本的值。 数组,字典 作为参数传入的时候,改变参数原本的值。
举个例子:
传入不可变类型
def ChangeInt( a ):
a = 10
b = 2
ChangeInt(b)
print b # b的结果是 2
传入可变类型
mylist = [10,20,30]
# 可写函数说明
def changeme( mylist ):
#"修改传入的列表"
mylist.append(40)
print ("函数内取值: ", mylist)
return
# 调用changeme函数
changeme( mylist )
print ("函数外取值: ", mylist)
# 输出结果如下
# 函数内取值: [10, 20, 30, 40]
# 函数外取值: [10, 20, 30, 40]
关键字参数
函数调用使用关键字参数来确定传入的参数值。
def printinfo( name, age ):
"打印任何传入的字符串"
print ("Name: ", name)
print ("Age ", age)
return
#调用printinfo函数
printinfo( age=50, name="miki" )
# 输出结果如下
# Name: miki
# Age 50
默认参数
# 如果没有传入age的值,则默认age的值是35
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("Name: ", name)
print ("Age ", age)
return
#调用printinfo函数
printinfo( age=50, name="miki" )
printinfo( name="miki" )
# 输出结果如下
# Name: miki
# Age 50
# Name: miki
# Age 35
不定长参数
星号(*)的变量名会存放所有未命名的变量参数。
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print "输出: "
print arg1
for var in vartuple:
print var
return
# 调用printinfo 函数
printinfo( 10 )
printinfo( 70, 60, 50 )
# 输出结果如下
# 第一个printinfo
# 10
# 第二个printinfo
# 70
# 60
# 50
这边的vartuple可以理解为一个数组。把arg1后面所有的参数都存入到这个数组当中。 所以一般这种都是放在定义函数的最后一个参数的位置。
匿名函数
- lambda只是一个表达式,函数体比def简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
上面的定义看不懂没关系,看例子知道形式即可。
sum = lambda arg1, arg2: arg1 + arg2
# 这个就等同于
# def sum(a,b):
# c = a + b
# return c
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
# 输出结果如下
# 相加后的值为 : 30
# 相加后的值为 : 40
稍微拆分一下就可以得出,lambda表达式的结构就是 lambda + 参数 + : + 函数体
变量的作用域
一般情况下,函数内部是不能改变函数外变量的值的,比如:
sum = 0
def function():
sum = 1
function()
print(sum)
# 0
可以发现,这里虽然调用了函数,函数内部令sum=0
了,但是并没有真正改变函数外sum
的值。
这是因为函数内部的变量只作用在函数内部。
那么如果想要在函数内部修改函数外部的值,就需要使用global
关键词。
sum = 0
def function():
global sum
sum = 1
function()
print(sum)
# 1
函数的递归
所谓递归,就是在函数里面调用函数自己。
举个例子:
我们来计算阶乘n! = 1 x 2 x 3 x … x n,用函数fact(n)表示
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
fact(5)
# 120
递归的过程如下:
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
递归了解即可,后面会详细讲解
附赠:经典汉诺塔问题
def move(n, a, b, c):
if n == 1:
print(a, '-->', c)
else:
move(n-1,a,c,b)
move(1,a,b,c)
move(n-1,b,c,a)
move(3, 'A', 'B', 'C')
局部变量和全局变量
简单粗暴的来归纳一下就是:
- 在函数内定义的变量基本都是局部变量
- 在函数外定义的变量基本都是全局变量
下面是关于局部变量和全局变量的详细解析:
python的 局部变量和全局变量_Vincent_ceso的博客-CSDN博客_python 局部变量
一般来讲,函数不能调用全局变量的,也就是不能改变函数外变量的值。
如果想要调用,就要使用global
关键词
举个例子:
Money = 2000
def AddMoney():
# 表明Money是全局变量
global Money
Money = Money + 1
print Money
AddMoney()
print Money
模块
模块的定义
Python的模块就类似于Java当中的类,非常好理解。<br />举个例子:<br />这里创建两个python文件,`support.py`以及`test.py`<br />**supprot.py**
# support.py 模块:
def print_func( par ):
print ("Hello : ", par)
return
**test.py**
# 导入模块
import support
# 现在可以调用模块里包含的函数了
support.print_func("Runoob")
# Hello : Runoob
总结一下就是:
- 首先在另外一个
python
文件中定义相关的函数变量等 - 在其他的
python
文件中使用import
进行导入文件 - 导入完成之后就可以通过导入的文件名称调用文件的函数等
模块语法
import
这个没什么好说的,就是单纯的导入模块 ```python导入模块
import support
现在可以调用模块里包含的函数了
support.print_func(“Runoob”)
Hello : Runoob
<a name="TqPjO"></a>
#### from import
Python 的 from 语句让你从模块中**导入一个指定的部分**到当前命名空间中。语法如下:
```python
# 导入support模块中的 print_func方法
from support import print_func
# 现在可以调用模块里包含的函数了
print_func("Runoob")
# Hello : Runoob
如果需要导入所有的部分,就只需要是 `import *`即可
# 导入support模块中的 print_func方法
from support import *
# 现在可以调用模块里包含的函数了
print_func("Runoob")
# Hello : Runoob
as
as
的作用就是给导入的模块取别名,以此简化书写,或者避免函数同名冲突:
# 导入support模块中的 print_func方法 并且取别名为pf
from support import print_func as pf
# 现在可以调用模块里包含的函数了
pf("Runoob")
# Hello : Runoob
模块相关函数(了解即可)
dir()函数
dir() 函数一个排好序的字符串列表,内容是一个模块里定义过的名字。
返回的列表容纳了在一个模块里定义的所有模块,变量和函数。如下一个简单的实例:
# 导入内置math模块
import math
content = dir(math)
print content;
以上实例输出结果:
['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
在这里,特殊字符串变量name指向模块的名字,file指向该模块的导入文件名。
globals() 和 locals() 函数
根据调用地方的不同,globals() 和 locals() 函数可被用来返回全局和局部命名空间里的名字。
如果在函数内部调用 locals(),返回的是所有能在该函数里访问的命名。
如果在函数内部调用 globals(),返回的是所有在该函数里能访问的全局名字。
两个函数的返回类型都是字典。所以名字们能用 keys() 函数摘取。
reload() 函数
当一个模块被导入到一个脚本,模块顶层部分的代码只会被执行一次。
因此,如果你想重新执行模块里顶层部分的代码,可以用 reload() 函数。该函数会重新导入之前导入过的模块。语法如下:
reload(module_name)
在这里,module_name要直接放模块的名字,而不是一个字符串形式。比如想重载 hello 模块,如下:
reload(hello)
原文链接: