学习日志34 python

1 Python 文件内容读取相关函数

  1. read()

    • 功能:一次性读取文件的全部内容
    • 返回值:字符串类型,包含文件所有内容
    • 示例:

      python

      运行

      with open("file.txt", "r") as f:
          content = f.read()  # 读取整个文件内容
      
  2. readline()

    • 功能:每次读取文件的一行内容
    • 返回值:字符串类型,包含当前行的内容(包含换行符)
    • 特点:多次调用会依次读取下一行,读到文件末尾返回空字符串
    • 示例:

      python

      运行

      with open("file.txt", "r") as f:
          line1 = f.readline()  # 读取第一行
          line2 = f.readline()  # 读取第二行
      
  3. readlines()

    • 功能:读取文件所有行内容
    • 返回值:列表类型,列表中的每个元素是文件的一行内容(包含换行符)
    • 示例:

      python

      运行

      with open("file.txt", "r") as f:
          lines = f.readlines()  # 得到包含所有行的列表
      
  4. 补充说明:

    • 以上三个函数均用于读取文件内容,只是读取方式和返回结果不同
    • 关闭文件使用close()方法,而非选项中的readclose()(该方法不存在)
    • 推荐使用with语句操作文件,可自动处理文件关闭,无需手动调用close()

这些函数适用于不同的读取场景,可根据实际需求选择使用:读取整个文件用read(),逐行处理用readline(),需要一次性获取所有行并处理用readlines()

math.floor() 函数

1. math.floor() 的核心功能

math.floor(x) 是数学中的向下取整函数,用于返回小于或等于输入值 x 的最大整数。
例如:

  • math.floor(5.5) 返回 5(小于 5.5 的最大整数)
  • math.floor(-2.3) 返回 -3(小于 -2.3 的最大整数)
  • math.floor(7) 返回 7(整数的向下取整是其本身)

2. Python 2.x 与 Python 3.x 的返回值差异

  • Python 2.xmath.floor() 返回 float 类型
    例如:math.floor(5.5) 的结果是 5.0(浮点数)

  • Python 3.xmath.floor() 返回 int 类型
    例如:math.floor(5.5) 的结果是 5(整数)

3. 实际使用示例

python

运行

import math

# Python 3.x 环境下
print(math.floor(5.5))   # 输出:5(int类型)
print(math.floor(-3.2))  # 输出:-4(int类型)
print(math.floor(10))    # 输出:10(int类型)

4. 注意点

  • 该函数属于 math 模块,使用前需先导入 import math
  • 向下取整与 “四舍五入” 不同,它总是向更小的方向取整(即使小数部分小于 0.5)。
  • 版本差异主要影响返回值的类型,不改变取整的逻辑结果。

这种差异是 Python 2 到 Python 3 升级过程中对数据类型规范化的一部分,让函数返回更符合直觉的整数类型。

3 元组的定义是通过逗号 , 来标识的,而不是单纯的括号 ()

在 Python 中,元组的定义是通过逗号 , 来标识的,而不是单纯的括号 ()。例如:

  • (1, 2) 是元组(因为有逗号)
  • ([1, 2]) 只是用括号包裹了一个列表,括号在这里仅起到分组作用,不会改变内部数据的类型,所以它仍然是列表 [1, 2]

而列表是不可哈希的(因为列表是可变类型,其内容可以被修改),不能作为字典的键。

如果想让它成为元组,需要添加逗号:

python

运行

dicts[(1, 2)] = 'abc'  # 正确,(1, 2) 是元组(可哈希)
dicts[([1, 2],)] = 'abc'  # 正确,元组内包含列表(但元组本身可哈希)

所以题目中 ([1, 2]) 本质是列表,导致代码报错。核心区别在于:括号本身不决定是否为元组,逗号才是元组的关键标识。

4 list元素可以重复,set集合不行

在 Python 中:

list 确实是列表,它是有序的、可修改的序列,允许包含重复元素。例如:[1, 2, 2, 3] 是一个有效的列表。

set 是集合,它是无序的、不可修改的(但可以添加 / 删除元素),并且不允许包含重复元素。如果尝试添加重复元素,集合会自动去重。例如:{1, 2, 2, 3} 最终会变成 {1, 2, 3}

这是列表和集合的核心区别之一,也是 Python 中两种常用数据结构的重要特性。

5 Python 中不可变数据类型及字符串的特性

1. 不可变数据类型的核心特性

不可变数据类型是指:对象创建后,其内存中的值不能被直接修改。若要 "修改",需创建新的对象并赋值,原对象保持不变。

Python 中常见的不可变类型包括:

  • 字符串(str
  • 整数(int)、浮点数(float)、布尔值(bool
  • 元组(tuple,仅当元素均为不可变类型时整体不可变)
  • 冻结集合(frozenset

2. 字符串不可变的具体表现

字符串的不可变性体现在:

  • 无法通过索引直接修改单个字符(如 s[0] = 'H' 报错)
  • 无法删除单个字符(如 del s[0] 报错)
  • 所有字符串方法(如 replace()upper())均返回新字符串,不改变原字符串

示例:

python

运行

s = "hello"
s_new = s.replace('h', 'H')  # 返回新字符串"Hello"
print(s)  # 原字符串仍为"hello",未被修改

3. 报错类型及原因

当尝试修改字符串的元素时,会触发 TypeError,错误信息为:
'str' object does not support item assignment(字符串对象不支持元素赋值)

原因:
字符串在内存中以固定序列存储,其地址(内存引用)与值绑定。若允许修改,会破坏 Python 对字符串的优化机制(如字符串驻留机制),同时影响依赖字符串不可变性的场景(如作为字典的键)。

4. 如何 "间接修改" 字符串

虽然不能直接修改,但可通过以下方式生成新字符串实现类似 "修改" 的效果:

  • 切片拼接

    python

    运行

    s = "hello"
    s_new = "H" + s[1:]  # 用新字符拼接原字符串的切片,结果为"Hello"
    
  • 列表转换:先转为可变的列表,修改后再转回字符串:

    python

    运行

    s = "hello"
    s_list = list(s)  # 转为列表['h','e','l','l','o']
    s_list[0] = "H"   # 修改列表元素
    s_new = "".join(s_list)  # 转回字符串"Hello"
    

5. 不可变类型的优势

  • 安全性:作为字典键或集合元素时,值不会意外被修改,避免哈希冲突。
  • 性能优化:Python 可对不可变对象进行缓存(如小整数池、字符串驻留),减少内存占用。
  • 线程安全:多线程环境下,无需担心不可变对象被并发修改。

6. 与可变类型的对比

类型可变 / 不可变能否直接修改元素示例操作
字符串(str)不可变不能s[0] = 'a' 报错
列表(list)可变lst[0] = 'a' 正常执行
元组(tuple)不可变不能tpl[0] = 'a' 报错
字典(dict)可变dct['key'] = 'val' 正常执行

理解这一特性,有助于避免编写错误代码,同时更合理地选择数据类型(如需要频繁修改用列表,作为键或需要稳定值用字符串 / 元组)。

可调用对象(callable)

在 Python 中,可调用对象(callable) 是指可以像函数一样通过 () 语法执行的对象。简单来说,就是可以在对象后面加括号进行调用的实体。

常见的可调用对象:

  1. 函数(function)
    用 def 定义的普通函数或 lambda 匿名函数,例如:

    python

    运行

    def add(a, b):
        return a + b
    add(1, 2)  # 可调用,返回3
    
    f = lambda x: x*2
    f(3)  # 可调用,返回6
    
  2. 类(class)
    类本身是可调用的,调用时会创建实例(触发 __init__ 方法):

    python

    运行

    class Person:
        def __init__(self, name):
            self.name = name
    p = Person("Alice")  # 调用类创建实例
    
  3. 类的实例(instance)
    如果类定义了 __call__ 方法,其实例也可被调用:

    python

    运行

    class Counter:
        def __call__(self):
            print("被调用了")
    c = Counter()
    c()  # 可调用,输出"被调用了"(因为定义了__call__)
    
  4. 其他可调用类型
    如内置函数(print()len())、方法(类或实例的方法)、生成器函数等。

不可调用的对象:

不可调用对象是指不能通过 () 语法执行的对象,大多数基础数据类型都属于此类,例如:

  • 数值(intfloat):123() 会报错
  • 字符串(str):"hello"() 会报错
  • 列表(list):[1,2,3]() 会报错
  • 字典(dict):{"a":1}() 会报错
  • 普通类实例(未定义 __call__ 方法):

    python

    运行

    class A:
        pass
    a = A()
    a()  # 报错,因为A未定义__call__
    

如何判断对象是否可调用?

可以使用内置函数 callable() 检查:

python

运行

print(callable(add))  # True(函数可调用)
print(callable(Person))  # True(类可调用)
print(callable(123))  # False(整数不可调用)
print(callable(a))  # False(未定义__call__的实例)

核心区别:可调用对象本质上实现了 Python 的 “调用协议”(通常是通过定义 __call__ 方法),而不可调用对象则没有这种能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值