python:从入门到放弃 07 函数的基本使用
定义函数
函数的使用必须遵循’先定义,后调用’的原则。
'''定义函数的语法'''
def 函数名(参数1,参数2,...):
"""文档描述"""
函数体
return 值
'''-----------------------------------'''
1.def: 定义函数的关键字;
2.函数名:函数名指向函数内存地址,是对函数体代码的引用。函数的命名应该反映出函数的功能;
3.括号:括号内定义参数,参数是可有可无的,且无需指定参数的类型;
4.冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代码;
5."""文档描述""": 描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性;
6.函数体:由语句和表达式组成;
7.return 值:定义函数的返回值,return是可有可无的。
调用函数
1.函数一定要遵循先定义后调用的原则
即定义函数的代码要比调用函数的代码先执行
2.函数在定义阶段只检测语法不执行代码
3.函数体代码只有在调用函数的时候才会执行
函数名() #如果是有参函数则需要传递参数,无参函数不需要传参
4.函数名其实相当于是变量名指向的是内存中函数体代码所在的位置
函数的分类
1.内置函数
python解释器提前定义好可以直接调用的函数
eg:len、open... # 如何查看代码的内部源码ctrl+鼠标左键
2.自定义函数
程序员自己编写的函数
2.1.无参函数
# 在函数定义阶段括号内没有参数
def 函数名():
函数体
# 在函数调用阶段括号内也不需要写参数
函数名()
2.2.有参函数
# 在函数定义阶段括号内有参数>>>:类似于变量名
def 函数名(a):
函数体
# 在函数调用阶段括号内也必须传参数>>>:类似于变量值
函数名(a)
2.3.空函数
# 在定义阶段函数体代码是用pass或者...占位
def 函数名():
pass
'''前期能够通过空函数快速的罗列出程序中大致的功能
让程序整体框架清晰 空函数大量的使用在项目前期的功能框架搭建'''
函数的返回值
函数的返回值其实就是在调用函数之后返回的结果
我们使用 '变量名 = 函数调用' 来获取返回值
然后操作返回值
1.当函数体代码没有return关键字的时候 返回值是None
2.当函数体代码写了return但是没有跟任何值得时候 返回值也是None
3.当函数体代码写了return并且跟了数据 那么写什么就返回什么
4.return后面还可以跟多个值 逗号隔开 会自动组织成元组返回出去后
5.函数体代码遇到return会立刻结束函数运行
函数体代码里面写return相当于循环体代码里面写break
遇到了就立刻结束函数和循环的执行
函数的参数
形参与实参
1.分类
函数的参数分为形式参数和实际参数,简称形参和实参:
形参即在定义函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值。
实参即在调用函数时,括号内传入的值,值可以是常量、变量、表达式或三者的组合
2.形参与实参的关系
形参类似于是变量名、实参类似于是变量的值
在调用函数的时候传入实参 会与形参临时绑定
函数运行结束之后自动解除绑定
位置参数
位置即顺序,位置参数指的是按顺序定义的参数,需要从两个角度去看:
1.在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参,凡是按照这种形式定义的形参都必须被传值
2.在调用函数时,按照从左到右的顺序依次定义实参,称为位置实参,凡是按照这种形式定义的实参会按照从左到右的顺序与形参一一对应
位置参数的特征
1.位置形参与位置实参在绑定关系的时候就是按照从左往右的顺序依次绑定
2.位置形参与位置实参的个数要一致 多一个不行少一个也不行
关键字参数
在调用函数时,实参可以是key=value的形式,称为关键字参数,凡是按照这种形式定义的实参,可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值
register(sex='male',name='lili',age=18)
Name:lili Age:18 Sex:male
# 需要注意在调用函数时,实参也可以是按位置或按关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值
默认参数
在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数。
需要注意:
1.默认参数必须在位置参数之后
2.默认参数的值仅在函数定义阶段被赋值一次
可变长度的参数
参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,实参的定义无非是按位置或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数,即*
与**
的用法
可变长度的位置参数
如果在最后一个形参名前加*
号,那么在调用函数时,溢出的位置实参,都会被*接收,以元组的形式保存下来赋值给该形参
def foo(x,y,z=1,*args): #在最后一个形参名args前加*号
print(x)
print(y)
print(z)
print(args)
foo(1,2,3,4,5,6,7) #实参1、2、3按位置为形参x、y、z赋值,多余的位置实参4、5、6、7都被*接收,以元组的形式保存下来,赋值给args,即args=(4, 5, 6,7)
1
2
3
(4, 5, 6, 7)
*
号在实参中,可以将列表或者元组打散成位置参数一一传入
def index(*[11,22,33]) 等价于 index(11,22,33)
def index(*(11,22,33)) 等价于 index(11,22,33)
可变长度的关键字参数
如果在最后一个形参名前加**
号,那么在调用函数时,溢出的关键字参数,都会被**
接收,以字典的形式保存下来赋值给该形参
def foo(x,**kwargs): #在最后一个参数kwargs前加**
print(x)
print(kwargs)
foo(y=2,x=1,z=3) #溢出的关键字实参y=2,z=3都被**接收,以字典的形式保存下来,赋值给kwargs
1
{'z': 3, 'y': 2}
**
号在实参中,可以将字典打散成关键字参数一一传入
def index(**{'name':'jason'}) 等价于 index(name='jason')
小作业
1.尝试使用函数写注册登录
def register():
# 注册函数,会返回一个bool值,如果用户名重复,返回False。注册完成返回True
is_success = True
username_inp = input('请输入用户名>>>')
with open(r'userinfo.txt', 'r', encoding='utf8') as f:
for i in f:
if i.split('|')[0] == username_inp:
is_success = False
return is_success
password_inp = input('请输入密码>>>')
user_str = username_inp + '|' + password_inp + '\n'
with open(r'userinfo.txt', 'a', encoding='utf8') as test:
test.write(user_str)
return is_success
def login():
# 登录函数,会返回一个bool值,登录成功返回True,登录失败返回False
is_success = True
username_inp = input('请输入用户名>>>')
password_inp = input('请输入密码>>>')
user_str = username_inp + '|' + password_inp + '\n'
with open(r'userinfo.txt', 'r', encoding='utf8') as test:
for i in test:
if i == user_str:
return is_success
else:
is_success = False
return is_success
while True:
print('1.注册 2.登录')
inp = input('输入编号选择功能')
if inp == '1':
success_onp = register()
if success_onp == False:
print('用户名重复,请重新注册')
elif success_onp == True:
print('注册成功')
elif inp == '2':
success_onp = login()
if success_onp == True:
print('登录成功')
elif success_onp == False:
print('用户名或密码错误')