赞
踩
在计算机程序的开发过程中,随着程序代码越写越多,在⼀个⽂件⾥代码就会越来越⻓,越来越不容易维护。
为了编写可维护的代码,我们把很多代码按功能分组,分别放到不同的⽂件⾥,这样,每个⽂件包含的代码就相对较少,很多编程语⾔都采⽤这种组织代码的⽅式。在Python
中,⼀个.py
⽂件就可以称之为⼀个模块(Module
)。
代码的可维护性
。其次,编写代码不必从零开始。当⼀个模块编写完毕,就可以被其他地⽅引⽤。我们在编写程序的时候,也经常引⽤其他模块,包括Python
内置的模块和来⾃第三⽅的模块。避免函数名
和变量名冲突
。每个模块有独⽴的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们⾃⼰在编写模块时,不必考虑名字会与其他模块冲突模块分为三种:
help(‘modules’)
查看所有python
⾃带模块列表开源模块
,可通过pip install
模块名 联⽹安装import module_a #导⼊
from module import xx # 导⼊某个模块下的某个⽅法 or ⼦模块
from module.xx.xx import xx as rename #导⼊后⼀个⽅法后重命令
from module.xx.xx import * #导⼊⼀个模块下的所有⽅法,不建议使⽤
module_a.xxx #调⽤
注意:模块⼀旦被调⽤,即相当于执⾏了另外⼀个py⽂件⾥的代码
这个最简单, 创建⼀个.py
⽂件,就可以称之为模块,就可以在另外⼀个程序⾥导⼊
有没有发现,⾃⼰写的模块只能在当前路径下的程序⾥才能导⼊,换⼀个⽬录再导⼊⾃⼰的模块就报错说找不到了, 这是为什么?
这与导⼊模块的查找路径有关
import sys
print(sys.path)
输出(注意不同的电脑可能输出的不太⼀样)
['',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/sitepackages']
你导⼊⼀个模块时,Python解释器会按照上⾯列表顺序去依次到每个⽬录下去匹配你要导⼊的模块名,只要在⼀个⽬录下匹配到了该模块名,就⽴刻导⼊,不再继续往后找。
注意列表第⼀个元素为空,即代表当前⽬录,所以你⾃⼰定义的模块在当前⽬录会被优先导⼊。
我们⾃⼰创建的模块若想在任何地⽅都能调⽤,那就得确保你的模块⽂件⾄少在模块路径的查找列表中。
我们⼀般把⾃⼰写的模块放在⼀个带有“site-packages”
字样的⽬录⾥,我们从⽹上下载安装的各种第三⽅的模块⼀般都放在这个⽬录。
https://pypi.python.org/pypi 是python的开源模块库,截⽌2020年5.26⽇ ,已经收录了236,269个来 ⾃全世界python开发者贡献的模块,⼏乎涵盖了你想⽤python做的任何事情。
事实上每个python开发 者,只要注册⼀个账号就可以往这个平台上传你⾃⼰的模块,这样全世界的开发者都可以容易的下载并 使⽤你的模块。
编译源码
python setup.py build 安装源码
python setup.py install
pip3 install paramiko #paramiko 是模块名
pip命令会⾃动下载模块包并完成安装。
软件⼀般会被⾃动安装你python安装⽬录的这个⼦⽬录⾥
/your_python_install_path/3.6/lib/python3.6/site-packages
pip命令默认会连接在国外的python官⽅服务器下载,速度⽐较慢,你还可以使⽤国内的⾖瓣源,数据会定期同步国外官⽹,速度快好
pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host
pypi.douban.com #alex_sayhi是模块名
-i 后⾯跟的是⾖瓣源地址
—trusted-host 得加上,是通过⽹站https安全验证⽤的
若你写的项⽬
较复杂,有很多代码⽂件的话,为了⽅便管理,可以⽤包
来管理。 ⼀个包其实就是⼀个⽂件⽬录
,你可以把属于同⼀个业务线的代码⽂件都放在同⼀个包⾥。
只需要在⽬录下创建⼀个空的``**init**``.py
⽂件 , 这个⽬录就变成了包。这个⽂件叫包的初始化⽂件,⼀般为空,当然也可以写东⻄,当你调⽤这个包下及其任意⼦包的的任意模块时, 这
个``**init**``.py
⽂件都会先执⾏。以下 有a、b
2个包,a2是a的⼦包,b2是b的⼦包
day6
!"" 课件
#"" a
$ #"" __init__.py
$ !"" a2
$ #"" __init__.py
$ #"" a_mod2.py
$ !"" a_module.py
#"" b
$ #"" __init__.py
$ #"" b2
$ $ #"" __init__.py
$ $ !"" b2_mod.py
$ !"" b_module.py
若在a_module.py模块⾥导⼊b2_mod.py的话,怎么办?
a_module.py的⽂件路径为
/Users/alex/Documents/work/PyProjects/py8days_camp/day6/课件/a/a2/a_module.py
想导⼊成功,直接写以下代码就可以
from day6.课件.b.b2 import b2_mod
os 模块提供了很多允许你的程序
与操作系统
直接交互的功能
import os
方法名 | 解释 |
---|---|
os.getcwd() | 得到当前⼯作⽬录,即当前Python脚本⼯作的⽬录路径 |
os.listdir() | 返回指定⽬录下的所有⽂件和⽬录名 |
os.remove() | 函数⽤来删除⼀个⽂件 |
os.removedirs(r“c:\python”) | 删除多个⽬录 |
os.path.isfile() | 检验给出的路径是否是⼀个⽂件 |
os.path.isdir() | 检验给出的路径是否是⼀个⽬录 |
os.path.isabs() | 判断是否是绝对路径 |
os.path.exists() | 检验给出的路径是否真地存 |
os.path.split() | 返回⼀个路径的⽬录名和⽂件名 |
os.path.splitext() | 分离扩展名 |
os.path.dirname() | 获取路径名 |
os.path.abspath() | 获得绝对路径 |
os.path.basename() | 获取⽂件名 |
os.system() | 运⾏shell命令 |
os.getenv(“HOME”) | 读取操作系统环境变量HOME的值 |
os.environ | 返回操作系统所有的环境变量 |
os.environ.setdefault(‘HOME’,’/home/alex’) | 设置系统环境变量,仅程序运⾏时有效 |
os.linesep | 给出当前平台使⽤的⾏终⽌符 |
os.name | 指示你正在使⽤的平台 |
os.rename(old,new) | 重命名 |
os.makedirs(r"c\python\test") | 创建多级⽬录 |
os.mkdir(“test”) | 创建单个⽬录 |
os.stat(file) | 获取⽂件属性 |
os.chmod(file) | 修改⽂件权限与时间戳 |
os.path.getsize(filename) | 获取⽂件⼤⼩ |
os.path.join(dir,filename) | 结合⽬录名与⽂件名 |
os.chdir(dirname) | 改变⼯作⽬录到dirname |
os.get_terminal_size() | 获取当前终端的⼤⼩ |
os.kill(10884,signal.SIGKILL) | 杀死进程 |
在平常的代码中,我们常常需要与时间打交道。在Python中,与时间处理有关的模块就包括:
time,datetime,calendar(很少⽤,不讲),下⾯分别来介绍。
我们写程序时对时间的处理可以归为以下3种:
时间的显示,在屏幕显示、记录⽇志等 “2022-03-04”
时间的转换,⽐如把字符串格式的⽇期转成Python中的⽇期类型
时间的运算,计算两个⽇期间的差值等
索引(Index) 属性(Attribute) 值(Values)
0 tm_year(年) ⽐如2011
1 tm_mon(⽉) 1 - 12
2 tm_mday(⽇) 1 - 31
3 tm_hour(时) 0 - 23
4 tm_min(分) 0 - 59
5 tm_sec(秒) 0 - 61
6 tm_wday(weekday) 0 - 6(0表示周⼀)
7 tm_yday(⼀年中的第⼏天) 1 - 366
8 tm_isdst(是否是夏令时) 默认为-1
UTC(Coordinated Universal Time,世界协调时)亦即格林威治天⽂时间,世界标准时间。在中国为UTC+8,⼜称东8区。DST(Daylight Saving Time)即夏令时。
将⼀个时间戳转换为当前时区的struct_time。若secs参数未提供,则以当前时间为准。
和localtime()⽅法类似,gmtime()⽅法是将⼀个时间戳转换为UTC时区(0时区)的struct_time。
返回当前时间的时间戳。
将⼀个struct_time转化为时间戳。
线程推迟指定的时间运⾏,单位为秒。
把⼀个代表时间的元组或者struct_time(如由
返回)转化为格式化的时间字符串。如果t未指定,将传⼊
举例: time.strftime(“%Y-%m-%d %X”, time.localtime()) #输出’2017-10-01
12:14:23’
把⼀个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
举例: time.strptime(‘2017-10-3 17:54’,”%Y-%m-%d %H:%M”) #输出
字符串转时间格式对应表
相⽐于time模块,datetime模块的接⼝则更直观、更容易调⽤
datetime模块定义了下⾯这⼏个类:
datetime.date:表示⽇期的类。常⽤的属性有year, month, day;
datetime.time:表示时间的类。常⽤的属性有hour, minute, second, microsecond;
datetime.datetime:表示⽇期时间。
datetime.timedelta:表示时间间隔,即两个时间点之间的⻓度。
datetime.tzinfo:与时区有关的相关信息。(这⾥不详细充分讨论该类,感兴趣的童鞋可以参考
python⼿册
d.year,d.timetuple()等⽅法可以调⽤
> datetime.datetime.now()
datetime.datetime(2017, 10, 1, 12, 53, 11, 821218)
>> datetime.datetime.now() + datetime.timedelta(4) #当前时间 +4天
datetime.datetime(2017, 10, 5, 12, 53, 35, 276589)
>> datetime.datetime.now() + datetime.timedelta(hours=4) #当前时间+4⼩时
datetime.datetime(2017, 10, 1, 16, 53, 42, 876275)
>> d.replace(year=2999,month=11,day=30)
datetime.date(2999, 11, 30)
>>> d.replace(year=2999,month=11,day=30)
datetime.date(2999, 11, 30)
程序中有很多地⽅需要⽤到随机字符,⽐如登录⽹站的随机验证码,通过random模块可以很容易⽣成随机字符串
>>> random.randrange(1,10) #返回1-10之间的⼀个随机数,不包括10 >>> random.randint(1,10) #返回1-10之间的⼀个随机数,包括10 >>> random.randrange(0, 100, 2) #随机选取0到100间的偶数 >>> random.random() #返回⼀个随机浮点数 >>> random.choice('abce3#$@1') #返回⼀个给定数据集合中的随机字符 '#' >>> random.sample('abcdefghij',3) #从多个字符中选取特定数量的字符 ['a', 'd', 'b'] #⽣成随机字符串 >>> import string >>> ''.join(random.sample(string.ascii_lowercase + string.digits, 6)) '4fvda1' #洗牌 >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> random.shuffle(a) >>> a [3, 0, 7, 2, 1, 6, 5, 8, 9, 4]
JSON(JavaScriptObject Notation, JS 对象简谱) 是⼀种轻量级的数据交换格式。它采⽤完全独⽴于编程语⾔的⽂本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语⾔。 易于⼈阅读和编写,同时也易于机器解析和⽣成,并有效地提升⽹络传输效率。
Json的作⽤是⽤于不同语⾔接⼝间的数据交换,⽐如你把python的list、dict直接扔给javascript, 它是解析不了的。2个语⾔互相谁也不认识。Json就像是计算机界的英语 ,可以帮各个语⾔之间实现数据类型的相互转换。
Python中的字符串、数字、列表、字典、集合、布尔 类型,都可以被序列化成JSON字符串,被其它任何编程语⾔解析
序列化是指把内存⾥的数据类型转变成字符串,以使其能存储到硬盘或通过⽹络传输到远程,因为硬盘或⽹络传输时只能接受bytes
你打游戏过程中,打累了,停下来,关掉游戏、想过2天再玩,2天之后,游戏⼜从你上次停⽌的地⽅继续运⾏,你上次游戏的进度肯定保存在硬盘上了,是以何种形式呢?游戏过程中产⽣的很多临时数据是不规律的,可能在你关掉游戏时正好有10个列表,3个嵌套字典的数据集合在内存⾥,需要存下来?你如何存?把列表变成⽂件⾥的多⾏多列形式?那嵌套字典呢?根本没法存。所以,若是有种办法可以直接把内存数据存到硬盘上,下次程序再启动,再从硬盘上读回来,还是原来的格式的话,那是极好的。
⽤于序列化的两个模块
json,⽤于字符串 和 python数据类型间进⾏转换
pickle,⽤于python特有的类型 和 python的数据类型间进⾏转换
模块提供了四个功能:dumps、dump、loads、load
import pickle
data = {'k1':123,'k2':'Hello'}
# pickle.dumps 将数据通过特殊的形式转换位只有python语⾔认识的字符串p_str = pickle.dumps(data) # 注意dumps会把数据变成bytes格式
print(p_str)
# pickle.dump 将数据通过特殊的形式转换位只有python语⾔认识的字符串,并写⼊⽂件
with open('result.pk',"wb") as fp:
pickle.dump(data,fp)
# pickle.load 从⽂件⾥加载
f = open("result.pk","rb")
d = pickle.load(f)
print(d)
Json模块也提供了四个功能:dumps、dump、loads、load,⽤法跟pickle⼀致
import json
# json.dumps 将数据通过特殊的形式转换位所有程序语⾔都认识的字符串
j_str = json.dumps(data) # 注意json dumps⽣成的是字符串,不是bytes
print(j_str)
#dump⼊⽂件
with open('result.json','w') as fp:
json.dump(data,fp)
#从⽂件⾥load
with open("result.json") as f:
d = json.load(f)
print(d)
JSON:
优点:跨语⾔(不同语⾔间的数据传递可⽤json交接)、体积⼩
缺点:只能⽀持int\str\list\tuple\dict
Pickle:
优点:专为python设计,⽀持python所有的数据类型
缺点:只能在python中使⽤,存储数据占空间⼤
第3⽅开源模块,安装
pip install openpyxl
from openpyxl import Workbook
# 实例化
wb = Workbook()
# 获取当前active的sheet
ws = wb.active
print(sheet.title) # 打印sheet表名
sheet.title = "salary luffy" # 改sheet 名
>>> from openpyxl import load_workbook
>>> wb2 = load_workbook('⽂件名称.xlsx')
# ⽅式⼀:数据可以直接分配到单元格中(可以输⼊公式)
sheet["C5"] = "Hello ⾦⻆⼤王"
sheet["C7"] = "Hello ⾦⻆⼤王2"
# ⽅式⼆:可以附加⾏,从第⼀列开始附加(从最下⽅空⽩处,最左开始)(可以输⼊多⾏)
sheet.append([1, 2, 3])
# ⽅式三:Python 类型会被⾃动转换
sheet['A3'] = datetime.datetime.now().strftime("%Y-%m-%d")
# sheet 名称可以作为 key 进⾏索引
ws3 = wb["New Title"]
ws4 = wb.get_sheet_by_name("New Title")
print(wb.get_sheet_names()) # 打印所有的sheet
sheet = wb.worksheets[0] # 获得第1个sheet
wb.save('⽂件名称.xlsx')
按⾏遍历
for row in sheet: # 循环获取表数据
for cell in row: # 循环获取每个单元格数据
print(cell.value, end=",")
print()
按列遍历
# A1, A2, A3这样的顺序
for column in sheet.columns:
for cell in column:
print(cell.value,end=",")
print()
遍历指定⾏&列
# 从第2⾏开始⾄第5⾏,每⾏打印5列
for row in sheet.iter_rows(min_row=2,max_row=5,max_col=5):
for cell in row:
print(cell.value,end=",")
print()
遍历指定⼏列的数据
# 取得第2-第5列的数据
for col in sheet.iter_cols(min_col=2,max_col=5,):
for i in col:
print(i.value,end=",")
print()
# ⽅式⼀
wb.remove(sheet)
# ⽅式⼆
del wb[sheet]
需导⼊的类
from openpyxl.styles import Font, colors, Alignment
字体
下⾯的代码指定了等线24号,加粗斜体,字体颜⾊红⾊。直接使⽤cell的font属性,将Font对象赋值给它。
bold_itatic_24_font = Font(name='等线', size=24, italic=True, color=colors.RED,
bold=True) # 声明样式
sheet['A1'].font = bold_itatic_24_font # 给单元格设置样式
对⻬⽅式
也是直接使⽤cell的属性aligment,这⾥指定垂直居中和⽔平居中。除了center,还可以使⽤right、left等等参数。
# 设置B1中的数据垂直居中和⽔平居中
sheet['B1'].alignment = Alignment(horizontal='center', vertical='center')
设置⾏⾼&列宽
# 第2⾏⾏⾼
sheet.row_dimensions[2].height = 40
# C列列宽
sheet.column_dimensions['C'].width = 30
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是⼀组⽤于由源地址到⽬的地址传送邮件的规则,由它来控制信件的中转⽅式
想实现发送邮件需经过以下⼏步:
Python
对SMTP
⽀持有 smtplib
和email
两个模块, email 负责构造邮件, smtplib 负责发送邮件,它对smtp
协议进⾏了简单的封装。。
发送⼀封最简单的信语法如下:
import smtplib from email.mime.text import MIMEText # 邮件正⽂ from email.header import Header # 邮件头 # 登录邮件服务器 smtp_obj = smtplib.SMTP_SSL("smtp.exmail.qq.com", 465) # 发件⼈邮箱中的SMTP服务 器,端⼝是25 smtp_obj.login("nami@luffycity.com", "xxxx-sd#gf") # 括号中对应的是发件⼈邮箱账 号、邮箱密码 #smtp_obj.set_debuglevel(1) # 显示调试信息 # 设置邮件头信息 msg = MIMEText("Hello, ⼩哥哥,约么?800上⻔,新到学⽣妹...", "plain", "utf-8") msg["From"] = Header("来⾃娜美的问候","utf-8") # 发送者 msg["To"] = Header("有缘⼈","utf-8") # 接收者 msg["Subject"] = Header("娜美的信","utf-8") # 主题 # 发送 smtp_obj.sendmail("nami@luffycity.com", ["alex@luffycity.com", "317822232@qq.com"], msg.as_string())
发送HTML格式的邮件
只需要改⼀下 MIMEText() 第2个参数为 html 就可以
# 设置邮件头信息
mail_body = '''
<h5>hello,⼩哥哥</h5>
<p>
⼩哥哥,约么?800,新到学⽣妹.. <a
href="http://wx1.sinaimg.cn/mw1024/5ff6135fgy1gdnghz2vbsg205k09ob2d.gif">这是我
的照⽚</a></p>
</p>
'''
msg = MIMEText(mail_body, "html", "utf-8")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。