定义函数
函数名称建议都用小写,参照PEP8
代码:
def greet(): #定义函数,注意冒号
"""显示简单的问候语""" #文档字符串的注释
print("Hello.")
greet()
a = greet #可以给定义的函数指定别名(函数名其实也是对象的引用)
greet() #调用定义的函数
a()
结果:
Hello.
Hello.
传递参数
定义函数时,可以同时定义需要传递的参数
代码:
def user_info(name, age): #定义函数的时候设定需要的参数
print("名字是:" + name + " 年龄是:" + str(age)) #age是int型,需要转化成字符串
user_info('葫芦娃', 1) #调用函数时传递参数过去,参数顺序必须相同
# user_info(name='葫芦娃', age=1) 或者用这种直接赋值的方式,这样顺序可以不固定
结果:
名字是:葫芦娃 年龄是:1
定义函数的时候可以指定参数的默认值,即调用时候没有传入参数时,则以默认值作为未传入的参数值。
ps: 默认参数一定要用不可变对象
代码:
def user_info(name, age=1): #age有默认值
print("名字是:" + name + " 年龄是:" + str(age))
user_info('葫芦大娃') #没有传入第二个参数
user_info('葫芦二娃')
user_info('蛇精', 100) #有传入参数,则按照传入的参数值执行逻辑
结果:
名字是:葫芦大娃 年龄是:1
名字是:葫芦二娃 年龄是:1
名字是:蛇精 年龄是:100
( 注意:定义函数有默认值的时候,有默认值的参数必须放在后边,如上边的age)
Tip:默认参数必须指向不变对象,不能是列表,字典等可变对象
代码:
def test(mylist=['s', 's']):
mylist.append('over')
return mylist
print (test()) # 第一次调用时候,默认值列表已经创建,变量mylist指向该列表
print (test()) # 第二次调用时,因为列表是可变的,没有产生新对象,所以会在原来列表上继续操作
def grow(name, age=18):
age = age + 1 # 函数里的+1运算产生了新的对象并由age指向,此时新的age以不是开始时的默认变量age
# now = age + 1 可换个名字,下面输出语句也要换,就是好理解而已
print ('name=' + name + '\nage=' + str(age) + '\n')
grow('ZhangSan') # 第一次调用时,age变量指向的整数是18,是不可变的
grow('ZhangSan') # 第二次调用时,因为整数是不可变的,所以age变量仍旧是指向整数18(函数里的+1运算产生了新的对象)
#age1和age2不是同一个
age1 = 18 #age1指向整数18
age2 = age1 #age2也指向整数18
age2 = age2 + 1 #因为整数是不可变的,所以age2+1操作后创建了新的对象,age2指向该对象
print (age1 is age2) # 所以age1和age2不同
#list1和list2是同一个
list1 = ['a', 'b']
list2 = list1
list2.append('c') #因为列表是可变的,所以list2.append操作后仍旧是该对象,list2仍旧指向它
print (list1 is list2) # 所以list1和list2相同
结果:
['s', 's', 'over']
['s', 's', 'over', 'over']
name=ZhangSan
age=19
name=ZhangSan
age=19
False
True
返回值
函数中可使用return
来返回该函数处理的一些数据,如列表,字典,字符串等
def get_info(first_name, last_name):
info= first_name + last_name
return info #此处将处理后的字符串返回
print(get_info('葫芦', '娃'))
结果:
葫芦娃
返回值可以是多个,用,
隔开。以元组的方式返回,例如
代码:
def myadd(x):
return x, x + 1
a = myadd(1)
print (a)
#a[0] = 20 #此句会报错,因为多个返回值是以元组的方式返回,不可更改
one, two = a #多个变量可同时接收同一个元组,按位置赋值,两边的个数多或少都会报错
print (one)
结果:
(1, 2)
1
返回列表和返回字典等同上,将函数体里的逻辑更换即可
传递任意数量的实参
在定义函数的时候,不知道需要接受多少个实参(同一种类的参数),可以用*
加上参数名,表示可接受多个参数(就是传递列表,元组→_→)
代码:
def cook_food(count, *toppings): # *toppings表示python创建了一个空元组,并将接收到的值加入到元组中
"""描述要制作的材料"""
print(str(count) + "份")
print(toppings)
cook_food(1, '葱', '姜', '蒜') # 先传固定的实参,再传不固定的参数
cook_food(10, '肉')
mylist = ['葱', '蒜', '鱼', '鸡']
cook_food(1, mylist) # 此句输出的是一个元组,但只有一个元素列表
cook_food(1, *mylist) # 此句是将参数mylist的所有元素,作为参数依次传递到函数里,输出的元组有四个元素
结果:
1份
('葱', '姜', '蒜')
10份
('肉',)
1份
(['葱', '蒜', '鱼', '鸡'],)
1份
('葱', '蒜', '鱼', '鸡')
传递任意数量的关键字实参
用**
加参数名,可以传递多个关键字实参(就是传递字典而且没有限制→_→)
代码:
def build_info(first, last, **user_info): # **user_info表示,创建一个空字典,并将接收到的键-值对加入到字典中
"""创建一个字典,包含用户的所有信息"""
info = {}
info['first_name'] = first # 添加字段
info['last_name'] = last
for key, value in user_info.items():
info[key] = value
return info # 返回字典
#可以封装成字典传入,但是必须加**,例如**dict,不可只传入字典
info = build_info('葫芦', '娃', ability='力气大', 排行=1)
print(info)
结果:
{'ability': '力气大', '排行': 1, 'first_name': '葫芦', 'last_name': '娃'}
命名关键字参数
用*
作为参数的分隔符,*
后边的即是只能传入的关键字参数(传递字典但是有限制→_→)
代码:
def student(name, age, *, address, tel): # 命名关键字可以有默认值
print(name, age, address, tel)
student('Tom', 22, address='china', tel=110) # 必须传入参数名address 和tel
结果:
Tom 22 china 110
命名关键字参数必须传入参数名,位置参数传入的位置顺序必须固定,命名关键字参数则没有顺序之分。
如果函数定义的参数中已经有一个任意数量的实参(注意不能是关键字实参即字典),则后边的命名关键字参数不在需要*
分隔。例如:
代码:
def student(name, age, *otherinfo, address, tel):
print(name, age, otherinfo, address, tel)
student('Tom', 22, 'nv', 180, address='china', tel=110)
结果:
Tom 22 ('nv', 180) china 110
递归函数
同大多数那样,自己调用自己的函数
e.g. 汉诺塔用递归实现
def move(n, a, b, c):
if n == 1:
print('move', a, '-->', c)
return
move(n-1, a, c, b) # A上的n-1个盘子通过C移动到B
print('move', a, '-->', c) # A上最底的盘子移动到C
move(n-1, b, a, c) # B上的n-1个盘子通过A移动到C
move(4, 'A', 'B', 'C')
结果:
move A --> C
move A --> B
move C --> B
move A --> C
move B --> A
move B --> C
move A --> C
将函数存储在模块中
函数的功能就是将逻辑代码块与主函数分离,可将函数写在其他文件中,然后倒入的要使用的文件里,使用import
语句。
1.导入整个模块(使用import xxx
语句)
先创建一个.py
文件
代码: greet.py
def greet_message(): #定义函数,注意冒号
"""显示简单的问候语""" #文档字符串的注释
print("Hello.")
在greet.py所在的目录下创建另一个.py
文件
代码: say.py
代码:
import greet # import语句,整个导入之前写的函数模块
# import greet as gt # 导入的时候可以用as,指定别名
greet.greet_message() # 使用moudle_name.function_name()的方式调用函数
# gt.greet_message() # 通过指定的别名,调用函数,指定别名后原模块名就不可用了
2.导入特定的函数(使用from xxx import xxx
语句)
代码同上,只不过将import greet
语句替换为from greet import greet_message
而且,在调用的时候只需要直接调用函数名即可,如greet_message()
,也可使用as
给函数指定别名