【python基础知识】17.模块的概念以及如何引入

简介: 【python基础知识】17.模块的概念以及如何引入

前言


本关要学习的知识是“模块”。虽然说是新知识,但我们在前面的课程经常cue到它,而且比起“类和对象”,模块的知识相对简单一些。


开门见山,我们先来谈一谈什么是模块。


什么是模块


之前我们已经学过,类可以封装方法和属性,就像这样:

1.png

用书里的话说:模块是最高级别的程序组织单元。这句话的意思是,模块什么都能封装,就像这样:2.png在模块中,我们不但可以直接存放变量,还能存放函数,还能存放类。

3.png

更独特的是,定义变量需要用赋值语句,封装函数需要用def语句,封装类需要用class语句,但封装模块不需要任何语句。

之所以不用任何语句,是因为每一份单独的Python代码文件(后缀名是.py的文件)就是一个单独的模块。

如果你使用过vscode或pycharm等编程工具编写python程序,每次都需要先创建一个后缀名为.py的Python程序文件,才能运行程序:

4.png在平时的学习中,其实我们每次运行的代码,本质上都是在运行一个名为main.py的程序文件:(只不过被隐藏在了终端里)

5.png

像这样:每一个单独的py文件,本质上都是一个模块。

封装模块的目的也是为了把程序代码和数据存放起来以便再次利用。如果封装成类和函数,主要还是便于自己调用,但封装了模块,我们不仅能自己使用,文件的方式也很容易共享给其他人使用。

所以,我们使用模块主要有两种方式,一种是自己建立模块并使用,另外一种是使用他人共享的模块。

使用自己的模块


建立模块,其实就是在主程序的py文件中,使用import语句导入其他py文件。

我们看一个小例子,这个例子中有两个模块,一个是test.py文件,另一个是main.py文件。

请你阅读两个文件中的代码,并运行main.py文件。

6.png7.png

运行main.py的结果:

模块test已经成功运行!

你看,是不是发现main.py文件借用并运行了test.py文件里的代码了?这就是import语句起作用了。


模块相关的常用语句主要有3个,我们接下来一个个来看。


import语句

8.png

我们使用import语句导入一个模块,最主要的目的并不是运行模块中的执行语句,而是为了利用模块中已经封装好的变量、函数、类。9.png

再来看一个案例。

a = '我是模块中的变量a'
def hi():
    a = '我是函数里的变量a'
    print('函数“hi”已经运行!')
class Go2:
    a = '我是类2中的变量a'
    def do2(self):
        print('函数“do2”已经运行!')
print(a)  # 打印变量“a”
hi()  # 调用函数“hi”
A = Go2()  # 实例化“Go2”类
print(A.a)  # 打印实例属性“a”
A.do2()  # 调用实例方法“do2”

麻雀虽小,五脏俱全。这段代码中基本上展现了所有的调用方式。

现在我们要做的是把这段代码拆分成两个模块,把封装好的变量、函数、类,放到test.py文件中,把执行相关的语句放到main.py文件中。

请你运行体验拆分后的代码:

test.py和main.py在同一目录下。

test.py文件内容:

a = '我是模块中的变量a'
def hi():
    a = '我是函数里的变量a'
    print('函数“hi”已经运行!')
class Go2:
    a = '我是类2中的变量a'
    def do2(self):
        print('函数“do2”已经运行!')

main.py文件内容:

import test
print(test.a)
test.hi()
A = test.Go2()
print(A.a)
A.do2()

main.py运行结果:

我是模块中的变量a
函数“hi”已经运行!
我是类2中的变量a
函数“do2”已经运行!

你是否注意到,当我们导入模块后,要使用模块中的变量、函数、类,需要在使用时加上模块.的格式。请阅读主程序main.py的代码注释:

# 这是主程序main.py
# 请阅读代码注释
import test  # 导入test模块
print(test.a)  # 使用“模块.变量”调用模块中的变量
test.hi()  # 使用“模块.函数()”调用模块中的函数
A = test.Go2()  # 使用“变量 = 模块.类()”实例化模块中的类
print(A.a)  # 实例化后,不再需要“模块.”
A.do2()  # 实例化后,不再需要“模块.”

到这里,我们来做个练习。下面有一段代码:

sentence = '从前有座山,'
def mountain():
    print('山里有座庙,')
class Temple:
    sentence = '庙里有个老和尚,'
    def reading(self):
        print('在讲一个长长的故事。')
for i in range(10):
    print(sentence)
    mountain()
    A = Temple()
    print(A.sentence)
    A.reading()
    print()

请你把这段代码拆分到两个模块中,其中执行语句放到main.py文件,封装好的变量、函数和类放到story.py文件。


参考代码:

# 【文件:story.py】
sentence = '从前有座山,'
def mountain():
    print('山里有座庙,')
class Temple:
    sentence = '庙里有个老和尚,'
    def reading(self):
        print('在讲一个长长的故事。')
# 【文件:main.py】
import story
for i in range(10):
    print(story.sentence)
    story.mountain()
    A = story.Temple()
    print(A.sentence)
    A.reading()
    print()

import语句还有一种用法是import…as…。比如我们觉得import story太长,就可以用import story as s语句,意思是为“story”取个别名为“s”。


上面的案例中,main.py文件可以写成这样:

# 文件:main.py
import story as s
for i in range(10):
    print(s.sentence)
    s.mountain()
    A = s.Temple()
    print(A.sentence)
    A.reading()
    print()

另外,当我们需要同时导入多个模块时,可以用逗号隔开。比如import a,b,c可以同时导入“a.py,b.py,c.py”三个文件。


好,学完了import语句,我们接着学习from … import …语句。


from … import … 语句

10.png

from … import …语句可以让你从模块中导入一个指定的部分到当前模块。格式如下:11.png我们来看一个例子:

# 【文件:test.py】
def hi():
    print('函数“hi”已经运行!')
# 【文件:main.py】
from test import hi  # 从模块test中导入函数“hi”
hi()  # 使用函数“hi”时无需加上“模块.”前缀

你来运行一下试试看:


运行结果:

函数“hi”已经运行!

当我们需要从模块中同时导入多个指定内容,也可以用逗号隔开,写成from xx模块 import a,b,c的形式。我们再运行一个小案例。

#【文件:test.py】
a = '我是模块中的变量a'
def hi():
    a = '我是函数里的变量a'
    print('函数“hi”已经运行!')
class Go2:
    a = '我是类2中的变量a'
    def do2(self):
        print('函数“do2”已经运行!')
# 【文件:main.py】
from test import a,hi,Go2
print(a)  # 打印变量“a”
hi()  # 调用函数“hi”
A = Go2()  # 实例化“Go2”类
print(A.a)  # 打印实例属性“a”
A.do2()  # 调用实例方法“do2”

运行结果:

我是模块中的变量a
函数“hi”已经运行!
我是类2中的变量a
函数“do2”已经运行!

对于from … import …语句要注意的是,没有被写在import后面的内容,将不会被导入。


比如以下代码将会报错,因为使用了没有被导入的函数:

#【test.py】文件内容
def hi():
    print('函数“hi”已经运行!') 
def hey():
    print('函数“hey”已经运行!') 
#【main.py】文件内容
from test import hi # 从模块test中导入函数“hi”
hi()
# 以下语句将会导致报错,因为并没有导入test模块,只是导入test模块中的函数“hi”,改成test.key()即可正常运行
hey()

当我们需要从模块中指定所有内容直接使用时,可以写成【from xx模块 import *】的形式,*代表“模块中所有的变量、函数、类”,我们再运行一个小案例。

#【test.py】文件
a = '我是模块中的变量a'
def hi():
    a = '我是函数里的变量a'
    print('函数“hi”已经运行!')
class Go2:
    a = '我是类2中的变量a'
    def do2(self):
        print('函数“do2”已经运行!')
#【main.py】文件
from test import *
print(a)  # 打印变量“a”
hi()  # 调用函数“hi”
A = Go2()  # 实例化“Go2”类
print(A.a)  # 打印实例属性“a”
A.do2()  # 调用实例方法“do2”
运行结果:
```python
我是模块中的变量a
函数“hi”已经运行!
我是类2中的变量a
函数“do2”已经运行!
不过,一般情况下,我们不要为了图方便直接使用【from xx模块 import *】的形式。
这是因为,模块.xx的调用形式能通过阅读代码一眼看出是在调用模块中的变量/函数/方法,而去掉模块.后代码就不是那么直观了。
到这里我们学完了from … import …语句,再来做一个练习吧。请看以下代码:
```python
# 【文件:story.py】
sentence = '从前有座山,'
def mountain():
    print('山里有座庙,')
class Temple:
    sentence = '庙里有个老和尚,'
    def reading(self):
        print('在讲一个长长的故事。')
# 【文件:main.py】
import story
for i in range(10):
    print(story.sentence)
    story.mountain()
    A = story.Temple()
    print(A.sentence)
    A.reading()
    print()

题目要求:在main.py文件导入story模块,将类Temple的属性’庙里有个老和尚,'打印出来。


要直接使用Temple类的属性,我们需要在导入的时候指定Temple类(不能直接指定类属性)。参考答案是这样的:

# 【文件:story.py】
sentence = '从前有座山,'
def mountain():
    print('山里有座庙,')
class Temple:
    sentence = '庙里有个老和尚,'
    def reading(self):
        print('在讲一个长长的故事。')
# 【文件:main.py】
from story import Temple
print(Temple.sentence)

学会了import语句和from … import …语句后,你就能愉快地导入模块了。我们接着学习下一个语句。


if name == ‘main’

12.png

为了解释什么是【if name == ‘main’】,我先给大家讲解一个概念“程序的入口”。

对于Python和其他许多编程语言来说,程序都要有一个运行入口。

在Python中,当我们在运行某一个py文件,就能启动程序 ——— 这个py文件就是程序的运行入口。

拿我们刚才的课堂练习为例:

13.png

更复杂的情况,我们也可以运行一个主模块,然后层层导入其他模块:14.png

但是,当我们有了一大堆py文件组成一个程序的时候,为了【指明】某个py文件是程序的运行入口,我们可以在该py文件中写出这样的代码:

# 【文件:xx.py】
代码块 ①……
if __name__ == '__main__':
    代码块 ②……

这句话的意思是这样的:

15.png

这里的【if name == ‘main’】就相当于是 Python 模拟的程序入口。Python 本身并没有规定这么写,这是一种程序员达成共识的编码习惯。


第一种情况:加上这句话后,程序运行效果不会变化,我们来试试:

#【story.py文件】
sentence = '从前有坐山,'
def mountain():
    print('山里有座庙,')
class Temple:
    sentence = '庙里有个老和尚,'
    def reading(self):
        print('在讲一个长长的故事。')
#【main.py】文件
import story
if __name__ == '__main__':
    print(story.sentence)
    story.mountain()
    A = story.Temple()
    print(A.sentence)
    A.reading()
    print()

运行结果:

从前有坐山,
山里有座庙,
庙里有个老和尚,
在讲一个长长的故事。

我们解释了“当xx.py文件被直接运行时,代码块②将被运行”,再解释一下“xx.py文件作为模块是被其他程序导入时,代码块②不被运行。”


我们来运行体验两段代码。这是第一段:

# 【B.py】文件
a = '我是模块中的变量a'
def hi():
    a = '我是函数里的变量a'
    print('函数“hi”已经运行!')
class Go2:
    a = '我是类2中的变量a'
    def do2(self):
        print('函数“do2”已经运行!')
print('【载入模块时,所有语句都会被运行】')
print(a)
hi()
b = Go2()
print(Go2.a)
b.do2()
【A.py】文件
import B

运行A.py文件的结果:

【载入模块时,所有语句都会被运行】
我是模块中的变量a
函数“hi”已经运行!
我是类2中的变量a
函数“do2”已经运行!

第一段代码没有使用if name == ‘main’,所有语句都会被运行。


这是第二段:(如果你运行A.py文件,看到运行结果什么都没有,那就是对的)

# 【B.py】文件
a = '我是模块中的变量a'
def hi():
    a = '我是函数里的变量a'
    print('函数“hi”已经运行!')
class Go1:  # 如果没有继承的类,class语句中可以省略括号,但定义函数的def语句括号不能省
    a = '我是类1中的变量a'
    @classmethod
    def do1(cls):
        print('函数“do1”已经运行!')
class Go2:
    a = '我是类2中的变量a'
    def do2(self):
        print('函数“do2”已经运行!')
if __name__ == '__main__':
    print('是主模块的时候才会执行以下语句:')
    print(a)
    hi()
    b = Go2()
    print(Go2.a)
    b.do2()
# 【A.py】文件
import B

现在我们运行A.py代码的时候,会发现if name == 'main’下的语句不会被执行。这是因为B.py文件并不是我们现在的程序运行入口,它是被A.py文件导入的。

关于这一个点目前你只需有个印象即可。接下来,我们来看看如何“使用他人的模块”。

使用他人的模块


在之前的项目实操中,我们常常用到这样的语句:

import time   
print('第一句话,过两秒出现第二句。')
time.sleep(2)
print('第二句话。')

又或者用到这样的功能:

import random  
a = random.randint(0,100)  # 随机从0-100(包括0和100)之间抽取一个数字
print(a)

这两个例子中的第一句代码import time和import random其实就是在导入time和random模块。


初探借用模块

16.png

time模块和random模块是Python的系统内置模块,也就是说Python安装后就准备好了这些模块供你使用。

此外,Python作为一门胶水语言,一个强大的优势就是它拥有许多第三方的模块可以直接拿来使用。

如果是第三方编写的模块,我们需要先从Python的资源管理库下载安装相关的模块文件。

下载安装的方式是打开终端,Windows用户输入pip install + 模块名;苹果电脑输入:pip3 install + 模块名,点击enter即可。(需要预装python解释器和pip)

比如说,爬虫时我们会需要用到requests这个库(库是具有相关功能模块的集合),就需要在终端输入pip3 install requests(Mac用户)的指令

17.png

第三方模块的使用我们会在之后的其他课程具体介绍,今天我们主要来学习Python的内置模块。


如果内置模块是用Python语言编写的话,就能找到py文件:18.png

我们用命令random.__file__找出了random模块的文件路径,就可以去打开查看它的代码:

from warnings import warn as _warn
from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
from os import urandom as _urandom
from _collections_abc import Set as _Set, Sequence as _Sequence
from hashlib import sha512 as _sha512
import _random
__all__ = ["Random","seed","random","uniform","randint","choice","sample",
           "randrange","shuffle","normalvariate","lognormvariate",
           "expovariate","vonmisesvariate","gammavariate","triangular",
           "gauss","betavariate","paretovariate","weibullvariate",
           "getstate","setstate", "getrandbits",
           "SystemRandom"]
NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
TWOPI = 2.0*_pi
LOG4 = _log(4.0)
SG_MAGICCONST = 1.0 + _log(4.5)
BPF = 53        # Number of bits in a float
RECIP_BPF = 2**-BPF
class Random(_random.Random):
    VERSION = 3     # used by getstate/setstate
    def __init__(self, x=None):
        self.seed(x)
        self.gauss_next = None
    def seed(self, a=None, version=2):
        if a is None:
            try:
                # Seed with enough bytes to span the 19937 bit
                # state space for the Mersenne Twister
                a = int.from_bytes(_urandom(2500), 'big')
            except NotImplementedError:
                import time
                a = int(time.time() * 256) # use fractional seconds
        if version == 2:
            if isinstance(a, (str, bytes, bytearray)):
                if isinstance(a, str):
                    a = a.encode()
                a += _sha512(a).digest()
                a = int.from_bytes(a, 'big')
        super().seed(a)
        self.gauss_next = None
……
……

由于代码太长,我们就不全部展示了。不过可以看到,random模块的源代码是这样的结构:

19.png我们熟悉的函数random.choice(list),功能是从列表中随机抽取一个元素并返回。它的代码被找到了:

def choice(self, seq):
    """Choose a random element from a non-empty sequence."""
    try:
        i = self._randbelow(len(seq))
    except ValueError:
        raise IndexError('Cannot choose from an empty sequence')
    return seq[i]

另一个熟悉的函数random.randint(a,b),功能是在a到b的范围随机抽取一个整数。它的代码也被找到了:

def randint(self, a, b):
    """Return random integer in range [a, b], including both end points."""
    return self.randrange(a, b+1)

像这样,通过阅读源代码我们能找到所有能够使用的变量、函数、类方法。


虽然你可以通过看源代码的方式来理解这个模块的功能。但如果你想要高效地学会使用一个模块,看源代码并不是最佳选项。我们接着谈谈“如何自学模块”。


如何自学模块

20.png

学习模块的核心是搞清楚模块的功能,也就是模块中的函数和类方法有什么作用,以及具体使用案例长什么样。

用自学“random”模块为例,如果英文好的同学,可以直接阅读官方文档:https://docs.python.org/3.6/library/random.html

或者也可以直接百度搜索:21.png

搜到教程后,我们重点关注的是模块中的函数和类方法有什么作用,然后把使用案例做成笔记。


例如random模块的关键知识(也就是比较有用的函数和类方法),可以做成这样的笔记:

import random  # 调用random模块
a = random.random()  # 随机从0-1之间(包括0不包括1)抽取一个小数
print(a)
a = random.randint(0,100)  # 随机从0-100(包括0和100)之间抽取一个数字
print(a)
a = random.choice('abcdefg')  # 随机从字符串,列表等对象中抽取一个元素(可能会重复)
print(a)
a = random.sample('abcdefg', 3) # 随机从字符串,列表等对象中抽取多个不重复的元素
print(a)
items = [1, 2, 3, 4, 5, 6]  # “随机洗牌”,比如打乱列表
random.shuffle(items)
print(items)

你来运行一下试试看:


运行结果:

0.645808551740738
13
f
['f', 'c', 'b']
[6, 2, 4, 1, 3, 5]

另外,我们还可以使用dir()函数查看一个模块,看看它里面有什么变量、函数、类、类方法。

import random  # 调用random模块
print(dir(random))

运行结果:

['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_Sequence', '_Set', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_accumulate', '_acos', '_bisect', '_ceil', '_cos', '_e', '_exp', '_inst', '_log', '_os', '_pi', '_random', '_repeat', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'choices', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate']

这就像是查户口一样,可以把模块中的函数(函数和类方法)一览无余地暴露出来。对于查到的结果"xx"结构的(如__doc__),它们是系统相关的函数,我们不用理会,直接看全英文的函数名即可。

这样查询的好处是便于我们继续搜索完成自学。比如我们在列表中看到一个单词“seed”,我们就可以搜一搜random.seed的用法:

22.png

甚至不是模块,我们也可以用这种方式自学:dir(x),可以查询到x相关的函数,x可以是模块,也可以是任意一种对象。

# 请直接运行并体验代码
a = ''  # 设置一个字符串
print('字符串:')
print(dir(a))    # 把字符串相关的函数展示出来
a = []  # 设置一个列表
print('列表:')
print(dir(a))    # 把列表相关的函数展示出来
a = {}  # 设置一个字典
print('字典:')
print(dir(a))  # 把字典相关的函数展示出来

运行结果:

字符串:
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
列表:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
字典:
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

好,我们回到模块上。再次总结一下模块的学习方法,其实可以归纳成三个问题:

23.png

这里想提醒大家的是,比较小的模块(比如random模块)可以通过这样的方式自学,大型模块的学习就比较困难(除非你有充足的专业背景知识)。

例如数据分析需要用到pandas和NumPy模块,网页开发要用到Django模块等等,这些大型模块最好还是在课程上系统学习,避免散乱的学习形不成知识体系。

以目前大家的水平来说,有一些很实用,又不难学的模块,已经足够我们探索了。在今天的最后,我想手把手带大家自学一个模块。

学习csv模块

24.png

今天想带大家学习的模块是csv模块。之所以教大家这个模块,是因为这个模块既简单又实用。


csv是一种文件格式,你可以把它理解成“简易版excel”。学会了csv模块,你就可以用程序处理简单的电子表格了。25.png

如果要手动新建csv文件,我们可以先新建一个excel表格,然后选择另存为“csv”格式即可。

26.png

同样的,当我们有了一张csv格式的表格,我们也可以选择另存为“excel”格式。


对csv文件的介绍就到这里。下面继续学习如何用csv模块读写csv文件。


我们使用import语句导入csv模块,然后用dir()函数看看它里面有什么东西:

# 请直接运行并体验代码
import csv
# dir()函数会得到一个列表,用for循环一行行打印列表比较直观
for i in dir(csv):
    print(i)

运行结果:

Dialect
DictReader
DictWriter
Error
QUOTE_ALL
QUOTE_MINIMAL
QUOTE_NONE
QUOTE_NONNUMERIC
Sniffer
StringIO
_Dialect
__all__
__builtins__
__cached__
__doc__
__file__
__loader__
__name__
__package__
__spec__
__version__
excel
excel_tab
field_size_limit
get_dialect
list_dialects
re
reader
register_dialect
unix_dialect
unregister_dialect
writer

同时,我们可以搜索到csv模块的官方英文教程:

https://docs.python.org/3.6/library/csv.html

中文教程:https://yiyibooks.cn/xx/python_352/library/csv.html#module-csv

如果你要通过阅读这份教程来学习csv模块的话,最简单的方式是先看案例(拉到教程的最后),遇到看不懂的函数,再倒回来查具体使用细节。

27.png

现在我们也跟着案例动手试试如何读取csv文件,可见open()后面跟了两个参数,用csv.reader(文件变量)创建一个reader对象。


我们新建了一个名为test.csv的文件,里面的内容是这样:

28.png

然后我们运行learn_csv.py文件的几行代码,你就能print出csv文件中的每一行信息。

import csv
with open("test.csv",newline = '')  as f:
    reader = csv.reader(f)
    #使用csv的reader()方法,创建一个reader对象
    for row in reader: 
    #遍历reader对象的每一行
        print(row)
print("读取完毕!")

运行结果:

['\ufeff1', '2', '3', '4', '5']
['6', '7', '8', '9', '10']
['11', '12', '13', '14', '15']
['16', '17', '18', '19', '20']
['21', '22', '23', '24', '25']
['26', '27', '28', '29', '30']
['31', '32', '33', '34', '35']
['36', '37', '38', '39', '40']
读取完毕!

我们可以看到,终端输出的每一行信息都是一个列表。


我们来做一个练习,下面有一个csv文件:

29.png

你来试试把它的每一行打印出来吧!


参考代码:

import csv
with open('test.csv', newline = '', encoding = 'utf-8')  as f:
    #参数encoding = 'utf-8'防止出现乱码

运行结果:

商品编号,商品名称,单价,库存,销量
1,猫零食,12,3133,5164
2,普通猫粮,33,5055,2231
3,猫粮四合一,187,212,334

以上就是读取csv文件的写法,接下来我们来看如何往csv格式文件写入数据。


写入数据的方式是这样的:

30.png

先创建一个变量名为writer(也可以是其他名字)的实例,创建方式是writer = csv.writer(x),然后使用writer.writerow(列表)就可以给csv文件写入一行列表中的内容。


另外关于open函数的参数,也就是图中的’a’,我们来复习一下:31.png

我们来做一个练习,还是这个商品列表的csv文件:

32.png

你来试试用writerow()方法为它追加写入两行列表吧:[‘4’, ‘猫砂’, ‘25’, ‘1022’, ‘886’]、[‘5’, ‘猫罐头’, ‘18’, ‘2234’, ‘3121’]。


参考代码:


在本地编辑器自行创建一个csv文件,并运行参考代码即可:

import csv
with open('test.csv','a', newline='',encoding='utf-8') as f:
    writer  = csv.writer(f)
    writer.writerow(['4', '猫砂', '25', '1022', '886'])
    writer.writerow(['5', '猫罐头', '18', '2234', '3121'])
————————————————
版权声明:本文为CSDN博主「大师兄6668」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41308872/article/details/132290758

到这里,最基本的csv表格读取和录入方法我们就已经学会了。csv模块虽然比random模块稍微复杂一点点,但按照模块三问(这模块有哪些函数可用?有哪些属性或方法可用?使用格式是什么?)的学习方式,我们一样可以学会它的基本用法。


总结


最后,对今天的知识做个总结:

33.png34.png

学完了模块,所有的基础知识你也学习完毕了。从今天起,你已经不再是一个麻瓜了。

之于编程的魔法世界,你已经能看明白这个世界的构造,懂得学习的方法和进阶的路径,我们称之为初窥门径。

这是我们当下的仰望星空,但并非终点。如果你肯把头抬得更高,你还能看到另一片更广阔的天地,是开源精神培育的热土。

相关文章
|
16天前
|
安全 大数据 程序员
Python operator模块的methodcaller:一行代码搞定对象方法调用的黑科技
`operator.methodcaller`是Python中处理对象方法调用的高效工具,替代冗长Lambda,提升代码可读性与性能。适用于数据过滤、排序、转换等场景,支持参数传递与链式调用,是函数式编程的隐藏利器。
62 4
|
10天前
|
存储 数据库 开发者
Python SQLite模块:轻量级数据库的实战指南
本文深入讲解Python内置sqlite3模块的实战应用,涵盖数据库连接、CRUD操作、事务管理、性能优化及高级特性,结合完整案例,助你快速掌握SQLite在小型项目中的高效使用,是Python开发者必备的轻量级数据库指南。
114 0
|
2月前
|
存储 安全 数据处理
Python 内置模块 collections 详解
`collections` 是 Python 内置模块,提供多种高效数据类型,如 `namedtuple`、`deque`、`Counter` 等,帮助开发者优化数据处理流程,提升代码可读性与性能,适用于复杂数据结构管理与高效操作场景。
104 0
|
3月前
|
数据安全/隐私保护 Python
抖音私信脚本app,协议私信群发工具,抖音python私信模块
这个实现包含三个主要模块:抖音私信核心功能类、辅助工具类和主程序入口。核心功能包括登录
|
6月前
|
Python
Python教程:os 与 sys 模块详细用法
os 模块用于与操作系统交互,主要涉及夹操作、路径操作和其他操作。例如,`os.rename()` 重命名文件,`os.mkdir()` 创建文件夹,`os.path.abspath()` 获取文件绝对路径等。sys 模块则用于与 Python 解释器交互,常用功能如 `sys.path` 查看模块搜索路径,`sys.platform` 检测操作系统等。这些模块提供了丰富的工具,便于开发中处理系统和文件相关任务。
243 14
|
10月前
|
Python
Python Internet 模块
Python Internet 模块。
212 74
|
7月前
|
人工智能 自然语言处理 Shell
[oeasy]python070_如何导入模块_导入模块的作用_hello_dunder_双下划线
本文介绍了如何在Python中导入模块及其作用,重点讲解了`__hello__`模块的导入与使用。通过`import`命令可以将外部模块引入当前环境,增强代码功能。例如,导入`__hello__`模块后可输出“Hello world!”。此外,还演示了如何使用`help()`和`dir()`函数查询模块信息,并展示了导入多个模块的方法。最后,通过一个实例,介绍了如何利用`jieba`、`WordCloud`和`matplotlib`模块生成词云图。总结来说,模块是封装好的功能部件,能够简化编程任务并提高效率。未来将探讨如何创建自定义模块。
87 8
|
7月前
|
缓存 Shell 开发工具
[oeasy]python071_我可以自己做一个模块吗_自定义模块_引入模块_import_diy
本文介绍了 Python 中模块的导入与自定义模块的创建。首先,我们回忆了模块的概念,即封装好功能的部件,并通过导入 `__hello__` 模块实现了输出 "hello world!" 的功能。接着,尝试创建并编辑自己的模块 `my_file.py`,引入 `time` 模块以获取当前时间,并在其中添加自定义输出。
105 5
|
8月前
|
Python API 监控
将Python CLI工具发布为pip模块的完整指南
注册PyPI账户 访问PyPI官网注册账户 推荐使用双因素认证增强安全性 生成API令牌 访问PyPI账户管理 生成具有"Upload packages"权限的令牌,妥善保存 确保模块名唯一性 在PyPI搜索页面验证模块名未被使用 建议使用小写字母和连字符的组合(如my-cli-tool)
151 9
|
9月前
|
Python
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
104 3

热门文章

最新文章

推荐镜像

更多