python基础-函数
函数
下面是一个最基本的函数
def greet():
print('esay')
greet()再看一个例子
def animals(name, age):
print('动物的年龄是' + str(age) + '岁,名字是' + name)
animals('dog', 3)
animals(age = 5, name = 'cat')形参与实参
animals(name, age)中,name和age是形参;而animals('dog',3)中的('dog',3)是实参。
实参又可以分为位置实参和关键字实参。
// 位置实参
animals('dog', 3) 传入的参数顺序与形参的顺序相同
// 关键字实参
animals(age = 5, name = 'cat') 通过关键字关联实参与形参的对应,顺序不重要设置函数默认参数值
def animals(name, age = 16):
xxx让函数返回处理结果,并给其设置默认参数
def connect_name(firstName, lastName, middleName = ''):
if middleName:
fullName = firstName + middleName + lastName
else:
fullName = firstName + lastName
return fullName
print( connect_name('wu', 'bin') )
print( connect_name('wu', 'tong', 'tong') )同样的函数也能返回字典
def getDirr(first, last):
obj = { 'first': first, 'last': last }
return obj
print( getDirr('wu', 'bin') )注意 函数中 不能写 return obj = {'..': xxxx} 连起来写就会报错 必须像上面例子那样分行写
结合while实现一个用户输入姓名,然后返回名字的功能,输入q则结束循环
def inputerYourName(first, last):
fullName = first + ' ' + last;
return fullName.title()
while True:
print('请告诉我你姓什么:')
print('输入q会跳出循环')
fname = input('姓')
if fname == 'q':
break
lname = input('名')
if lname == 'q':
break
full_name = inputerYourName(fname, lname)
print(full_name)函数中是可以修改传入的列表的
将列表传递给函数后,函数就可以对其进行修改,而且函数对这个列表所做的任何修改都是永久性的!
下面看一个例子
def print_works(works, finishs):
# 遍历数组 直到遍历完所有元素
while works:
# 从数组末尾中取一个项 pop()会从works列表末尾移除最后一项 并返回
currentWork = works.pop()
print('正在做的是' + currentWork)
finishs.append(currentWork)
def show_finish(finishs):
print('以下是全部完成的工作')
for finish in finishs:
print(finish)
works = ['#1工作', '#2work', '#3work', '#4work']
finishs = []
print_works(works, finishs)
show_finish(finishs)正在做的是#4work
正在做的是#3work
正在做的是#2work
正在做的是#1工作
-----------以下是全部完成的工作--------
#4work
#3work
#2work
#1工作pop()会从数组中移除最后一项,并返回被移除的项,直到works为空
上面就是最终运行的结果,可以发现,数组变量已经被修改了
哪怕我修改变量名,结果也是一样
works_ppp = ['#1工作', '#2work', '#3work', '#4work']
finishs_ppp = []
print_works(works_ppp, finishs_ppp)
show_finish(finishs_ppp)再来看一个更好理解的例子
def changelist(nums):
for item in nums:
# item = item + 1 这样写不会改变传递进来的nums数组
nums[item - 1] = item + 1
testlist = [1, 2, 3, 4]
changelist(testlist)
print(testlist)最终输出的结果就是:[2, 3, 4, 5],testlist被改变了!
但是,如果在函数中,使用单纯的赋值,是改变不了传入的列表的!
def changelist(nums):
newarr = []
for item in nums:
item = item + 1
newarr.append(item)
nums = newarr // 赋值会改变nums,但不会改变外部的testlist
print(nums)
print('---')
testlist = [1, 2, 3, 4]
changelist(testlist)
print(testlist)运行结果
[2, 3, 4, 5]
---
[1, 2, 3, 4]所以结论就是,如果要在函数内部修改传入的外部列表,只有直接修改传入列表中的项才可以
禁止函数修改传入的列表
解决这个问题很简单,只要让传入的是一个列表的副本就行
function_name(list_name[:])切片表示法[:] 代表创建一个列表的副本,比如上面例子中,如果不想要清空外部的工作列表works,可以像下面这样使用:
def print_works(works, finishs):
# 遍历数组 直到遍历完所有元素
while works:
# 从数组末尾中取一个项
currentWork = works.pop()
print('正在做的是' + currentWork)
finishs.append(currentWork)
def show_finish(finishs):
print('-----------以下是全部完成的工作--------')
for finish in finishs:
print(finish)
works = ['#1工作', '#2work', '#3work', '#4work']
finishs = []
print_works(works[:], finishs)
show_finish(finishs)
print('=========以下是原本works===========')
print(works)运行结果
正在做的是#4work
正在做的是#3work
正在做的是#2work
正在做的是#1工作
-----------以下是全部完成的工作--------
#4work
#3work
#2work
#1工作
=========以下是原本works===========
['#1工作', '#2work', '#3work', '#4work']通过传入副本,让原本的works中的数据没有被删除。没有影响外部的列表。
建议:还是推荐将原始列表传递给函数,因为让函数使用现成列表可以避免花时间和内存创建副本,从而提高效率,特别是列表比较大的时候。
任意数量的实参
当预先不知道需要接收多少实参时,使用*形参名,无论传入多少实参,都会被其接收,如下
def make_cook(*toppings):
print(toppings)
make_cook('面条', '米饭')
make_cook('大头菜', '馒头', '鸡肉', '等等更多')topping可以是任意名称,*everyname
最终打印结果
('面条', '米饭')
('大头菜', '馒头', '鸡肉', '等等更多')形参名*topping中的*让py创建了一个名为topping的空元组,并将接收到的所有值都封装到这个元组中。
即使一个值也会如此,比如('面条')
因此接下来就可以对元组进行遍历,以处理传入的所有参数。
def make_cook(*everyname):
print(everyname)
for name in everyname:
print('=' + name)
make_cook('面条', '米饭')
make_cook('大头菜', '馒头', '鸡肉', '等等更多')结果
('面条', '米饭')
=面条
=米饭
('大头菜', '馒头', '鸡肉', '等等更多')
=大头菜
=馒头
=鸡肉
=等等更多结合位置实参和任意数量实参
注意,任意数量的形参,比如放在最后
def make_cook(size, *everyname):
print('要做的菜尺寸是' + str(size))
for name in everyname:
print('=' + name)
make_cook(16, '大头菜', '馒头', '鸡肉', '等等更多')要做的菜尺寸是16
=大头菜
=馒头
=鸡肉
=等等更多有时候,需要接收任意数量的实参,但预先不知道传递给函数的会是什么样的信息,这时,可将函数编写成能接受任意数量的键值对。
比如,将收到用户有关信息,但不确定是什么样的信息。
def build_profile(first, last, **user_info):
# 创建一个字典
profile = {}
profile['first'] = first
profile['last'] = last
for key, value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile(
'wu',
'bin',
age = 35,
sex = '男',
job = '信网'
)
print(user_profile)此函数要求提供姓名,以及允许用户根据需求提供任意数量的 名称=“值”,这样形式的键值对。
形参**user_info中的两个星号让py创建一个名为user_info的空字典,并将所有接收到的 名称=值 都封装到这个字典中,可以像访问其他字典那样访问user_info中的名称=值对。
在build_profile函数中,将固定的姓名首先加入字典,其次遍历**user_info字典中的键值对,将每个属性以及对应的值也加入到profile字典中,最后返回这个字典。
结果:{'first': 'wu', 'last': 'bin', 'age': 35, 'sex': '男', 'job': '信网'}
在实际开发中,可以混用位置实参、关键字实参、任意数量实参。
函数存储在模块中
函数可以存储在独立的文件中,叫做模块。
import允许当前主程序中使用模块中的代码。
在同一个目录下创建两个文件,test.py和fns.py
在fns.py中写函数:
def funtest(num):
print( num + 1 )在test.py中
import fns # 引入整个函数模块
# 调用fns文件中的函数
fns.funtest(2)使用import导入了名为module_name.py的整个模块,就可以使用
module_name.function_name()来使用其中任何一个函数。
导入特定的函数
from module_name import function_name还可以用逗号分隔函数名,从模块中导入任意数量的函数
from module_name import function_0, function_1, function_2比如,fns.py
def fun1(num):
print( num + 1 )
def fun2(num):
print(num - 1)test.py
from fns import fun1
fun1(2)from fns import fun1, fun2
fun1(2)
fun2(10)使用这种形式的时候,就不用使用fns.xx了,因为都已经显示的导入了函数,所以就无需再指定其名称了。
使用别名as
如果导入的函数名与现有的函数名有冲突,那么就使用as起一个别名。
from fns import fun1 as lovew, fun2 as love
lovew(2)
love(4)使用as给模块指定别名
给模块指定别名,可以更加简短的使用模块
import fns as small
small.fun1(5)使用*导入模块中的所有函数
from fns import *
fun1(5)非自己编写的模块文件,不建议这么用,因为会发生函数名冲突。
函数名规范
函数或者模块命名时,只在其中使用小写字母和下划线,
给形参指定默认值时,等号两边不要有空格
def function_name(param_0, param_1='default'):在函数调用中的实参,也要遵守这个约定
function_name('1', param_1=20)一般代码行长度不要超过79个字符,如果参数太长
def function_name(
param1, param2,
param3, param4
):
...所有的Import都应该写在文件开头
目录