python-入门6

1. 函数

1.1 函数同时返回多个值

"""
函数同时返回多个值
需求: 自定义函数 calculate(), 接收两个整数, 然后返回它们的 加减乘除结果
"""
# 定义函数calculate(), 接收两个整数
def calculate(a, b):
    """
    自定义函数, 模拟计算器, 计算两个整数的 加减乘除结果
    :param a: 要操作的第1个整数
    :param b: 要操作的第2个整数
    :return: 加减乘除结果
    """
    # 具体的计算加减乘除结果的动作
    sum = a + b
    sub = a - b
    mul = a * b
    div = a // b
    # 返回它们的 加减乘除结果
    return sum, sub, mul, div  # 同时返回多个值, 默认会用 元组封装

# 调用函数, 进行测试.
if __name__ == '__main__':
    result = calculate(10, 3)
    print(result)  # (13, 7, 30, 3)

1.2 函数的参数写法-位置参数

"""
Python中 函数的参数写法 主要有如下的四种:
    位置参数
    关键字参数
    默认参数(缺省参数)
    不定长参数
细节:
    1. 位置参数 和 关键字参数 是针对于 实参 来讲的
    2. 缺省参数 和 不定长参数 是针对于 形参 来讲的

位置参数:
    我们之前写的实参写法 就是位置参数, 即: 实参的 个数 和 顺序 必须和 形参保持一致
"""

# 定义函数 user_info(), 接收三个参数, 打印自己的信息: name, age, address
def user_info(name, age, address):
    print(f'我叫: {name}, 今年 {age} 岁了, 我住在: {address}')

# main函数是程序的 主入口, 所有的代码都是从这里开始执行的.
if __name__ == '__main__':
    # 调用函数 user_info()
    user_info('张三', 23, '北京')

1.3 关键字参数

"""
关键字参数:
    我们之前写的实参写法 就是位置参数, 即: 实参的 个数 和 顺序 必须和 形参保持一致.
    如果 实参 和 形参的顺序不一致, 结果不一定是我们想要的, 所以为了更灵活的调用函数, 引入了: 关键字参数.

    格式:
        采用 键 = 值 的形式来传递 实参.
    细节:
        如果有多个参数(实参), 则: 位置参数在前, 关键字参数在后(且多个关键字参数之间, 没有顺序要求)
"""
# 1. 定义函数 user_info(), 接收三个参数, 打印自己的信息: name, age, address
def user_info(name, age, address):
    print(f'我叫: {name}, 今年 {age} 岁了, 我住在: {address}')

# main函数是程序的 主入口, 所有的代码都是从这里开始执行的.
if __name__ == '__main__':
    # 关键字参数, 多个关键字参数之间无顺序要求.
    user_info(address='广州', name='李四', age=24)

    # 如果既有关键字参数, 又有位置参数. 则: 位置参数在前, 关键字参数在后.
    # user_info(address='广州', name='李四', 25)      # 报错, 顺序不对.

    #           位置参数              关键字参数
    user_info('王五', address='深圳', age=25)

1.4 缺省参数

"""
缺省参数:
    概述:
        缺省参数也叫 默认参数, 即: 定义在 函数的形参列表的 最后.
    格式:
        采用 键 = 值 的形式来定义, 且必须放 形参列表的最后.
    细节:
        1. 调用函数时, 没有给缺省参数赋值, 则: 用缺省参数的默认值.
        2. 调用函数式, 如果给缺省参数赋值, 则: 用赋的新值.
"""

def user_info(name, age, address='三亚'):
    print(f'我叫: {name}, 今年 {age} 岁了, 我住在: {address}')

# main函数是程序的 主入口, 所有的代码都是从这里开始执行的.
if __name__ == '__main__':
    # 2. 调用函数 user_info()
    # 位置参数
    user_info('张三', 23, '北京')
    user_info('张三', '北京', 23)  # 位置参数, 故意传错位置. 不报错, 但是结果不是我们要的.
    print('-' * 28)

    # 关键字参数, 多个关键字参数之间无顺序要求.
    user_info(address='广州', name='李四', age=24)

    # 如果既有关键字参数, 又有位置参数. 则: 位置参数在前, 关键字参数在后.
    # user_info(address='广州', name='李四', 25)      # 报错, 顺序不对.

    #           位置参数              关键字参数
    user_info('王五', address='深圳', age=25)
    print('-' * 28)

    # 不给默认参数传值.
    user_info('王五', age=25)

1.5 不定长参数

"""
不定长参数:
    概述:
        不定长参数也叫 可变参数, 即: 参数的个数是可以变化的.
    应用场景:
        适用于 实参的个数不确定的情况, 就可以把 形参定义成 可变参数.
    格式:
        *args           只能接收所有的 位置参数, 封装到: 元组中.
        **kwargs        只能接收所有的 关键字参数, 封装到: 字典中.
    细节:
        1. 关于实参, 位置参数在前, 关键字参数在后.
        2. 关于形参, 如果两种 可变参数都有, 则: *args 在前, **kwargs 在后.
        3. 关于形参, 如果既有 缺省参数 又有不定长参数, 则编写顺序为:  *args, 缺省参数, **kwargs
"""

# 需求1: 演示 不定长参数(可变参数)之 接收 位置参数.
def method01(*args):                      # 约定俗成, 变量名可以任意写, 但是建议写成 args
    print(f'接收到的所有参数为: {args}')     # 你把 args变量当做 元组来用即可.
    print(type(args))

# 需求2: 演示 不定长参数(可变参数)之 接收 关键字参数.
def method02(**kwargs):
    print(f'接收到的所有参数为: {kwargs}')
    print(type(kwargs))

# 需求3: 同时定义两种 参数.
#             不定长(可变)参数
def method03(*args, **kwargs):
    print(f'args: {args}')
    print(f'kwargs: {kwargs}')

# 需求4: 同时定义 缺省参数, 不定长参数.
#          不定长参数   缺省参数    不定长参数
def method04(*args, name='张三', **kwargs):
    print(f'name: {name}')
    print(f'args: {args}')
    print(f'kwargs: {kwargs}')

# main充当程序的 主入口.
if __name__ == '__main__':
    # 调用 method01()函数.
    method01(1, '张三', 23)
    # method01(1, '张三', age=23)       # 报错, *args 只能接收所有的 位置参数.
    print('-' * 28)

    # 调用 method02()函数.
    method02(name='张三', age=23, phone='13112345678')
    # method02('李四', age=24, phone='13112345678')     # 报错, **kwarg 只能接收所有的 关键字参数.
    print('-' * 28)

    # 调用 method03()函数
    #                位置参数           关键字参数
    method03(10, 20, 'aa', name='王五', age=25, address='杭州')
    print('-' * 28)

    # 调用 method04()函数
    #                位置参数             关键字参数
    method04(10, 20, 'aa', name='王五', age=25, address='杭州')

1.6 组包与拆包

"""
组包和拆包解释:
    概述:
        组包 和 拆包 是Python中的一种独有写法.
    格式:
        把 多个值 => 1个变量 的过程, 称之为: 组包.
        把 1个(容器)变量 => 多个变量值 的过程, 称之为: 拆包.
    应用场景:
        1. 一次性获取到 元组, 列表, 字典中的每个数据.
        2. 交换变量.
"""
# 组包.   多 => 1
list1 = [11, 22, 33, 44, 55]
tuple1 = ('aa', 'bb', 'cc')
dict1 = {'name': '张三', 'age': 23}

# 拆包.
# 从 列表 拆包
a, b, c, d, e = list1
print(a, b, c, d, e)

# 从 元组 拆包
x, y, z = tuple1
print(x, y, z)

# 从 字典 拆包, 只能获取 键 的值.
k1, k2 = dict1
print(k1, k2)

1.7 引用

"""
引用 介绍:
    概述:
        Python中的引用 指的是 地址值,即: 变量在内存中的位置(地址).
    格式:
        id(变量名)         可以查看变量在内存中的地址.
    细节:
        1. Python中只有 引用传递, 即: 我们以前看到的所有赋值动作, 都是把 地址值拷贝(赋值)过去.
        2. 区分 可变 和 不可变类型的依据: 在不改变地址值的情况下, 是否可以修改变量的内容, 可以: 可变类型, 不可以: 不可变类型.
            可变:     列表, 字典, 集合.
            不可变:   int, float, bool, str, 元组
        3. 观察如下的代码, 分析程序结果:
            形参是可变类型:    形参的可变直接影响实参.
            形参是不可变类型:  形参的改变对实参没有任何影响.
"""

"""
观察如下的代码, 分析程序结果, 得到的结论如下.
    形参是可变类型:    形参的改变直接影响实参.
    形参是不可变类型:  形参的改变对实参没有任何影响.
"""

# 定义函数, 接收 参数, 一会传入: 整数(int), 不可变类型.
def change(num):
    num = 200

# 定义函数, 接收 参数, 一会传入: 列表(list), 可变类型.
def change2(list1):
    list1[1] = 28

if __name__ == '__main__':
    # 演示: 不可变类型 函数的调用.
    a = 100
    print(f'调用 change 函数前, a: {a}')     # 100
    change(a)
    print(f'调用 change 函数前, a: {a}')     # 100

    # 演示: 可变类型 函数的调用.
    list1 = [1, 2, 3, 4, 5]
    print(f'调用 change 函数前, list1: {list1}')  # 1, 2, 3, 4, 5
    change2(list1)
    print(f'调用 change 函数后, list1: {list1}')  # 1, 28, 3, 4, 5

1.8 匿名函数

"""
匿名函数介绍:
    概述:
        没有名字的函数 就叫 匿名函数.
    格式:
        变量名 = lambda 形参列表 : 函数体(只能写一行代码, 且该行代码的结果会被自动返回)
    细节:
        1. Python的匿名函数 类似于 Java中的Lambda表达式.
        2. 匿名函数适用于简单的业务需求, 即: 函数体只有一行代码的函数.
        3. 匿名函数的应用场景:
            当对方法仅调用一次.
            匿名函数 可以作为 函数对象 进行传递.
"""

# 匿名函数入门
# 需求: 定义函数, 用于计算两个整数和
def get_sum(a, b):
    return a + b

print(get_sum(10, 20))

# 匿名函数实现
my_get_sum = lambda a, b :  a + b
print(my_get_sum(11, 22))
print('-' * 28)

2. 文件

2.1 从文件中读取信息

"""
文件 介绍:
    概述:
        无论是 windows, Linux, Mac系统, 都是采用 文件 来管理数据的, 它们都是 文件管理系统.
        之所以用文件来管理数据, 原因是因为: 内存中的数据是临时存储的, 电脑管理了, 数据就丢失了.
        文件: 可以实现 永久 存储数据.
    文件的类型:
        文本文档, 图片类型, 视频类型, 音频类型......
    文件的操作步骤:
        1. 打开文件.
        2. 读写操作.
        3. 关闭文件.

    打开文件 涉及到的API(Application Programming Interface, 应用程序编程接口), 就是: 别人写的 函数.
        文件对象名 = open('文件路径', '打开模式', 码表)        # 参3为可选项, 针对于 中文有效.
    读取文件信息:
        read(num)       一次读取num个字节的数据, 不写就一次性读取所有的数据.
        readline()      一次读取一行.
        readlines()     一次性读取读完所有行, 且会把每行数据封装到 1个列表中.
    关闭文件:
        文件对象名.close()

细节:
    1. Python中, 路径的写法, 要么用 \\,  要么用 /, 要么用 r'一个\就行', 即: r'\' 会取消 \的转移含义, 当做1个普通字符来用.
    2. 相对路径默认是相对于 当前项目的路径来写的, 即: 你直接写 1.txt, 想到于是  /当前项目路径/1.txt
"""

# 1. 打开文件(file).
# 场景1: 绝对路径.
# f = open(r'D:\workspace\ai_28_basic_bj\pythonProject\day06\data\a.txt', 'r')           # r'' 取消 \的 转义函数.
# f = open('D:\\workspace\\ai_28_basic_bj\\pythonProject\\day06\\data\\a.txt', 'r')      # \\ 代表 1个 \
# f = open('D:/workspace/ai_28_basic_bj/pythonProject/day06/data/a.txt', 'r')              # 或者可以写成 /

# 场景2: 相对路径写法.  默认是相对于当前项目的路径来讲的
f = open('./data/a.txt', 'r')           # ./ 代表当前目录
# print(f'文件对象名: {f}')

# 2. 读写操作.
# read(num)       一次读取num个字节的数据, 不写就一次性读取所有的数据.
# print(f.read())      # 一次性读取所有的数据.
# print(f.read(3))     # 一次读取3个字节, 包括: \n 也占1个字节
# print(f.read(5))     # 一次读取5个字节, 包括: \n 也占1个字节

# readlines()     一次性读取读完所有行, 且会把每行数据封装到 1个列表中.
print(f.readlines())    # ['abc\n', 'defg\n', 'xyz']

# 3. 关闭文件.
f.close()

"""
中文 解释:
    计算机底层存储, 操作, 运算数据, 都是采用数据的 二进制(补码)形式, 所以中文, 特殊符号, 数字, 英文字母底层都是要转成二进制的.
    后来科学家就提出了 码表的概念, 用来描述 字符 及其 对应的数字的关系.  例如: 'a' => 97,  'A' => 65, '0' => 48...
    最早的码表 ASCII码表记录的就是: 英文字母, 数字, 特殊符号及其对应的 数字的关系.
    后来随着计算机的普及, 各个国家都有了各个国家的 码表, 咱们国内使用最多的主要是 GBK系列, 1个中文 占 2个字节.
    后来有个组织就统计全世界各个国家的码表, 制定了一张"万国码", 也叫"统一码", 这就是: Unicode系列的码表, 例如: utf-8, utf-16, utf-32...

    总结:
        国内主要用 GBK码表, 1个中文占 2个 字节.
        国际通用码表 UTF-8, 1个中文占 3个字节.
        无论是什么码表, 英文字母, 数字, 特殊符号都只占1个字节.
        只要以后你遇到了乱码的情况, 不用想, 原因只会有1个: 编解码不一致.
"""

# 1. 打开文件.
# f = open('./data/a.txt', 'r')                 # r是字符形式读, 没写码表, 默认是按照: gbk 读.
# f = open('./data/a.txt', 'r', encoding='gbk')   # 效果同上
f = open('./data/a.txt', 'r', encoding='utf-8')   # 按照 utf-8 码表解析

# 以二进制形式来读
# f = open('./data/a.txt', 'rb')

# 2. 读取文件内容.
print(f.read())

# 3. 关闭文件.
f.close()

2.2 往文件中写信息

"""
往文件中写信息:
    write(数据)       往文件中写数据
    writelines()     一次写多行

细节:
    1. 注意写数据的模式,  w: write,覆盖写入.  a: append,追加写入
    2. 读的时候, 如果 数据源文件不存在, 会报错.  No Such File Or Directory...
    3. 写的时候, 如果 目的地文件不存在, 会自动创建
"""

# 写数据到文件.
# 1. 打开文件.
# f = open('./data/b.txt', 'w', encoding='utf-8')     # 覆盖写入
f = open('./data/b.txt', 'a', encoding='utf-8')     # 覆盖写入

# 2. 往文件中写数据.
f.write('hello world!\n')
f.write('好好学习, 天天向上!')

# 3. 关闭文件.
f.close()

# 拷贝 a.txt文件数据 到 b.txt
# 1. 封装数据源文件, 用于: 读取它的数据.
src_f = open('./data/a.txt', 'r', encoding='utf-8')

# 2. 封装目的地文件, 用于: 往其中写数据.
dest_f = open('./data/b.txt', 'w', encoding='utf-8')

# 循环读取, 读一行, 写一行.  或者 一次性读写指定的字节数, 一般是: 1024的整数倍.
while True:
    # 一次性读取 8192个字节, 8 * 1024 = 8192个字节 = 8KB
    data = src_f.read(8192)
    # 核心细节: 如果读不到数据了, 即读取到文件末尾了, 结束读取.
    # if len(data) == 0:        # 可以判断长度
    if data == '':              # 也可以判断是否为空
        break
    # 把读取到的数据, 写到目的地文件.
    dest_f.write(data)

# 3. 关闭文件.
src_f.close()
dest_f.close()

2.3 操作文件-扩展

"""
扩展: with-open语句:
    主要是针对于 文件操作的, 即: 不用手动 close()释放资源了, 该语句会在 语句体执行完毕后, 自动释放资源
    格式:
        with open('路径', '模式', '码表') as 别名,  open('路径', '模式', '码表') as 别名:
            语句体
    特点:
        语句体执行结束后, with后边定义的变量, 会自动被释放
"""

# 打开 数据源 和 目的地文件.
with open('./data/a.txt', 'rb') as src_f, open('./data/b.txt', 'wb') as dest_f:
    # 循环拷贝
    while True:
        # 一次读取8192个字节.
        data = src_f.read(8192)
        # 读完了, 就不读了.
        if len(data) <= 0:
        # if data == '':
            break
        # 走到这里, 说明读到了, 把读取到的数据写出到目的地文件.
        dest_f.write(data)
  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值