函数(Functions
)是指可重复使用的程序片段。它们允许你为某个代码块赋予名字,允许你通过这一特殊的名字在你的程序任何地方来运行代码块,并可重复任何次数。这就是所谓的调用(Calling)函数。
def
关键词开头,后接函数标识符名称和圆括号()
。return [表达式]
结束函数,选择性地返回一个值给调用方。不带表达式的 return 相当于返回 None。return
可以返回多个值,此时返回的数据为元组类型。定义函数的语法格式:
# 定义函数时,带默认值的参数必须在无默认值的参数后面
def function_name(param1, param2, param3=None, param4=2):
body
在Python中,类型属于对象,变量没有类型
a = [1, 2, 3]
a = "Runoob"
以上代码中,[1,2,3]
是 List 类型,"Runoob"
是 String 类型,而变量 a
是没有类型,它仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。
可更改与不可更改对象:
在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
也会受影响
Python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
必须参数
必须参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
关键字参数
关键字参数和函数调用关系密切,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明不一致,因为Python解释器能够用参数名匹配参数值。
# 函数定义
def print_info(name, age):
"打印任何传入的字符串"
print("名字: ", name)
print("年龄: ", age)
return
# 函数调用
print_info(age=50, name="john") # 关键字参数,参数的顺序可以改变
默认参数
调用函数时,如果没有传递参数,则会使用默认参数。
# 函数定义
def print_info(name, age=35):
print ("名字: ", name)
print ("年龄: ", age)
return
# 函数调用
print_info(age=50, name="john")
print("------------------------")
print_info(name="john") # age 使用默认参数 35
不定长参数
*
的参数会以元组的形式导入,存放所有未命名的变量参数。def print_info(arg1, *vartuple): # vartuple是一个元组,用于存放函数调用时,传入的多余的参数
print("输出: ")
print(arg1)
for var in vartuple:
print (var)
return
print_info(10)
print_info(70, 60, 50)
*
的参数会以字典的形式导入。变量名为键,变量值为字典元素值。def print_info(arg1, **vardict):
print("输出: ")
print(arg1)
print(vardict)
print_info(1, a=2, b=3)
Python
使用 lambda
来创建匿名函数。
所谓匿名,意即不再使用 def
语句这样标准的形式定义一个函数。lambda
只是一个表达式,函数体比 def
简单很多。
lambda
的主体是一个表达式,而不是一个代码块。仅仅能在 lambda
表达式中封装有限的逻辑进去。 lambda
函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。 虽然 lambda 函数看起来只能写一行,却不等同于 C
或 C++
的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
# 语法格式
lambda [arg1 [,arg2,.....argn]]: expression
lambda
函数的返回值是其expression
表达式的值。
calc = lambda x,y: x/y if x>y else x*y # 匿名函数最多只支持三元运算,再复杂的判断不支持
print(calc(3,8))
print(calc(16,8))
print(func(3,8))
print(func(16,8))
Python 3 提供一种语法,用于为函数声明中的参数和返回值附加元数据。下面的例子是注解后的版本,特点在第一行:
def clip(text : str, max_len : 'int > 0' = 80) -> str:
"""
在max_len前面或后面的第一个空格处截断文本
"""
end = None
if len(text) > max_len:
space_before = text.rfind(' ', 0, max_len)
if space_before >= 0
end = space_before
else:
space_after = text.rfind(' ', max_len) # 返回字符串最后一次出现的位置,没有则返回-1
if space_after >= 0:
end = space_after
if end is None: # 没找到空格
end = len(text)
return text[:end].rstrip() # 删除字符串末尾指定的字符串,默认为空格
函数声明中的各个参数可以在:
后增加注解表达式(如text : str
)。
如果参数由默认值,注解放在参数名和 = 号之间(如max_len : 'int > 0' = 80
)。
如果注解有返回值,在 )
和函数末尾的:
之间增加 ->
和一个表达式。那个表达式可以是任何类型。注解中最常用的类型是类(如 str
或 int
)和字符串(如 'int > 0'
)。
注解不会做任何处理,只是存储在函数的annotations
属性(一个字典)中:
>>> from clip_annot import clip
>>> clip._annotations__
{
'text' : <class 'str'>, 'max_len' : 'int > 0', 'return' : <class 'str'>}
'return'
键保存的是返回值注解,即函数声明里以 ->
标记的部分。
Python对注解所做的唯一的事情是,把他们存储在函数的__annotations__
属性里。仅此而已,Python不做检查,不做强制,不做验证,什么操作都不做。
换句话,注解对Python解释器没任何意义。注解只是元数据,可以供IDE、框架和装饰器等工具使用。