函数基础
目录
函数基础
函数初识
name_list = [1,2,1,3,1,5,1]
# 统计列表的原数个数,不让使用len方法
count = 0
while True
for i in name_list:
count + =1
print(count)
#如果统计列表个数代码需要在很多地方使用
#相同代码需要在不同位置反复执行
循环
相同代码在相同位置反复执行
函数
相同代码在不同位置反复执行
ps:相同的代码不是真正一模一样而是可以通过传入的数据不同而做出不同的改变
def my_len():
count = 0
while True
for i in name_list:
count + =1
print(count)
my_len()
'''
函数相当于是工具(具有一定功能)
不用函数
修理工需要修理器件要用锤子 原地打造 每次用完就丢掉 下次用继续原地打造
用函数
修理工提前准备号工具 什么时候用就直接拿出来使用
'''
函数的语法结构
def 函数名(参数):
'''函数注释'''
函数体
return 返回值
1.def
函数定义关键字
2.函数名
等同于变量名
3.参数
可有可无,主要是在使用函数的时候规定要不要外界传数据进来
4.函数注释
解释说明这个函数的作用
5.函数体
是整个函数的核心 主要取决于程序员编写
6.return
使用函数之后可以返回给使用者的数据 可有可无
函数定义与调用
- 函数在定义阶段只检测语法 不执行代码
-
函数在调用阶段才使用函数体代码
my_def()
-
函数必须先定义后调用
-
函数定义使用关键字def函数调用使用
函数名加括号
-
如果有参数则需要在括号呢按照相应的规制传递参数
函数的分类
1.空函数
函数体代码为空 使用pass 或···补全的空函数主要用于项目前期的功能框架搭建
def login():
'''登录功能'''
pass
2.无参函数
定义函数的时候括号内没有函数
def func()
print('函数')
3.有参函数
定义函数的时候括号内写参数 调用函数的时候括号传参数
def func(a):
print(a)
函数的返回值
1.什么是函数的返回值
调用函数之后返回给调用者的结果
2.如何获取返回值
变量名 赋值符号 函数调用
res = func() # 先执行func函数 然后将返回值赋值给res
3.函数返回值的多种情况
3.1.函数体代码没有return关键字 默认返回None
3.2.函数体代码有return 如果后面没有写任何东西还是返回None
3.3.函数体代码有return 后面些什么就返回什么
3.4.函数体代码有return并且后面有多个数据值 则自动组织成元组返回
3.5.函数体代码遇到return立即结束
函数参数
形式参数
在函数定义阶段括号内填写的参数,简称为'形参'
在函数调用阶段函数内填写的参数,简称为'实参'
'''
形参与实参的关系
形参类似于变量名在函数定义阶段可以随便写 最好见名知意
def login(name,pwd):
pass
实参类似于数据值 在函数调用阶段与形参临时绑定 函数运行结束立即断开
login('张三',123) #形参name 与实参 '张三' 形参pwd 与实参 123
'''
函数参数之位置参数
'''当代码只有一行并且很简单的情况下 可以直接在冒号后编写 不用换行'''
位置参数
函数定义阶段阔内从左往右依次填写的变量名
def func(v1,v2,v3):pass
位置实参
函数调用阶段括号内从左到右依次填写的数据值
func(1,2,3)
按照位置传递参数
def func1(av1,av2,av3):
print(av1,av2,av3)
func1(11,22,33) # 11 22 33
# 多参数,少参数都不行
func1(11,22) # 报错少一个参数
func1(11,22,33,44) # 报错多一个参数
func1(av1=11,22,33) # 报错关键之传参一定要在位置传参后面
func1(11,av2=22,av3=33) # 11 22 33 可以
func1(11,av1=12,22,33) # 报错用一个形参在调用时候不能多次赋值
name = '张三'
pwd = '123'
def func2(name,pwd):
print(name,pwd)
func2(name,pwd) # 张三 123 可以 实参没有固定的定义 可以传数据值 也可以绑定数据值的变量名
func2(name=name,pwd=pwd) # 张三 123 可以
'''
遵循规律:
越短的越简单的越靠前
越长的越复杂的越靠后
但是遇到下列情况除外
用一个形参在调用时候不能多次赋值
'''
默认参数
本质其实就是关键字形参
别名叫默认参数:提前就已经给了 用户可传 也可以不传
'''默认参数的定义也遵循短的靠前简单的靠前 长的复杂的靠后'''
def register(name,age,gender='male'):
print(name,age,gender)
register('张三','123') # 张三 123 male
register('莉莉','111','female') # 莉莉 111 female
可变长形参
用于接收不固定数据值长度
def func1(*args):
print(v1)
func1() # ()不传默认为空元组
func1(11,22) # (11,22) 为元组
func1(11) # (11,)元组
def func2(va1,*va2):
print(va1,va2)
func2() # 报错需要最少一个参数
func2(11) # 11,()
func2(11,22,33,44) # 11 (22,33,44)
"""
*号在形参中
用于接收多余的位置参数 组织成元组赋值给*号后面的变量名
"""
用于接收不过顶关键字命名参数
def func1(**kwargs):
print(kwargs)
func1() # {}空字典
func1(name='1',pwd='2',gender='male') #{'name':'1','pwd':'2','gender':'male'}
def func2(a,**kwargs):
print(a,kwargs)
func2(n=1,w=2) # 报错 需要给a传递一个参数
func2(1) # 1 {s}
func2(11,n='1',w='2') # 11 {'n':'1','w':'2'}
func2(a=22,n=1,w=3) # 22 {'n':1,'w':3}
"""
**号在行参中
用于接收多余的关键字参数 组织成字典的形式赋值给**后面的变量名
"""
def func3(*args,**kwargs):
print(args,kwargs)
func3() # () {}
func3(11,22,33) # (11,22,33) {}
func3(a=1,b=2,c=3) # {'a':1,'b':2,'c':3}
func3(11,kw=22) # (11,) {'kw':22}
def func4(n,*args,**kwargs):
print(n,args,kwargs)
func4() # 报错需要传一个参数
func4(1) # 1 () {}
func4(1,2,3) # 1 (2,3) {}
func4(1,a=1,b=2) # 1 () {'a'=1,'b'=2}
func4(n=1,a=2,b=3) # 1 () {'a'=1,'b'=2}
func4(1,2,3,a=4,b=5) # 1 (2,3) {'a':4,'b':5}
"""
由于*和**在函数的形参中使用频率很高 后面跟变量名推荐使用
*args **kwargs
"""
可变长实参
def index(v1,v2,v3):
print(v1,v2,v3)
l1 = [11,22,33]
t1 = (11,22,33)
s1 = {11,22,33}
st = 'chi'
d1 = {'name':'zhang','age':18,'gender':'male'}
"""将其中数据值取出来传给函数的三个形参"""
index(*l1) # 11 22 33
index(*t1) # 11 22 33
index(*s1) # 11 22 33
index(*st) # c h i
index(*d1) # name age gender
"""
*在实参
类似于for循环 将所有循环遍历出来的数据按照位置参数一次性传给参数
"""
d1 = {'name':'zhang','age':18,'gender':'male'}
def index2(name,age,gender):
print(name,age,gender)
# 使用**时字典的键要与形参的变量名一致,顺序可不一致
index2(**d1) # zhang 18 male
"""
**在实参中
将字典打散成关键字参数的形式传递给函数
"""
def index3(*args,**kwargs):
print(args,kwargs)
index(*(1,2,3),**d1) #(1,2,3) {'name':'zhang','age':18,'gender':'male'}
命名关键之参数
"""形参必须按照关键字参数传值>>>:命名关键字参数"""
def index(name,*args,gender='male',**kwargs):
print(name,args,gender,kwargs)
index('张') # 张 () male {}
index('jj',1,2,3,'female',a=1) # jj (1,2,3,'female') male {'a':1}
index('jj',1,2,3,gender='female',a=1) # jj (1, 2, 3) female {'a': 1}
命名空间
"""
name = 'jason'
1.申请内存空间存储jason
2.给jason绑定一个变量名name
3.后续通过变量名name就可以访问到jason
"""
名称空间就是用来存储变量名与数据值绑定关系的地方(可以简单的理解为就是存储变量名的地方)
1.内置空间
解释器运行自动产生 里面包括了很多名字
eg:len print input
2.全局名称空间
py文件运行产生 里面存放文件级别的名字
name='jj'
age =18
if name:
sex = 'male'
while True:
salary = 1888.8
def index():
pass
class MyClass:pass
name\age\sex\salary\index\MyClass
3.局部命名空间
函数体代码运行\类替代运行 产生的空间
命名空间存活周期与作用范围
存活周期
内置名称空间
python解释器启动则创建 关闭则销毁
全局名称空间
py文件执行则创建 运行关闭则销毁
局部命名空间
函数体代码调用则创建 执行完毕则销毁
作用域
内置名称空间
解释器级别的全局有效
全局名称空间
py文件级别的全局有效
局部名称空间
函数体代码内有效
名字的查找顺序
涉及到名字的查找 一定要先搞明白自己在哪一个空间的哪一个级别
1.当我们在局部名称空间中的时候
局部空间名称>>>全局名称空间>>>内置名称空间
2.当在全局名称空间中的时候
全局名称空间>>>内置名称空间
ps:其实名字查早的顺序可以打破global(升级全局变量) nonloabl(使用上一级变量)
查找顺序案例
1.相互独立的局部名称空间默认不能够互相访问
def func1():
name = 'jason'
print(age)
def func2():
age = 18
print(name)
2.局部名称空间嵌套
先从自己的局部名称空间查找 之后由内而外依次查找
"""
函数体代码中名字的查找顺序在函数定义阶段就已经固定死了
x = '干饭了'
def func1():
x = 1
def func2():
x = 2
def func3():
print(x)
'''
# 函数在定义的时候查找顺序就已经固定了,这个时候如果在定义变 量之前查找这个变量就先会在本地的函数体内查找,认为已经有了,实际没有所有就会报错
'''
x = 3
func3()
func2()
func1()
"""
作业1
'''
1.使用函数将员工管理系统和文件进阶注册登录封装
'''
'''
1.使用函数将员工管理系统和文件进阶注册登录封装
'''
'''
1.登录模块
1.管理员模块
1.2普通用户模块
2.注册模块(默认普通用户)
3.查看员工信息模块
3.1单个员工
3.2多个员工(管理员可见)
3.3按职位查看员工(管理员可见)
4.修改员工信息模块(管理员可修改全部信息,用户只能修改昵称和密码)
5.退出模块
6.删除用户信息(管理员可见)
'''
'''
user_info_db = {
'name',
'username':用户名,
'userpwd':密码,
'isadmin':0(管理员) or 1(普通用户),
'addr':'北京',
'phone':'12333',
'job':'teacher',
'register_time':'时间'
'isdelete':0(已删除) or 1(在职)
}
'''
import json
import datetime
isadmin = None
islogin = None
def open_file(mode):
'''
打开文件模块不重复写代码
:param mode: 打开模式
:return: 文件对象f
'''
f = open(file=r'db/db.txt', mode=mode, encoding='utf-8')
return f
def login():
'''
登录模块
:param username: 用户名
:param pwd: 密码
:return: 0管理员1普通用户 or False
'''
if is_login():
return '已登录'
while True:
global islogin, isadmin
username = input('请输入用户名(q\Q退出)')
if username.upper() == 'Q':
return '返回主页面'
userpwd = input('请输入密码')
login_read = open_file('rt')
for userinfo in login_read:
userinfo = json.loads(userinfo.strip()) # 读出来字符串转字典
if username == userinfo['username'] and userpwd == userinfo['userpwd']:
islogin = userinfo['username']
isadmin = True if userinfo['isadmin'] == '0' else False # 判断是否是管理员
return f'用户名{username}登录成功!!!'
else:
return '登录失败,请检查用户名或密码!!!'
def register():
'''
注册模块
:return:
'''
while True:
username = input('请输入用户名(q\Q退出)')
if username.upper() == 'Q':
return '返回主页面'
userpwd = input('请输入密码')
name = input('请输入姓名')
phone = input('请输入人手机号')
addr = input('请输入家庭地址')
job = input('请输入岗位')
register_read = open_file('rt')
for userinfo in register_read:
userinfo = json.loads(userinfo.strip())
if username == userinfo['username']:
print('用户名已存在,请更改用户名')
break
else:
register_write = open_file('at')
userinfo = {
'username': username,
'userpwd': userpwd,
'name': name,
'isadmin': '1',
'addr': addr,
'phone': phone,
'job': job,
'register_time': datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S'),
'isdelete': '1'
}
userinfo = json.dumps(userinfo) # # 字典转字符串
register_write.write(userinfo + '\n')
print('添加成功')
'''
3.查看员工信息模块
3.1单个员工
3.2多个员工(管理员可见)
3.3按职位查看员工(管理员可见) # 暂时不上线
'''
def show_user_info():
'''用户信息查看模块'''
if not is_login():
return '未登录,请先登录'
global islogin, isadmin
show_user_info_read = open_file('rt')
if not isadmin:
for userinfo in show_user_info_read:
userinfo = json.loads(userinfo.strip())
if userinfo['username'] == islogin:
print(f'''
{userinfo['username']}个人信息
姓名:{userinfo['name']}
用户名:{userinfo['username']}
家庭地址:{userinfo['addr']}
手机号:{userinfo['phone']}
岗位:{userinfo['job']}
注册时间:{userinfo['register_time']}
''')
return '查询完毕'
print(f'欢迎你{islogin}管理员')
for userinfo in show_user_info_read:
userinfo = json.loads(userinfo.strip())
print(f'''
{userinfo['username']}个人信息
姓名:{userinfo['name']}
用户名:{userinfo['username']}
密码:{userinfo['userpwd']}
家庭地址:{userinfo['addr']}
手机号:{userinfo['phone']}
岗位:{userinfo['job']}
注册时间:{userinfo['register_time']}
权限:{'管理员' if userinfo['isadmin'] == '0' else '普通用户'}
是否离职:{'离职' if userinfo['isdelete'] == '0' else '在职位'}
''')
return '查询完毕'
def update_user_info():
'''
更新用户信息
:return:
'''
if not is_login():
return '未登录,请先登录'
while True:
show_user_info()
global isadmin, islogin
if isadmin:
username = input('请输入要修改的用户名(q\Q退出)')
if username.upper() == 'Q':
return '返回主页面'
else:
username = islogin
show_user_info_read = open_file('rt')
show_user_info_read = show_user_info_read.readlines()
for userinfo in show_user_info_read:
data = json.loads(userinfo.strip())
if username == data['username']:
print('以下信息不输入则不修改')
if not isadmin:
name = input('请输入新的姓名(q\Q退出)')
if name.upper() == 'Q':
return '返回主页面'
if name != '':
data['name'] = name
userpwd = input('请输入新的密码')
if userpwd != '':
data['userpwd'] = userpwd
phone = input('请输入人新的手机号')
if phone != '':
data['phone'] = phone
else:
username = input('请输入用户名')
if username != '':
data['username'] = username
userpwd = input('请输入新的密码')
if userpwd != '':
data['userpwd'] = userpwd
name = input('请输入新的姓名')
if name != '':
data['name'] = name
phone = input('请输入人新的手机号')
if phone != '':
data['phone'] = phone
addr = input('请输入家庭地址')
if addr != '':
data['addr'] = addr
job = input('请输入岗位')
if job != '':
data['job'] = job
is_admin = input('0管理员1普通用户')
if is_admin != '':
data['isadmin'] = is_admin
isdelete = input('0离职1在职')
if isdelete != '':
data['isdelete'] = isdelete
# 修改列表里面原始数据数据
show_user_info_read[show_user_info_read.index(userinfo)] = json.dumps(data) + '\n'
show_user_info_write = open_file('wt')
show_user_info_write.writelines(show_user_info_read) # 在重新写入文件
show_user_info_write.flush()
print('修改成功')
break
else:
print('用户名不存在')
def is_login():
'''
判断是否登录
:return:
'''
global islogin
if islogin:
return True
else:
return False
def logout():
'''退出登录'''
global islogin, isadmin
if is_login():
islogin = None
isadmin = None
return '注销成功'
else:
return '未登录,请先登录'
def delete_user():
'''
删除用户信息
:return:
'''
if not is_login():
return '未登录,请先登录'
while True:
show_user_info()
global isadmin, islogin
if isadmin:
username = input('请输入要删除的用户名(q\Q退出)')
if username.upper() == 'Q':
return '返回主页面'
else:
return '你不是管理员,权限不足'
show_user_info_read = open_file('rt')
show_user_info_read = show_user_info_read.readlines()
for userinfo in show_user_info_read:
data = json.loads(userinfo.strip())
if username == data['username']:
del show_user_info_read[show_user_info_read.index(userinfo)]
show_user_info_write = open_file('wt')
show_user_info_write.writelines(show_user_info_read)
show_user_info_write.flush()
print('删除成功')
break
else:
print('用户名不存在')
def run():
'''
程序入口
:return:
'''
global isadmin
while True:
func_dict = {
'1': login,
'2': register,
'3': show_user_info,
'4': update_user_info,
'5': logout,
'6': delete_user
}
if not isadmin:
del func_dict['6']
print(f'''
1.登录模块
2.注册模块(默认普通用户)
3.查看员工信息模块(默认普通用户查看自己信息,管理员可查看所有人信息)
4.修改员工信息模块(管理员可修改全部信息,用户只能修改昵称和密码)
5.退出模块(管理员可见)
{"" if not isadmin else "6.删除用户"}
''')
inputs = input('请选择功能编号(q\Q退出)')
if inputs.upper() == 'Q':
return
if inputs in func_dict:
res = func_dict[inputs]()
print(res)
else:
print('输入功能编号有误,请重新输入')
if __name__ == '__main__':
run()
作业2
1.判断下列money的值是多少并说明理由 思考如何修改而不是新增绑定关系
money = 100
def index():
money = 666
print(money) # 100
money = 100
def func1():
money = 666
def func2():
money = 888
func2()
print(money) # 100