13 函数基础

函数基础

1 什么是函数

函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段

2 为什么使用函数

不使用函数的结果:

  1. 组织结构不清晰,可读性差;
  2. 代码冗余;
  3. 可维护性、扩展性差。

函数能提高应用的模块性和代码的重复利用率。

3 如何使用函数

原则:先定义 后调用。

定义函数的过程:

  1. 在内存中申请空间来保存函数体的代码;
  2. 将该内存地址交给函数名;
  3. 定义函数时不会执行函数体代码,但会检测函数体语法。

调用函数的过程

  1. 通过函数名找到函数的内存地址;
  2. 加括号就意味着要执行函数体代码。
def test():
	undef  # 变量undef虽然没有定义,但此处不存在语法错误,不会报错。
	print('不会报错')

test()  # 报错,执行函数体代码时找不到变量undef的引用值。
3.1 函数定义

定义函数就相当于将一段代码封装起来,然后将内存地址交给函数名。
函数名是对这段代码的引用,这和变量的定义是相似的。
函数的命名应该反映出函数的功能,一般使用动词。

以 def 关键词开头,后接函数名和圆括号()
圆括号()可以放入形式参数
函数体代码以冒号起始,并且缩进
return [表达式] 用于结束函数,可以返回一个值给调用方。
不带表达式的return相当于返回 None。

def 函数名(形参列表):
    """文档描述(可选)"""
    函数体
    return 返回值(可选)
3.2 函数定义分类
3.2.1 无参函数

函数定义时参数列表为空。

3.2.2 有参函数

函数定义时包括参数列表。

3.2.3 空函数

函数体代码为pass或…
可以用于构思代码。

def func(x, y):
    pass
3.3 函数调用
3.3.1 语句形式

函数名 + 括号
一般不需要函数体的返回值

def hello():
	print('Hello!')

hello()
3.3.2 表达式形式
  1. 赋值表达式
def add(x, y):
	return x + y

a = 1
b = 2
res = add(a, b)
  1. 运算表达式
def add(x, y):
	return x + y

a = 1
b = 2
res = add(a, b) * 25
3.3.3 参数形式

函数调用可以作为参数

def add(x, y):
	return x + y

a = 1
b = 2
res = add(add(a, b), 25)
3.4 函数返回值

return是函数结束的标志,用于退出函数。
函数体代码一旦运行到return就会立刻终止函数的运行,
并将return后的表达式当做本次运行的结果返回。

  1. 返回None
    函数体内没有return
    return 或者 return None
  2. 返回一个值
def test():
	return [1, 2, 3]

res = test()
print(res, type(res))  # [1, 2, 3] list
  1. 返回多个值
    用逗号分隔开多个值,会以元组类型返回。
def test():
	return 1, 2, 3

res = test()
print(res, type(res))  # (1, 2, 3) tuple

4 练习

4.1 编写文件修改功能

调用函数时,传入三个参数:修改的文件路径,要修改的内容,修改后的内容。

import os


def modify(file_path, raw_txt, modified_txt):
    """
    用于修改文件。
    :param file_path: 修改的文件路径
    :param raw_txt: 要修改的内容
    :param modified_txt: 修改后的内容
    :return: None
    """
    if not os.path.exists(file_path):
        print('文件不存在。')
        return
    new_path = r'.{}.swap'.format(file_path)
    with open(file_path, mode='rt', encoding='utf-8') as f1, \
            open(new_path, mode='wt', encoding='utf-8') as f2:
        for each_line in f1:
            f2.write(each_line.replace(raw_txt, modified_txt))

    os.remove(file_path)
    os.rename(new_path, file_path)
4.2 编写tail工具
import time
import os


def tail(filepath):
    """
    用于查阅正在改变的文件内容
    :param filepath: 目标文件的路径
    :return: None
    """
    if not os.path.exists(filepath):
        print('文件不存在。')
        return
    with open(filepath, mode='rb') as f:
        f.seek(0, 2)
        while 1:
            end_line = f.readline()
            if len(end_line) == 0:
                time.sleep(0.5)
            else:
                print(end_line.decode('utf-8'))
4.3 编写登录功能
import os


def read_file(filepath):
    if not os.path.exists(filepath):
        print('用户数据文件不存在。')
        return
    user_dict = {}
    with open(filepath, mode='rt', encoding='utf-8') as user_f:
        for each_line in user_f:
            un, pw = each_line.strip().split(':')
            user_dict[un] = pw
    return user_dict


def check_login(user_dict):
    un_input = input('请输入用户名:').strip()
    if un_input not in user_dict:
        print('用户名不存在。')
    else:
        pw_input = input('请输入密码:').strip()
        if user_dict[un_input] != pw_input:
            print('密码错误。')
        else:
            print('登陆成功。')


def login(filepath):
    filepath = r'{}'.format(filepath)
    user_dict = read_file(filepath)
    if user_dict is not None:
        check_login(user_dict)


login('./user_info.txt')
4.4 编写注册功能
import os


def read_file(filepath):
    if not os.path.exists(filepath):
        print('用户数据文件不存在。')
        return
    user_dict = {}
    with open(filepath, mode='rt', encoding='utf-8') as user_f:
        for each_line in user_f:
            un, pw = each_line.strip().split(':')
            user_dict[un] = pw
    return user_dict


def append_file(filepath, new_user_info):
    with open(filepath, mode='at', encoding='utf-8') as user_f:
        user_f.write(new_user_info)
        return True


def check_register(user_dict):
    while 1:
        un_input = input('请输入用户名:').strip()
        if un_input in user_dict:
            print('用户名已存在,禁止注册。')
        else:
            while 1:
                pw_input = input('请输入密码:').strip()
                repw_input = input('请再次输入密码:').strip()
                if pw_input != repw_input:
                    print('两次输入的密码不相同。')
                else:
                    return '{un}:{pw}\n'.format(un=un_input, pw=pw_input)


def register(filepath):
    filepath = r'{}'.format(filepath)
    user_dict = read_file(filepath)
    if user_dict is not None:
        new_user = check_register(user_dict)
        register_result = append_file(filepath, new_user)
        if register_result:
            print('注册成功。')


register('./user_info.txt')
4.5 编写ATM程序实现下述功能

数据来源于文件db.txt

  1. 充值功能:用户输入充值钱数,db.txt中该账号钱数完成修改;
  2. 转账功能:用户A向用户B转账1000元,db.txt中完成用户A账号减钱,用户B账号加钱;
  3. 提现功能:用户输入提现金额,db.txt中该账号钱数减少;
  4. 查询余额功能:输入账号查询余额;
  5. 用户登录成功后,内存中记录下该状态,上述功能以当前登录状态为准,必须先登录才能操作。
import os

INFO_PATH = r'./db.txt'

'''
db.txt格式为 用户名:密码:余额,例如:
A:AA:10000
B:BB:10000
'''


def read_file():
    if not os.path.exists(INFO_PATH):
        print('用户数据文件不存在。')
        return
    user_dict = {}
    with open(INFO_PATH, mode='rt', encoding='utf-8') as user_f:
        for each_line in user_f:
            # 用户名,密码,存款
            un, pw, dep = each_line.strip().split(':')
            user_dict[un] = {'pw': pw, 'dep': int(dep)}
    return user_dict


def check_login(user_dict):
    un_input = input('请输入用户名:').strip()
    if un_input not in user_dict:
        print('用户名不存在,请核对用户名后重新登录。')
        return None
    else:
        pw_input = input('请输入密码:').strip()
        if user_dict[un_input]['pw'] != pw_input:
            print('密码错误,请核对用户名和密码后重新登录。')
            return None
        else:
            print('登陆成功。')
            return un_input


def login():
    user_dict = read_file()
    if user_dict is not None:
        while 1:
            un = check_login(user_dict)
            if un is not None:
                return un


def write_file(new_dict):
    new_str = ''
    for each_un in new_dict:
        each_pw = new_dict[each_un]['pw']
        each_dep = new_dict[each_un]['dep']
        new_str += '{un}:{pw}:{dep}\n'.format(un=each_un, pw=each_pw, dep=each_dep)

    with open(INFO_PATH, mode='wt', encoding='utf-8') as f:
        f.write(new_str)


def save_money(un, user_dict):
    while 1:
        money = input('请输入存钱金额:')
        if not money.isdigit():
            print('只接受数字。')
        else:
            money = int(money)
            break
    user_dict[un]['dep'] += money
    write_file(user_dict)
    print('存钱完成')


def withdraw_money(un, user_dict):
    deposits = int(user_dict[un]['dep'])
    if deposits == 0:
        print('账户余额为0,退出取钱功能。')
        return
    while 1:
        money = input('请输入取出金额:')
        if not money.isdigit():
            print('只接受数字。')
        else:
            money = int(money)
            if deposits < money:
                print('账户余额不足。')
            else:
                break
    user_dict[un]['dep'] -= money
    write_file(user_dict)
    print('取钱完成')


def transfer_money(un, user_dict):
    deposits = int(user_dict[un]['dep'])
    if deposits == 0:
        print('账户余额为0,退出转账功能。')
        return
    while 1:
        money = input('请输入转账金额:')
        if not money.isdigit():
            print('只接受数字。')
        else:
            money = int(money)
            if deposits < money:
                print('账户余额不足。')
            else:
                break
    while 1:
        other_un = input('请输入转账目标用户:')
        if other_un not in user_dict:
            print('用户名错误,请重新确认后再输入。')
        else:
            break
    print('''
        注意,这里不能保证事务的四个特性,
        如果因某些原因导致数据错误, Agon 老师一赔十,他有钱 :)
    ''')
    user_dict[un]['dep'] -= money
    user_dict[other_un]['dep'] += money
    write_file(user_dict)
    print('转账完成')


def check_money(un, user_dict):
    deposits = int(user_dict[un]['dep'])
    print('您的账户余额为:{deposits}'.format(deposits=deposits))


def quit(un, user_dict):
    print('感谢使用,再见。')
    return True


def atm():
    un = login()
    print('''
        充值功能: 1
        提现功能: 2
        转账功能: 3
        查询余额功能: 4
        退出程序: 5
    ''')
    while 1:
        while 1:
            num_input = input('请输入操作编号:')
            if not num_input.isdigit():
                print('注意,只能输入整数。')
            cmd_num = int(num_input)
            if cmd_num < 1 or cmd_num > 5:
                print('注意,只能输入功能编号,其它数字无效。')
            else:
                break

        while 1:
            user_dict = read_file()
            switch = {
                1: save_money,
                2: withdraw_money,
                3: transfer_money,
                4: check_money,
                5: quit,
            }
            quit_flg = switch.get(cmd_num)(un, user_dict)
            if quit_flg:
                return
            break


atm()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值