python-函数练习题(闭包,装饰器 )

# !/use/bin/env python
# -*-conding:utf-8-*-

# author:shanshan
import os

"""
1,写函数,计算传入数字参数的和。(动态传参)
"""


def sum_values(*args): # *args是一个列表
sum_values = sum(args)
return sum_values


# print(sum_values(1,2,5,7,-10))


def try_open_file(alter_file_fun): # 执行函数异常的装饰器

def try_open(file_name, old_content, new_content):
try:
alter_file_fun(file_name, old_content, new_content)
except Exception as e:
print('替换 出错了:{}'.format(e.args))

return try_open


"""
2,写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作
"""


def alter_file_1(file_name, old_content, new_content):
"""
替换文件中旧的内容,全局修改为新的内容(但是生成了新的文件)
:param file_name: 文件名 (同一目录下的)
:param old_content: 旧的内容
:param new_content: 新的内容
:return:
"""
file_path = os.path.abspath(file_name) # 传入文件名的绝对路径
with open(file=file_path + '副本', mode='a', encoding='utf-8') as fw: # 写入一个文件叫副本,用追加的方式
with open(file_path, 'r', encoding='utf-8')as fr: # 找到传入的文件
while True:
str_line_file = fr.readline()
if str_line_file: # 如果可以读到一行的内容继续--->
if old_content in str_line_file: # 判断老的内容是否在这一行中
replace_line = str_line_file.replace(old_content, new_content) # 如果存在则将老内容全部替换
fw.write(replace_line) # 写入新的内容
else:
fw.write(str_line_file) # 否则的话写入 老的内容
else:
break # 如果这一行读不到了就退出程序
os.remove(file_path) # 删除旧文件
os.renames(file_path + '副本', file_path) # 将新文件修改为 旧文件的名称


# alter_file_1('english_text','dayto','Today')

@try_open_file
def alter_file_2(file_name, old_content, new_content):
"""
替换文件中旧的内容,全局修改为新的内容(源文件的基础上)
:param file_name: 文件名 (同一目录下的)
:param old_content: 旧的内容
:param new_content: 新的内容
:return:
"""

file_path = os.path.abspath(file_name) # 传入文件名的绝对路径
with open(file_path, 'r', encoding='utf-8')as f: # 以读的方式打开将内容保存在一个变量中(也就是宝存到了内存)
str_file = f.read()

with open(file_path, 'w', encoding='utf-8')as f:
str_replace_file = str_file.replace(old_content, new_content) # 以写的方式重新打开写入新的内容
f.write(str_replace_file)


# alter_file_2('1111','dayto','Today')

"""
3,写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容。
"""


def check_input(str_list_tuple):
flag = False
for i in str_list_tuple:
if (' ' or '') in i: # 循环遍历每个值,如果有空的内容那就将flag设置为true,代表有空的内容
flag = True
if flag == False: # 没有在里面那么flag的值还是false
print('{}:中无空内容'.format(str_list_tuple))
else:
print('{}:中有空内容'.format(str_list_tuple))


# check_input(['1','2 ',' '])

"""
4,写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容(对value的值进行截断),
并将新内容返回给调用者,注意传入的数据可以是字符、listdict
"""


def is_null(func):
def is_parameter_null(*arg, **kwargs):
for i in arg: # arg是一个元祖,i代表里面的值
if i: # 如果i是空值,即为False的时候返回空值
# func(arg,**kwargs)
return func(*arg, **kwargs)
else:
# print('是个空值,不做截取')
return ('是个空值,不做截取')

return is_parameter_null


@is_null
def check_value_len(*arg, **kwargs):
print('传入的数据是:{}'.format(arg))
new_list = []
for value in arg:
if type(value) in (list, tuple):
for value in value:
if len(value) > 2:
value = value[:2]
new_list.append(value)
else:
new_list.append(value)
return new_list

elif type(value) == str:
if len(value) > 2:
value = value[:2]
return value

elif type(value) == dict:
new_dict = {} # 空字典用来接收截取后的值
for dict_key in value:
# if type(arg[i]) == dict: # 如果字典的值还是字典类型,退出
# print('传入字典的value不能为字典')
# break
if len(value[dict_key]) > 2: # 如果长度大于2时,截取前两个长度内容
new_dict[dict_key] = value[dict_key][:2]
else:
new_dict[dict_key] = value[dict_key] # 否则还是用原有的内容
return new_dict


dict_test1 = {'name': '山山1111', '地址': '北京市顺义区'}
dict_test2 = {}
list_test1 = ['111', '22222222', '3333', '44', '', ' ']
list_test2 = []
str_test1 = 'absdnasdjasdkas'
str_test2 = ' '
str_test3 = None
# print("截取后数据:{}".format(check_value_len(dict_test1))) # 传入的字典其中value值不能为字典
# print("截取后数据:{}".format(check_value_len(dict_test2)))
# print("截取后数据:{}".format(check_value_len(list_test1)))
# print("截取后数据:{}".format(check_value_len(list_test2)))
# print("截取后数据:{}".format(check_value_len(str_test1)))
# print("截取后数据:{}".format(check_value_len(str_test2)))
# print("截取后数据:{}".format(check_value_len(str_test3)))


"""
5,解释闭包的概念
答:外函数的返回值是内函数的函数名,内函数调用外函数的变量,使得变量得不到释放的这种现象 就叫做闭包
"""

"""
6,写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组
例如:[(‘红心2),(‘草花2), …(‘黑桃A’)]
"""


def return_card_list():
card_num = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
card_type = ['红心', '草花', '黑桃', '方片']
card_list = []
for i in card_type:
for j in card_num:
card_list.append((i, j)) # 注意返回的样式要求是[(‘红心2),(‘草花2), …(‘黑桃A’)],这里直接把样式写成(ij)形式最简单
return card_list


# print(return_card_list())

"""
7,写函数,传入n个数,返回字典{‘max’:最大值,’min’:最小值}
例如:minmax(2,5,7,8,4)
返回:{‘max’:8,’min’:2}
"""

# def return_max_min(*args):
# """
# 返回一串数字的最大值,最小值,以字典的形式
# :param num: 数字 int
# :return: 字典 dict
# """
#
# num = list(args)
# dict_num = {'max':max(num),'min':min(num)}
# return dict_num

# print(return_max_min(0,-1,5))

"""
8,写函数,专门计算图形的面积
其中嵌套函数,计算圆的面积,正方形的面积和长方形的面积
调用函数area(‘圆形’,圆半径) 返回圆的面积
调用函数area(‘正方形’,边长) 返回正方形的面积
调用函数area(‘长方形’,长,宽) 返回长方形的面积
"""


def area(*args):
def zero_area():
pass

def square_area():
pass

def rectangle_area():
pass


# area('圆形',5)


"""
9,写函数,传入一个参数n,返回n的阶乘

"""


def jiecheng(n):
if n == 1:
return 1 # 递归函数重要的是要有程序的出口
else:
return n * jiecheng(n - 1)


# print(jiecheng(7))

"""
10,编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
"""
login_value = {

'is_login': False}



def login(func):
def login_auth():

with open(r'C:UsersAdministratorPycharmProjectsuntitledfirst_ide_file练习题login_auth', 'r',
encoding='utf-8') as f: str_file = f.read()

# file_is_login = str_file.split('|')[0]
# print(file_is_login)
file_username = str_file.split('|')[1] # 不能使用f.read()两次,将f.read()保存在变量中
file_password = str_file.split('|')[2]
if login_value['is_login'] is False: # 如果此处使用全局的变量,那就涉及到修改全局变量的事,如果使用的是局部变量 name每次进来都将局部变量赋值了
username = input('请输入您的用户名:') password =
input('请输入您的密码:')
if file_username.upper() == username.upper() and file_password.upper() == password.upper():
print('登陆成功{}'.format(username)) login_value[
'is_login'] = True
return func()
else:
print('登录失败')
else:
print('已登录') func()


return login_auth


def home():
print("首页")


@login
def TV():
print('电视页面')


@login
def live():
print('直播页面')

# TV()
# live()


原文地址:https://www.cnblogs.com/shanshan-test/p/12609370.html