python中的模块

python基础语法

模块

什么是模块

  • 类可以封装方法和属性,而模块是最高级别的程序组织单元,什么都能封装。
模块
  • 在模块中,我们不但可以直接存放变量,还能存放函数,还能存放类
模块与封装
  • 独特的是,定义变量需要用赋值语句,封装函数需要用def语句,封装类需要用class语句,但封装模块不需要任何语句。
  • 之所以不用任何语句,是因为每一份单独的Python代码文件(后缀名是.py的文件)就是一个单独的模块。
  • vscode或pycharm等编程工具编写python程序,每次都需要先创建一个后缀名为.py的Python程序文件。每一个单独的py文件,本质上都是一个模块。
  • 封装模块的目的也是为了把程序代码和数据存放起来以便再次利用。如果封装成类和函数,主要还是便于自己调用,但封装了模块,我们不仅能自己使用,文件的方式也很容易共享给其他人使用。
  • 使用模块主要有两种方式,一种是自己建立模块并使用,另外一种是使用他人共享的模块。

使用自己的模块

  • 建立模块,其实就是在主程序的py文件中,使用import语句导入其他py文件。
import函数
  • main.py文件借用并运行了test.py文件里的代码,这就是import语句的作用

import语句

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

案例
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==

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
# 请阅读代码注释

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()# 换行
  • 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

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”三个文件。

from...import...

  • from … import …语句可以让你从模块中导入一个指定的部分到当前模块。
from..import格式

案例

# 【文件:test.py】
def hi():
    print('函数“hi”已经运行!')

# 【文件:main.py】
from test import hi  # 从模块test中导入函数“hi”
hi()  # 使用函数“hi”时无需加上“模块.”前缀
  • 当我们需要从模块中同时导入多个指定内容,也可以用逗号隔开,写成from xx模块 import a,b,c的形式。
from test import a,hi,Go2

print(a)  # 打印变量“a”

hi()  # 调用函数“hi”

A = Go2()  # 实例化“Go2”类
print(A.a)  # 打印实例属性“a”
A.do2()  # 调用实例方法“do2”
  • 对于from … import …语句要注意的是,没有被写在import后面的内容,将不会被导入。
from test import hi # 从模块test中导入函数“hi”

hi()

# 以下语句将会导致报错,因为并没有导入test模块,只是导入test模块中的函数“hi”
test.hey()
  • 当我们需要从模块中指定所有内容直接使用时,可以写成【from xx模块 import 】的形式,代表“模块中所有的变量、函数、类”
from test import *

print(a)  # 打印变量“a”

hi()  # 调用函数“hi”

A = Go2()  # 实例化“Go2”类
print(A.a)  # 打印实例属性“a”
A.do2()  # 调用实例方法“do2”
  • 一般情况下,我们不要为了图方便直接使用【from xx模块 import *】的形式。 *
  • 因为模块.xx的调用形式能通过阅读代码一眼看出是在调用模块中的变量/函数/方法,而去掉模块.后代码就不是那么直观了。

练习

# 【文件: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的属性'庙里有个老和尚,'打印出来。
# 【文件:main.py】

from story import Temple

print(Temple.sentence)

if name == 'main'

程序的入口
  • 对于Python和其他许多编程语言来说,程序都要有一个运行入口。
  • 在Python中,当我们在运行某一个py文件,就能启动程序 ——— 这个py文件就是程序的运行入口。
程序入口
  • 更复杂的情况,我们也可以运行一个主模块,然后层层导入其他模块:
主模块与其它模块

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

代码块 ①……

if __name__ == '__main__':
    代码块 ②……
指明入口
  • 【if name == 'main'】就相当于是 Python 模拟的程序入口

  • 加上这句话后,程序运行效果不会变化,即:当xx.py文件被直接运行时,代码块②将被运行
import story

if __name__ == '__main__':# 加上这句话后,程序运行效果不会变化
    print(story.sentence)
    story.mountain()
    A = story.Temple()
    print(A.sentence)
    A.reading()
    print()

第二种情况
==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
  • 在我们运行代码的时候,会发现if name == 'main'下的语句不会被执行。这是因为==B.py文件并不是我们现在的程序运行入口==,它是被A.py文件导入的。

使用他人的模块

借用内置模块

  • 之前所学习的import time和import random其实就是在导入time和random模块。
  • time模块和random模块是Python的系统内置模块,也就是说Python安装后就准备好了这些模块供使用。
  • Python作为一门胶水语言,一个强大的优势就是它拥有许多第三方的模块可以直接拿来使用。
  • 如果是第三方编写的模块,我们需要先从Python的资源管理库下载安装相关的模块文件。
  • 下载安装的方式是打开终端,Windows用户输入pip install + 模块名;苹果电脑输入:pip3 install + 模块名,点击enter即可。(需要预装python解释器和pip)
  • 例如:爬虫时我们会需要用到requests这个库(库是具有相关功能模块的集合),就需要在终端输入pip3 install requests(Mac用户)的指令。
  • 如果内置模块是用Python语言编写的话,就能找到py文件
  • 用命令random.file找出random模块的文件路径,就可以去打开查看它的代码
random模块
  • 我们熟悉的函数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)
  • 通过阅读源代码我们能找到所有能够使用的变量、函数、类方法。

自学模块

  • 但如果你想要高效地学会使用一个模块,看源代码并不是最佳选项。
  • 学习模块的核心是搞清楚模块的功能,也就是模块中的函数和类方法有什么作用,以及具体使用案例长什么样。
  • 可以直接阅读官方文档;或者也可以直接百度搜索
  • 搜到教程后,我们重点关注的是模块中的函数和类方法有什么作用,然后把使用案例做成笔记
  • 例如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)
  • 另外,我们还可以使用dir()函数查看一个模块,看看它里面有什么变量、函数、类、类方法。
import random  # 调用random模块

print(dir(random))
  • 就像是查户口一样,可以把模块中的函数(函数和类方法)一览无余地暴露出来。对于查到的结果"xx"结构的(如doc),它们是系统相关的函数,不用理会,直接看全英文的函数名即可。
  • 这样查询的好处是便于我们继续搜索完成自学。比如我们在列表中看到一个单词“seed”,我们就可以搜一搜random.seed的用法
  • 即使不是模块,我们也可以用这种方式自学: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']
'''
模块学习小结
  • 比较小的模块(比如random模块)可以通过这样的方式自学,大型模块的学习就比较困难(除非你有充足的专业背景知识)。
  • 比如数据分析需要用到pandas和NumPy模块,网页开发要用到Django模块等等,这些大型模块最好还是在课程上系统学习,避免散乱的学习形不成知识体系。

学习csv模块

  • csv是一种文件格式,你可以把它理解成“简易版excel”。学会了csv模块,你就可以用程序处理简单的电子表格了。
  • 如果要手动新建csv文件,我们可以先新建一个excel表格,然后选择另存为“csv”格式即可。
  • 同样的,当我们有了一张csv格式的表格,我们也可以选择另存为“excel”格式。

  • 使用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模块的话,最简单的方式是先看案例(拉到教程的最后),遇到看不懂的函数,再倒回来查具体使用细节。
  • 跟着案例动手试试如何读取csv文件,可见open()后面跟了两个参数,用csv.reader(文件变量)创建一个reader对象。
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("读取完毕!")

'''
['1', '2', '3', '4', '5']arn_csv.py 
['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写入数据
  • 先创建一个变量名为writer(也可以是其他名字)的实例,创建方式是writer = csv.writer(x),然后使用writer.writerow(列表)就可以给csv文件写入一行列表中的内容。
open()函数

练习

csv文件
  • 用writerow()方法为它追加写入两行列表吧:['4', '猫砂', '25', '1022', '886']、['5', '猫罐头', '18', '2234', '3121']。
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'])
#['4', '猫砂', '25', '1022', '886']
#['5', '猫罐头', '18', '2234', '3121']
  • csv模块虽然比random模块稍微复杂一点点,但按照模块三问(这模块有哪些函数可用?有哪些属性或方法可用?使用格式是什么?)的学习方式,我们一样可以学会它的基本用法。
知识小结

csv小项目——时间记录

import time

input("欢迎使用“时间管理器”!请按回车继续。")

while True:
    task_name = input('请输入任务名:')
    task_time = int(input('你觉得自己至少可以专注这个任务多少分钟?输入 N 分钟'))
    input('此次任务信息:\n我要完成的任务:%s\n我至少要专注:%d分钟\n按回车开始计时:'%(task_name,task_time))
    start = time.time()  # 开始计时
    start_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))  # 格式化日期
    
    # 实际代码:分钟转成秒要乘60,用-1来倒计时。
    # for t in range(task_time*60,0,-1):
    for t in range(task_time,0,-1):
        info = '请专注任务,还要保持专注 ' + str(t) + ' 秒哦!'
        print(info,end="")
        print("\b"*(len(info)*2),end="",flush=True)
        time.sleep(1)
    print('你已经专注了 %d 分钟,很棒~再加把劲,完成任务!'%task_time)  # 倒计时后,才继续运行之后的代码。

    # 询问任务是否完成
    task_status = input('请在任务完成后按输入y:')
    if task_status == 'y':
        end = time.time()  # 一定用户按了 y,就记下结束时间。
        end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))  # 日期格式化
        actual_time = int((end -start)/60)  # 始末时间相减,从秒换算到分,除以60。
        start_end = start_time + '——' + end_time + '\n'
        with open('timelog3.txt','a', encoding = 'utf-8') as f:
            f.write(task_name + ' 的预计时长为:' + str(task_time) + '分钟\n')
            f.write(task_name + ' 的实际时长为:' + str(actual_time) + '分钟,具体时间为:' + start_end)
        again = input('建立一个新任务请按 y, 退出时间日志记录器请按 q:')
        if again == 'q':            
            break
    else:
        print('抱歉,你的输入有误。请重启时间记录器。')

print('愿被你善待的时光,予你美好的回赠。')

os模块的替换案例

import os

list_test = ['一弦一柱思华年。\n','只是当时已惘然。\n']

with open ('poem3.txt','r') as f:
    lines = f.readlines()

with open('poem_new.txt','w') as new:
    for line in lines:
        if line in list_test:
            new.write('____________。\n')
        else:
            new.write(line)

os.replace('poem_new.txt', 'poem3.txt')
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352