python modbus类封装_小白详细的 python 模块的运用

小白详细的 python 模块的运用

什么是模块

用书里的话说:模块是最高级别的程序组织单元。这句话的意思是,模块什么都能封装,就像这样:

def8778f723107b1f15295ce5318474a.png

在模块中,我们不但可以直接存放变量,还能存放函数,还能存放类。

62a2892f40d0e62426bcdc5344726f60.png

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

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

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

62adec5b4d8cd643af22ae937dda50e2.png

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

0a995d0dd80673dd96a589344740bb5c.png

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

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

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

使用自己的模块

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

c67ae467b26a30be7a09adf8866a33a7.png
ff387acd8fee032664d091763bf360f1.png

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

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

improt语句

8ba038ccc2bfea4d5eec8dbec1f128c6.png

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

28a54c5e812285a8927787090a6c2ca9.png
60cae4a846bc47aa30e57d5cf88ee9e4.png

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

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

fd1af88d7aceb41782bd6ee1dae4f344.png

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

3c4d4d71df0f713505329a24d2c136b9.png

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

2a85fb0288b41c5f8b374b3e08249d77.png

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

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

from...import..语句

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

d65f950430d15676b9dc07cde3093875.png
b27a0c6eccd986a9adc2f529b3c29b2b.png
b9f4a3d7cf9a07324154b45bd9822003.png

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

f76857aa4da169b56ffd9e6690759fda.png

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

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

e622b9cc712af5465cff9c2f8ce1a3cf.png

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

73aebda0efc575e14b16ce8ae416cd58.png

不过,一般情况下,我们不要为了图方便直接使用【from xx模块 import *】的形式。

这是因为,模块.xx的调用形式能通过阅读代码一眼看出是在调用模块中的变量/函数/方法,而去掉模块.后代码就不是那么直观了。

19835ce36625d7e580bf198f43fe7828.png
dea334b5f255414093b955801943db73.png

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

b854fd7fe218d70ebd1f7c5de87fe1e4.png

要直接使用Temple类的属性,我们需要在导入的时候指定Temple类(不能直接指定类属性)。

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

if __name__ == '__main__'

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

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

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

dfe0ec6c0d0d4076b6fd34fd3be17b99.png

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

49c10881c12aeebe000c7f325a8761fa.png

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

b5c3e285be5850123cd319e478d2f455.png

这句话的意思是这样的:

2473ac5d1d99e7c0125cb8be06f0f529.png

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

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

135dfee887d96ad58fdec301067dee64.png
09bd01a852948f36c413eefbbe72aaf7.png

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

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

1d75325193505343e864f887263bdca5.png
624cfe2402d0c2ad7dfa790eb7e2b884.png

第一段代码没有使用if __name__ == '__main__',所有语句都会被运行。

第一段代码没有使用if __name__ == '__main__',所有语句都会被运行。

6addb6c8b73490afab77e48955f5947c.png
94fb7c37189ad5873ebf53fa53f6652c.png

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

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

初探借用模块

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

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

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

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

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

6512761f4800f92fdc0b5285f269436b.png

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

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

d2ffa5dec95a00b0a0bc115c76a4501e.png

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

a7657b471909fd4260a477a800eaf4c0.png

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

2163578692eed7749abd0e0ea3b0d450.png

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

67ed09c153b26001718778d6c5b1aa4e.png

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

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

如何自学模块

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

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

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

搜到教程后,我们重点关注的是模块中的函数和类方法有什么作用,然后把使用案例做成笔记(还记得第8关谈到的如何做学习笔记么?)。

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

c6ec8fb931defd13ae4ac9911b177960.png

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

86a2257ee8c8c0343d9c9c8378318fb2.png

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

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

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

4c8f04e512caed9c9ed872b969de37a9.png

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

ab577a6cd0b1dac2ef54872653e17748.png

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

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

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

学习CSV模块

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

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

7c2c91f60610ee51afe15363d2859ff3.png

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

96ea1d18d3276b6c8ddc88e009e6d1e2.png

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

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

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

9dc88105752a99fe3af397e79f5299ea.png

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

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

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

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

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

7c2f63237a85a10c19bf3abb7c79c5cc.png

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

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

73dea3ee99832e187c8a8d52200488b3.png

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

a65454fd06bc0a94fc147812eae6a467.png

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

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

e2f8a88ce66f684cdc7cbefe8c73193c.png

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

5989b960cdfabb934f46e0417e32a781.png

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

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

1325c653a0815aa61856c1ad3798ef2e.png

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

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

b406a606bf691b4d502e801e274433ea.png

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

0bd10f8b3f852df44295f638c276a85a.png

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

d1f0636bd821a73446ea7efbbd81d4cc.png

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

ac8ea5706202c46c27a467872de2df2f.png
aa19a4a3c658eab15fec2bfe4922c717.png

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

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

Python的模块正是开源精神的一块块切片。在网络上也有很多优秀的开发者在分享着自己的代码。他们不计辛劳,不计报酬的付出,只是单纯地为了思想的碰撞,为了帮助其他人提高效率,共同推动互联网进步发展。

--------------------------------------------------------

练习一

一个没用模块的“时间记录器”

请运行左侧的代码,并读懂代码中的每一行。

涉及知识:判断、循环、文件读写等。

注:新建文件,在“步骤”旁的“文件”里查看。

# 不用 time模块 的时间记录器。

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

while True:

task_name = input('请输入任务名:')

task_time = int(input('你觉得自己至少可以专注这个任务多少分钟?输入 N 分钟'))

input('此次任务信息:我要完成的任务:%s我至少要专注:%d分钟按回车开始专注:'%(task_name,task_time))

task_status = input('请在任务完成后按输入y:')

actual_time = input('该任务实际用时为几分钟?')

if task_status == 'y':

with open('timelog1.txt','a', encoding = 'utf-8') as f: # 将时间日志文档和代码放一起。

f.write(task_name + ' 的预计时长为:' + str(task_time) + '分钟')

f.write(task_name + ' 的实际时长为:' + str(actual_time) + '分钟')

again = input('建立一个新任务请按 y, 退出时间日志记录器请按 q:')

if again == 'q':

break

else:

print('抱歉,你的输入有误。请重启时间记录器。')

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

----------------------------------------------------------------------------------------

只要我们想通过编程做到更多的事,就避不开主动了解更多知识。

所以,这次的练习,想将主动权更多地交在大家手里。

请你通过搜索和自学,了解并运用下面两个新知识:

time模块中的时间戳(可进行日期运算)和格式化日期(可将日期转换成平常我们所见的格式);

倒计时的功能怎么用print()函数实现,属于之前没有讲过的方法,需要去搜索新的知识。

# 第一行:必不可少的调用模块。

import time

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

while True:

count = 0

task_name = input('请输入任务名:')

task_time = int(input('你觉得自己至少可以专注这个任务多少分钟?输入 N 分钟'))

input('此次任务信息:我要完成的任务:%s我至少要专注:%d分钟按回车开始专注:'%(task_name,task_time))

# 下面应该要有两行代码,自动记录可以计算以及可以打印的开始时间。

#a = int(input('time:'))

b = task_time * 60

# 这里可以加一个倒计时,实时显示还剩多少时间,可参考左侧提供的资料。代码量大概有5行。

while (count < b):

ncount = b - count

print('倒计时开始:%d秒'%(ncount))

time.sleep(1)

count += 1

print('时间到!')

task_status = input('请在任务完成后按输入y:')

actual_time = input('该任务实际用时为几分钟?')

if task_status == 'y':

# 下面应该要有两行代码,自动记录可以计算以及可以打印的结束时间。

# 有了自动记录的始末时间后,记录的代码也需要随之改变。

with open('timelog2.txt','a', encoding = 'utf-8') as f:

f.write(task_name + ' 的预计时长为:' + str(task_time) + '分钟')

f.write(task_name + ' 的实际时长为:' + str(actual_time) + '分钟')

again = input('建立一个新任务请按 y, 退出时间日志记录器请按 q:')

if again == 'q':

break

else:

print('抱歉,你的输入有误。请重启时间记录器。')

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

--------------------------------------------------------------------------------------------

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

while True:

task_name = input('请输入任务名:')

task_time = int(input('你觉得自己至少可以专注这个任务多少分钟?输入 N 分钟'))

input('此次任务信息:我要完成的任务:%s我至少要专注:%d分钟按回车开始计时:'%(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() 函数会把内容放到内存中, 内存中的内容并不一定能够及时刷新显示到屏幕

# 中(应该是要满足某个条件,这个条件现在还不清楚)。 使用flush=True之后,会在

# print结束之后,不管你有没有达到条件,立即将内存中的东西显示到屏幕上,清空缓存。

# 使用场景:

#1.尤其是在while循环中,要想每进行一次while循环体,在屏幕上更新打印的内容就得使用flush = True的参数。

#2. 打开一个文件, 向其写入字符串, 在关闭文件f.close()之前, 打开文件是看不到写入的字符的。 要想在关

# 闭之前实时的看到写入的字符串,应该用flush = True.

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 + ''

with open('timelog3.txt','a', encoding = 'utf-8') as f:

f.write(task_name + ' 的预计时长为:' + str(task_time) + '分钟')

f.write(task_name + ' 的实际时长为:' + str(actual_time) + '分钟,具体时间为:' + start_end)

again = input('建立一个新任务请按 y, 退出时间日志记录器请按 q:')

if again == 'q':

break

else:

print('抱歉,你的输入有误。请重启时间记录器。')

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

----------------------------------------------------------------------------

练习二

os模块学习

#同样,运行后重新打开文件查看变化

import os

with open ('test.txt','r') as f:

lines = f.readlines()

with open('test_new.txt','w') as new: # 新建一个文档

for line in lines:

if line not in ['0','1']:

new.write(line)

# 可以先运行一次代码,然后,再将下面代码的注释取消,再运行一次。

os.replace('test_new.txt', 'test.txt') # 语法:os.replace(file1,file2),将file1重命名为file2,将其替代。

# 请你根据上面的方法,将之前的代码改为用模块 os 实现(可选文档poem2)。

# 在改代码之前,可以先将上面的代码注释,然后取消下面代码的注释。

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

with open ('poem2.txt','r',encoding='utf-8') as f:

lines = f.readlines()

with open('new_poem.txt','w',encoding='utf-8') as new:

for line in lines:

if line in list_test:

new.write('____________。')

else:

new.write(line)

os.replace('new_poem.txt','poem2.txt')

'''

os.getcwd() # 返回当前工作目录

os.listdir(path) # 返回path指定的文件夹包含的文件或文件夹的名字的列表

os.mkdir(path) # 创建文件夹

os.path.abspath(path) # 返回绝对路径

os.path.basename(path) # 返回文件名

os.path.isfile(path) # 判断路径是否为文件

os.path.isdir(path) # 判断路径是否为目录

Python中可以使用第三方库modbus_tk来创建modbus服务端。modbus_tk是一个用于Modbus通信的Python库,它提供了简化和封装modbus协议的功能。使用modbus_tk,开发者可以轻松地创建modbus服务端。 要创建一个modbus服务端,首先需要安装modbus_tk库。可以使用pip工具在Python环境中安装modbus_tk库,命令如下: ``` pip install modbus_tk ``` 安装完成后,可以在Python脚本中导入modbus_tk库并使用它提供的函数和来创建modbus服务端。下面是一个简单的示例: ```python from modbus_tk import modbus_tcp, modbus_rtu # 创建一个modbus TCP服务端 server = modbus_tcp.TcpServer(address='localhost', port=502) server.start() # 创建一个modbus RTU服务端 server = modbus_rtu.RtuServer(port='/dev/ttyUSB0') server.start() # 在服务端上注册一个数据地址范围 server.add_slave(1, address=0x00) # 启动服务端,开始监听客户端请求 server.start() ``` 在上面的代码中,我们首先导入modbus_tk库中的modbus_tcp和modbus_rtu模块。然后,我们通过创建TcpServer对象和RtuServer对象来创建modbus TCP和RTU服务端。可以根据需要指定地址和端口号。接下来,我们使用add_slave方法在服务端上注册一个数据地址范围,这样客户端就可以访问该范围内的数据。最后,我们调用start方法启动服务端,开始监听客户端的请求。 通过以上步骤,我们就可以在Python中创建一个modbus服务端了。可以根据具体的需求来进一步配置和扩展服务端的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值