【3天速成Python基础语法(2)】


1 🍑函数🍑

1.1 🍎基本了解🍎

编程中的函数和数学中的函数有一定的相似之处,编程中的函数, 是一段 可以被重复使用的代码片段。

代码示例: 求数列的和, 不使用函数:

# 1. 求 1 - 100 的和
sum = 0
for i in range(1, 101):
    sum += i
print(sum)

# 2. 求 300 - 400 的和
sum = 0
for i in range(300, 401):
    sum += i
print(sum)

# 3. 求 1 - 1000 的和
sum = 0
for i in range(1, 1001):
    sum += i
print(sum)

可以发现, 这几组代码基本是相似的, 只有一点点差异,可以把重复代码提取出来, 做成一个函数。

代码示例:

# 定义函数
def calcSum(beg, end):
    sum = 0
    for i in range(beg, end + 1):
        sum += i
    print(sum)

# 调用函数
calcSum(1, 100)
calcSum(300, 400)
calcSum(1, 1000)

可以明显看到, 重复的代码已经被消除了。

1.2 🍎语法格式🍎

创建函数/定义函数:

def 函数名(形参列表):
    函数体
    return 返回值

调用函数/使用函数:

函数名(实参列表)           // 不考虑返回值
返回值 = 函数名(实参列表)   // 考虑返回值
  • 函数定义并不会执行函数体内容,必须要调用才会执行,调用几次就会执行几次:
def test1():
    print('hello')
    
# 如果光是定义函数, 而不调用, 则不会执行
  • 函数必须先定义, 再使用:
test3()          # 还没有执行到定义, 就先执行调用了, 此时就会报错. 
def test3():
    print('hello')

在这里插入图片描述

1.3 🍎函数传参🍎

在函数定义的时候, 可以在 ( ) 中指定 “形式参数” (简称 形参), 然后在调用的时候, 由调用者把 “实际参数” (简称 实参) 传递进去,这样就可以做到一份函数, 针对不同的数据进行计算处理,考虑前面的代码案例:

def calcSum(beg, end):
    sum = 0
    for i in range(beg, end + 1):
        sum += i
    print(sum)

calcSum(1, 100)
calcSum(300, 400)
calcSum(1, 1000)

上面的代码中, beg, end 就是函数的形参。1, 100 / 300, 400 就是函数的实参。

注意:

  • 一个函数可以有一个形参, 也可以有多个形参, 也可以没有形参。
  • 一个函数的形参有几个, 那么传递实参的时候也得传几个,保证个数要匹配。

和 C/ C++ 不同, Python 是动态类型的编程语言, 函数的形参不必指定参数类型。换句话说, 一个函数可以支持多种不同类型的参数,比如:

def test(a):
    print(a)
test(10)
test('hello')
test(True)

在这里插入图片描述

1.4 🍎函数返回值🍎

函数的参数可以视为是函数的 “输入”, 则函数的返回值, 就可以视为是函数的 “输出”。
下列代码:

def calcSum(beg, end):
    sum = 0
    for i in range(beg, end + 1):
        sum += i
    print(sum)
    
calc(1, 100)

可以转换成:

def calcSum(beg, end):
    sum = 0
    for i in range(beg, end + 1):
        sum += i
    return sum
result = calcSum(1, 100)
print(result)

这两个代码的区别就在于, 前者直接在函数内部进行了打印, 后者则使用 return 语句把结果返回给函数调用者, 再由调用者负责打印。

  • 一个函数中可以有多个 return 语句:
# 判定是否是奇数
def isOdd(num):
    if num % 2 == 0:
        return False
    else:
        return True
  
result = isOdd(10)
print(result)
  • 执行到 return 语句, 函数就会立即执行结束, 回到调用位置。比如上面的代码,如果 num 是偶数, 则进入 if 之后, 就会触发 return False , 也就不会继续执行 return True。

  • 一个函数是可以一次返回多个返回值的,使用 , 来分割多个返回值:

def getPoint():
    x = 10
    y = 20
    return x, y
a, b = getPoint()
print(a,b)

在这里插入图片描述

  • 如果只想关注其中的部分返回值, 可以使用 _ 来忽略不想要的返回值:
def getPoint():
    x = 10
    y = 20
    return x, y
_, b = getPoint()

1.5 🍎变量作用域🍎

观察以下代码:

def getPoint():
    x = 10
    y = 20
    return x, y
x, y = getPoint()

在这个代码中, 函数内部存在 x, y, 函数外部也有 x, y。但是这两组 x, y 不是相同的变量, 而只是恰好有一样的名字。

  • 变量只能在所在的函数内部生效。
    在函数 getPoint() 内部定义的 x, y 只是在函数内部生效,一旦出了函数的范围, 这两个变量就不再生效了:
def getPoint():
    x = 10
    y = 20
    return x, y
getPoint()
print(x, y)

在这里插入图片描述

  • 在不同的作用域中, 允许存在同名的变量。
    虽然名字相同, 实际上是不同的变量:
x = 20
def test():
    x = 10
    print(f'函数内部 x = {x}')
test()
print(f'函数外部 x = {x}')

在这里插入图片描述
注意:

  • 在函数内部的变量, 也称为 “局部变量”。

  • 不在任何函数内部的变量, 也称为 “全局变量”。

  • 如果函数内部尝试访问的变量在局部不存在, 就会尝试去全局作用域中查找。

x = 20
def test():
    print(f'x = {x}')
test()

在这里插入图片描述

  • 如果是想在函数内部, 修改全局变量的值, 需要使用 global 关键字声明。
x = 20
def test():
    global x
    x = 10
    print(f'函数内部 x = {x}')
test()
print(f'函数外部 x = {x}')

在这里插入图片描述
如果此处没有 global , 则函数内部的 x = 10 就会被视为是创建一个局部变量 x, 这样就和全局变量 x 不相关了。

  • if / while / for 等语句块不会影响到变量作用域。换而言之, 在 if / while / for 中定义的变量, 在语句外面也可以正常使用。
for i in range(1, 4):
    print(f'函数内部 i = {i}')
print(f'函数外部 i = {i}')

在这里插入图片描述
注意分析结果,range里面存放的是[1,3]之间连续的整数,当出了for循环后里面的i就是3而不是4,这跟C/C++有所差异。

1.6 🍎函数执行过程🍎

  • 调用函数才会执行函数体代码,不调用则不会执行。
  • 函数体执行结束(或者遇到 return 语句), 则回到函数调用位置, 继续往下执行。

链式调用:

def isOdd(num):
    if num % 2 == 0:
        return False
    else:
        return True
print(isOdd(10))

嵌套调用:

def a():
    print("函数 a")
def b():
    print("函数 b")
    a()
def c():
    print("函数 c")
    b()
def d():
    print("函数 d")
    c()
d()

1.7 🍎函数递归🍎

递归是 嵌套调用 中的一种特殊情况, 即一个函数嵌套调用自己。这跟C/C++递归是一样的逻辑,一定要有递归出口,否则将会造成栈溢出。
代码实例:

def factor(n):
    if n == 1:
        return 1
    return n * factor(n - 1)
result = factor(5)
print(result)

1.8 🍎参数默认值🍎

Python 中的函数, 可以给形参指定默认值,带有默认值的参数, 可以在调用的时候不传参。(类似于C++中的缺省参数)

代码示例: 计算两个数字的和

def add(x, y, debug=False):
    if debug:
        print(f'调试信息: x={x}, y={y}')
    return x + y
print(add(10, 20))
print(add(10, 20, True))

此处 debug=False 即为参数默认值,当我们不指定第三个参数的时候, 默认 debug 的取值即为 False。

在这里插入图片描述
带有默认值的参数需要放到没有默认值的参数的后面,这个跟C++规则一致:

def add(x, debug=False, y):
    if debug:
        print(f'调试信息: x={x}, y={y}')
    return x + y
print(add(10, 20))

在这里插入图片描述

1.9 🍎关键字参数🍎

在调用函数的时候, 需要给函数指定实参,一般默认情况下是按照形参的顺序, 来依次传递实参的。但是我们也可以通过关键字参数, 来调整这里的传参顺序, 显式指定当前实参传递给哪个形参。

def test(x, y):
    print(f'x = {x}')
    print(f'y = {y}')
test(x=10, y=20)
test(y=100, x=200)

在这里插入图片描述


2 🍑列表和元组🍑

2.1 🍎基本概念🍎

编程中, 经常需要使用变量来保存/表示数据,如果代码中需要表示的数据个数比较少, 我们直接创建多个变量即可。但是有的时候, 代码中需要表示的数据特别多, 甚至也不知道要表示多少个数据。这个时候, 就需要用到列表。

列表是一种让程序猿在代码中批量表示/保存数据的方式。元组和列表相比, 是非常相似的, 只是列表中放哪些元素可以修改调整, 元组中放的元素是创建元组的时候就设定好的, 不能修改调整

2.2 🍎列表操作🍎

2.2.1 🍋创建列表🍋

创建列表主要有两种方,[ ] 表示一个空的列表:

alist = [ ]
blist = list()

如果需要往里面设置初始值, 可以直接写在 [ ] 当中。使用list()方式不能够在括号里进行初始化。

可以直接使用 print 来打印 list 中的元素内容:

alist = [1,4,6,9]
print (alist)

在这里插入图片描述

列表中存放的元素允许是不同的类型。(这一点和 C/C++差别较大)

alist = [1, 'hello', True]
print(alist)

在这里插入图片描述

2.2.2 🍋访问下标🍋

可以通过下标访问操作符 [ ] 来获取到列表中的任意有效元素。

alist = [1, 2, 3, 4]
print(alist[2])

在这里插入图片描述
下标是从 0 开始计数的, 因此下标为 2 , 则对应着 3 这个元素。这一点和 C/C++一样。

  • 通过下标不光能读取元素内容, 还能修改元素的值:
alist = [1, 2, 3, 4]
alist[2] = 100
print(alist)
  • 如果下标超出列表的有效范围, 会抛出异常:
alist = [1, 2, 3, 4]
print(alist[100])

在这里插入图片描述

  • 因为下标是从 0 开始的, 因此下标的有效范围是 [0, 列表长度 - 1]. 使用 len 函数可以获取到列表的元素个数。
alist = [1, 2, 3, 4]
print(len(alist))

在这里插入图片描述

  • 下标可以取负数,表示 “倒数第几个元素”:
alist = [1, 2, 3, 4]
print(alist[-3])
print(alist[-1])

在这里插入图片描述

2.2.3 🍋切片操作🍋

通过下标操作是一次取出里面第一个元素。通过切片, 则是一次取出一组连续的元素, 相当于得到一个 子列表。使用 [ : ] 的方式进行切片操作。

代码实例:

alist = [1, 2, 3, 4]
print(alist[1:3])

alist[1:3] 中的 1:3 表示的是 [1, 3) 这样的由下标构成的前闭后开区间。也就是从下标为 1 的元素开始(2), 到下标为 3 的元素结束(4), 但是不包含下标为 3 的元素,所以最终结果只有 2, 3。

  • 切片操作中可以省略前后边界。
alist = [1, 2, 3, 4]
print(alist[1:])        # 省略后边界, 表示获取到列表末尾
print(alist[:-1])       # 省略前边界, 表示从列表开头获取
print(alist[:])         # 省略两个边界, 表示获取到整个列表

在这里插入图片描述

  • 切片操作还可以指定 “步长” , 也就是每访问一个元素后, 下标自增几步。
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[1:3:1])
print(alist[1:7:2])
print(alist[2:9:3])
print(alist[::5])

在这里插入图片描述
再使用一个:来表示步长。

  • 切片操作指定的步长还可以是负数, 此时是从后往前进行取元素,表示 “每访问一个元素之后, 下标自减几步”。
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[8:3:-3])
print(alist[1:7:-2])
print(alist[::-2])

在这里插入图片描述
注意分析结果,当区间不存在时会返回一个空列表,步长为负数的话也是遵循左闭右开的原则。

alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[7:1:-1])

在这里插入图片描述
结果从下标7到下标2,不包括下标1,这点大家要注意。不过一般情况下我们不会这么写代码。

2.2.4 🍋遍历列表元素🍋

“遍历” 指的是把元素一个一个的取出来, 再分别进行处理。

  • 最简单的办法就是使用 for 循环
alist = [1, 2, 3, 4]
for elem in alist:
    print(elem)
  • 也可以使用 for 按照范围生成下标, 按下标访问
alist = [1, 2, 3, 4]
for i in range(0, len(alist)):
    print(alist[i])
  • 还可以使用 while 循环,手动控制下标的变化
alist = [1, 2, 3, 4]
i = 0
while i < len(alist):
    print(alist[i])
    i += 1

2.2.5 🍋新增元素🍋

  • 使用 append 方法, 向列表末尾插入一个元素(尾插)
alist = [1, 2, 3, 4]
alist.append('hello')
alist.append(False)
print(alist)

在这里插入图片描述

  • 使用 insert 方法, 向任意位置插入一个元素,insert 第一个参数表示要插入元素的下标。
alist = [1, 2, 3, 4]
alist.insert(1, 'hello')
print(alist)

在这里插入图片描述

2.2.6 🍋查找元素🍋

  • 使用 in 操作符, 判定元素是否在列表中存在,返回值是布尔类型。
alist = [1, 2, 3, 4]
print(2 in alist)
print(10 in alist)

在这里插入图片描述

  • 使用 index 方法, 查找元素在列表中的下标,返回值是一个整数,如果元素不存在, 则会抛出异常。
alist = [1, 2, 3, 4]
print(alist.index(2))
print(alist.index(10))

2.2.7 🍋删除元素🍋

  • 使用 pop 方法删除最末尾元素
alist = [1, 2, 3, 4, 5]
alist.pop()
print(alist)

在这里插入图片描述

  • pop 也能按照下标来删除元素
alist = [1, 2, 3, 4]
alist.pop(2)
print(alist)

在这里插入图片描述

  • 使用 remove 方法, 按照值删除元素
alist = [1, 2, 3, 4, 2, 5, 2]
alist.remove(2)
print(alist)

在这里插入图片描述
存在多个值的话按照索引顺序删除第一个值。

2.2.8 🍋连接列表🍋

  • 使用 + 能够把两个列表拼接在一起。此处的 + 结果会生成一个新的列表,而不会影响到旧列表的内容。
alist = [1, 2, 3, 4]
blist = [5, 6, 7]
print(alist + blist)

在这里插入图片描述

  • 使用 extend 方法, 相当于把一个列表拼接到另一个列表的后面。

a.extend(b) , 是把 b 中的内容拼接到 a 的末尾,不会修改 b, 但是会修改 a

alist = [1, 2, 3, 4]
blist = [5, 6, 7]
alist.extend(blist)
print(alist)
print(blist)

在这里插入图片描述

2.3 🍎元组🍎

元组的功能和列表相比, 基本是一致的,元组使用 ( ) 来表示。

atuple = ( )
atuple = tuple()

元组不能修改里面的元素, 列表则可以修改里面的元素。

因此, 像读操作,比如访问下标, 切片, 遍历, in, index, + 等, 元组也是一样支持的。但是, 像写操作, 比如修改元素, 新增元素, 删除元素, extend 等, 元组则不能支持。

另外, 元组在 Python 中很多时候是默认的集合类型。例如, 当一个函数返回多个值的时候:

def getPoint():
    return 10, 20
result = getPoint()
print(type(result))

在这里插入图片描述

问题来了, 既然已经有了列表, 为啥还需要有元组?

  • 你有一个列表, 现在需要调用一个函数进行一些处理。但是你有不是特别确认这个函数是否会把你的列表数据弄乱,那么这时候传一个元组就安全很多。
  • 我们马上要讲的字典, 是一个键值对结构,要求字典的键必须是 “可hash对象” (字典本质上也是一个hash表)。而一个可hash对象的前提就是不可变,因此元组可以作为字典的键, 但是列表不行。

3 🍑字典🍑

3.1 🍎概念🍎

字典是一种存储 键值对 的结构,类似于C/C++中的unordered_map,底层是哈希表。

3.2 🍎字典操作🍎

3.2.1 🍋创建字典🍋

创建一个空的字典,使用 { } 表示字典。

a = { }
b = dict()
print(type(a))
print(type(b))
  • 也可以在创建的同时指定初始值
  • 键值对之间使用 , 分割, 键和值之间使用 : 分割。(冒号后面推荐加一个空格)
student = { 'id': 1, 'name': 'zhangsan' }
print(student)

在这里插入图片描述

  • 为了代码更规范美观, 在创建字典的时候往往会把多个键值对, 分成多行来书写:
student = {
    'id': 1,
    'name': 'zhangsan'
}
  • 最后一个键值对, 后面可以写 , 也可以不写。
student = {
    'id': 1,
    'name': 'zhangsan',
}

注意键和值可以为任意类型哦:

student = {
    'id': 1,
    'name': ["zs","ls"],
    1: 1
}

print(student)

在这里插入图片描述

3.2.2 🍋查找 key🍋

  • 使用 in 可以判定 key 是否在 字典 中存在,返回布尔值。
student = {
    'id': 1,
    'name': 'zhangsan',
}
print('id' in student)
print('score' in student)
  • 使用 [ ] 通过类似于取下标的方式, 获取到val的值,只不过此处的 “下标” 是 key。(可能是整数, 也可能是字符串等其他类型)
student = {
    'id': 1,
    'name': ["zs","ls"],
    1: 3
}

print(student['name'])
print(student[1])

在这里插入图片描述

  • 如果 key 在字典中不存在, 则会抛出异常.
student = {
    'id': 1,
    'name': ["zs","ls"],
    1: 3
}

print(student[2])

在这里插入图片描述

3.2.3 🍋新增/修改元素🍋

使用 [ ] 可以根据 key 来新增/修改 value。

  • 如果 key 不存在, 对取下标操作赋值, 即为新增键值对:
student = {
    'id': 1,
    'name': 'zhangsan',
}
student['score'] = 90
print(student)

在这里插入图片描述
这个特性类似于C++。

  • 如果 key 已经存在, 对取下标操作赋值, 即为修改键值对的值:
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
student['score'] = 90
print(student)

在这里插入图片描述

3.2.4 🍋删除元素🍋

  • 使用 pop 方法根据 key 删除对应的键值对:
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
student.pop('score')
print(student)

在这里插入图片描述

3.2.5 🍋遍历字典元素🍋

  • 直接使用 for 循环能够获取到字典中的所有的 key, 进一步的就可以取出每个值了.
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
for key in student:
    print(key, student[key])

在这里插入图片描述

  • 取出所有 key 和 value。使用 keys 方法可以获取到字典中的所有的 key。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
print(student.keys())

在这里插入图片描述

此处 dict_keys 是一个特殊的类型, 专门用来表示字典的所有 key。大部分元组支持的操作对于dict_keys 同样适用。

  • 使用 values 方法可以获取到字典中的所有 value。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
print(student.values())

在这里插入图片描述

此处 dict_values 也是一个特殊的类型, 和 dict_keys 类似。

  • 使用 items 方法可以获取到字典中所有的键值对。
student = {
    'id': 1,
    'name': 'zhangsan',
    'score': 80
}
print(student.items())

在这里插入图片描述

3.2.6 🍋合法的 key 类型🍋

不是所有的类型都可以作为字典的 key,字典本质上是一个 哈希表, 哈希表的 key 要求是 “可哈希的”, 也就是可以计算出一个哈希值。

  • 可以使用 hash 函数计算某个对象的哈希值。
  • 但凡能够计算出哈希值的类型, 都可以作为字典的 key。
print(hash(0))
print(hash(3.14))
print(hash('hello'))
print(hash(True))
print(hash(()))           # ( ) 是一个空的元组

在这里插入图片描述

  • 列表无法计算哈希值。
print(hash([1, 2, 3]))

在这里插入图片描述

  • 字典也无法计算哈希值。
print(hash({ 'id': 1 }))

在这里插入图片描述


4 🍑文件🍑

4.1 🍎基本概念🍎

变量是把数据保存到内存中,如果程序重启/主机重启, 内存中的数据就会丢失。要想能让数据被持久化存储, 就可以把数据存储到硬盘中,也就是在 文件 中保存。

通过文件的后缀名, 可以看到文件的类型. 常见的文件的类型如下:

  • 文本文件 (txt)
  • 可执行文件 (exe, dll)
  • 图片文件 (jpg, gif)
  • 视频文件 (mp4, mov)
  • office 文件 (.ppt, docx)

咱们课堂上主要研究最简单的文本文件。

4.2 🍎文件操作🍎

4.2.1 🍋打开文件🍋

使用内建函数 open 打开一个文件。

f = open('d:/test.txt', 'r')
  • 第一个参数是一个字符串, 表示要打开的文件路径。
  • 第二个参数是一个字符串, 表示打开方式。其中 r 表示按照读方式打开, w 表示按照写方式打开, a表示追加写方式打开。
  • 如果打开文件成功, 返回一个文件对象,后续的读写文件操作都是围绕这个文件对象展开。
  • 如果打开文件失败(比如路径指定的文件不存在), 就会抛出异常。

在这里插入图片描述

4.2.2 🍋关闭文件🍋

使用 close 方法关闭已经打开的文件。

f.close()

使用完毕的文件要记得及时关闭,否则就可能会造成文件描述符泄漏。

虽然Python存在垃圾回收机制能够在文件对象销毁时自动的关闭文件,但是由于垃圾回收操作不一定及时,所以我们在写代码的时候仍然要考虑手动关闭。

4.2.3 🍋写文件🍋

文件打开之后, 就可以写文件了。

  • 写文件, 要使用写方式打开, open 第二个参数设为 w
  • 使用 write 方法写入文件
f = open('d:/test.txt', 'r')
f.write('hello')
f.close()

在这里插入图片描述

  • 使用 w 一旦打开文件成功, 就会清空文件原有的数据.
  • 使用 a 实现 “追加写”, 此时原有内容不变, 写入的内容会存在于之前文件内容的末尾.
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
f = open('d:/test.txt', 'a')
f.write('world')
f.close()

在这里插入图片描述

  • 针对已经关闭的文件对象进行写操作, 也会抛出异常.
f = open('d:/test.txt', 'w')
f.write('hello')
f.close()
f.write('world')

在这里插入图片描述

4.2.4 🍋读文件🍋

  • 读文件内容需要使用 r 的方式打开文件。
  • 使用 read 方法完成读操作,参数表示 “读取几个字符” 。
f = open('d:/test.txt', 'r')
result = f.read(2)
print(result)
f.close()

在这里插入图片描述

  • 如果文件是多行文本, 可以使用 for 循环一次读取一行。

实例:
在这里插入图片描述

f = open('d:/test.txt', 'r')
for line in f:
    print(f'line = {line}')
f.close()

在这里插入图片描述

注意: 由于文件里每一行末尾都自带换行符, print 打印一行的时候又会默认加上一个换行符, 因此打印结果看起来之间存在空行。

使用 print(f'line = {line}', end='') 手动把 print 自带的换行符去掉。

在这里插入图片描述

  • 使用 readlines 直接把文件整个内容读取出来, 返回一个列表,每个元素即为一行。
f = open('d:/test.txt', 'r')
lines = f.readlines()
print(lines)
f.close()

在这里插入图片描述

此处的 \n 即为换行符。

4.3 🍎关于中文的处理🍎

当文件内容存在中文的时候, 读取文件内容不一定就顺利。有时候会出现乱码或者异常。

出现上面的根本原因就是文件本身的编码方式与Python代码读取文件的编码方式不匹配。

Python3 中默认打开文件的字符集跟随系统, 而 Windows 简体中文版的字符集采用了 GBK, 所以如果文件本身是 GBK 的编码, 直接就能正确处理,如果文件本身是其他编码(比如 UTF-8), 那么直接打开就可能出现问题。

为了解决编码问题可以在使用 open 打开文件时加上 encoding 参数指定字符集编码方式来解决问题。

f = open('d:/test.txt', 'r', encoding='utf8')

4.4 🍎使用上下文管理器🍎

打开文件之后, 是容易忘记关闭的. Python 提供了 上下文管理器 , 来帮助程序猿自动关闭文件。

  • 使用 with 语句打开文件。
  • with 内部的代码块执行完毕后, 就会自动调用关闭方法。
with open('d:/test.txt', 'r', encoding='utf8') as f:
    lines = f.readlines()
    print(lines)
  • 28
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值