模块(本篇内容均在PyCharm运行)
以往脚本基本是用 Python 解释器来编程,如果从 Python 解释器退出再进入,那么定义的所有的方法和变量就都消失了。
为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块(Module)。
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 Python 标准库的方法。
小汇总
- 容器–> 数据的封装
- 函数–> 语句的封装
- 类 --> 方法和属性的封装
- 模块–> 程序文件
#创建一个hello.py文件
#hello.py
def hi():
prnt("Hi everyone, I love Python!")
命名空间
命名空间因为对象的不同,也有所区别,可以分为几种:
- 内置命名空间(Built-in Namespaces):Python 运行起来,它们就存在了。内置函数的命名空间都属于内置命名空间,所以,我们可以在任何程序中直接运行它们,比如id(),不需要做什么操作,拿过来就直接使用了。
- 全局命名空间(Module:Global Namespaces):每个模块创建它自己所拥有的全局命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间,也会因为模块的不同而不相互干扰。
- 本地命名空间(Function & Class:Local Namespaces):模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间。如果函数返回了结果或者抛出异常,则本地命名空间也结束了。
程序在查询上述三种命名空间的时候,就按照从里到外的顺序,即:Local Namespaces --> Global Namesspaces --> Built-in Namesspaces。
import hello
hello.hi() # Hi everyone, I love lsgogroup!
hi() # NameError: name 'hi' is not defined
导入模块
#创建一个模块Temp.py
def c2f(cel):
fah = cel * 1.8 + 32
return fah
def f2c(fah):
cel = (fah - 32) / 1.8
return cel
import 模块名
#import Temp.py并分别代入数值计算
import Temp
print('32摄氏度 = %.2f华氏度' % Temp.c2f(32))#代入c2f函数中计算
print('99华氏度 = %.2f摄氏度' % Temp.f2c(99))#代入f2c函数中计算
# 32摄氏度 = 89.60华氏度
# 99华氏度 = 37.22摄氏度
from 模块名import函数名
- 不推荐使用from … import *,原因后文详解。
from Temp import c2f,f2c
print('32摄氏度 = %.2f华氏度'%c2f(32))
print('99华氏度 = %.2f摄氏度'%f2c(99))
# 32摄氏度 = 89.60华氏度
# 99华氏度 = 37.22摄氏度
import 模块名 as 新名字
import Temp as tp
print('32摄氏度 = %.2f华氏度'%tp.c2f(32))
print('99华氏度 = %.2f摄氏度'%tp.f2c(99))
if name == ‘main’
- 对于很多编程语言来说,程序都必须要有一个入口,而 Python 则不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
- 当
.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。 - 具体案例,上一节有介绍。
搜索路径
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
import sys
print(sys.path)
#['C:\\ProgramData\\Anaconda3\\DLLs', 'C:\\ProgramData\\Anaconda3\\lib', 'C:\\ProgramData\\Anaconda3', 'C:\\ProgramData\\Anaconda3\\lib\\site-packages',...]`
原理
使用 import 语句的时候,Python 解释器是怎样找到对应的文件的呢?
这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。
这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。
搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量中。
原理
使用 import 语句的时候,Python 解释器是怎样找到对应的文件的呢?
这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。
这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。
搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量中。
包
包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。
创建包分为三个步骤:
- 创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字。
- 在文件夹中创建一个 init.py 的模块文件,内容可以为空。
- 将相关的模块放入文件夹中。
案例:设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。
- 现存很多种不同的音频文件格式(基本上都是通过后缀名区分的,例如: .wav,.aiff,.au),所以你需要有一组不断增加的模块,用来在不同的格式之间转换。
- 并且针对这些音频数据,还有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果),所以你还需要一组怎么也写不完的模块来处理这些操作。
sound/ 顶层包
__init__.py 初始化 sound 包
formats/ 文件格式转换子包
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ 声音效果子包
__init__.py
echo.py
surround.py
reverse.py
...
filters/ filters 子包
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包,最简单的情况,放一个空的 __init__.py 就可以了。
例如导入子模块echo.py
- 第一种
import sound.effects.echo,这将会导入子模块sound.effects.echo,必须使用全名去访问:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
- 导入子模块:
from sound.effects import echo,这同样会导入子模块: echo,并且不需要那些冗长的前缀,所以可以这样使用:
echo.echofilter(input, output, delay=0.7, atten=4)
- 直接导入:
from sound.effects.echo import echofilter,这种方法会导入子模块: echo,并且可以直接使用echofilter() 函数:
echofilter(input, output, delay=0.7, atten=4)
注意当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。
对from…import *的禁忌原因:
-
Python 会进入文件系统,找到这个包里面所有的子模块,一个一个的把它们都导入进来。
-
导入语句遵循如下规则:如果包定义文件
__init__.py存在一个叫做__all__的列表变量,那么在使用from package import *的时候就把这个列表中的所有名字作为包内容导入。 -
如果
__all__有定义,则导入定义里的子模块。 -
如果
__all__没有定义,使用from sound.effects import *就**不会导入包sound.effects里的任何子模块,只是把包sound.effects和它里面定义的所有内容导入进来(可能运行__init__.py里定义的初始化代码)。 -
上述会把
__init__.py里面定义的所有名字导入进来,并且不会破坏掉在这句话之前导入的所有明确指定的模块。
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
这个例子中,在执行 from…import 前,包 sound.effects 中的 echo 和 surround 模块都被导入到当前的命名空间中了。
通常我们并不主张使用 * 这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。
练习题
-
怎么查出通过 from xx import xx导⼊的可以直接调⽤的⽅法?
-
了解Collection模块,编写程序以查询给定列表中最常见的元素。
题目说明:
输入:language = [‘PHP’, ‘PHP’, ‘Python’, ‘PHP’, ‘Python’, ‘JS’, ‘Python’, ‘Python’,‘PHP’, ‘Python’]
输出:Python
Input file language = ['PHP', 'PHP', 'Python', 'PHP', 'Python', 'JS', 'Python', 'Python','PHP', 'Python'] Output file Python
def most_element(language):
""" Return a list of lines after inserting a word in a specific line. """
# your code here
【答案】
- 看子模块的直接调用的方法
help函数可以查看函数或模块用途的详细说明
dir()函数用来查询一个类或者对象的所有属性
?是自带模块的应用查询,例如可以查看help
2的解题思路:
- 首先,要了解collections模块的应用,collections模块的数据类型:
- namedtuple():生成可以使用名字来访问元素内容的tuple子类
- deque:双端队列,可以快速的从另外一侧追加和推出对象
- counter:计数器
- ordereddict:有序字典
- defaultdict:带有默认值的字典
其中Counter()是本题所需要的的子模块。
- Counter()的应用:Counter()输出的是tuple内含dict({}),所以需要dict化。
- 找到对应的最大的数值,并根据数值对应的key即可。
#2. 了解Collection模块
from collections import Counter
language = ['PHP', 'PHP', 'Python', 'PHP', 'Python', 'JS', 'Python', 'Python','PHP', 'Python']
def the_most(list):
c = Counter(list)
print(c)
max_value = max(dict.values(c))
for key, value in dict.items(c):
if value == max_value:
print('最多出现的元素:',key,'对应的次数:',value)
the_most(language)

参考文献:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017455068170048
https://blog.csdn.net/quanlingtu1272/article/details/96969776
https://www.cnblogs.com/z-x-y/p/9906401.html
datetime 模块
datetime 是 Python 中处理日期的标准模块,它提供了 4 种对日期和时间进行处理的类:datetime、date、time 和 timedelta.
datetime类
datetime.now(tz=None)获取当前的日期时间,输出顺序为:年、月、日、时、分、秒、微妙datetime.timestamp()获取以1970年1月1日为起点记录的秒数。datetime.fromtimestamp(tz=None)使用unixtimestamp创建一个datetime.
class datetime():
def __init__(self, year, month, day, hour, minute, second, microsecond, tzinfo):
pass
def now(cls, tz=None):
pass
def timestamp(self):
pass
def fromtimestamp(cls, t, tz=None):
pass
def date(self):
pass
def time(self):
pass
def year(self):
pass
def month(self):
pass
def day(self):
pass
def hour(self):
pass
def minute(self):
pass
def second(self):
pass
def isoweekday(self):
pass
def strftime(self, fmt):
pass
def combine(cls, date, time, tzinfo=True):
pass
#如何创建一个datetime对象?
import datetime
dt = datetime.datetime(year=2020,month=8,day=8,hour=11,minute=11,second=11)
print(dt) #显示时间
print(dt.timestamp()) #时间戳

通过时间戳反向求时间
dt = datetime.datetime.fromtimestamp(1596856271.0)
print(dt)
print(type(dt))

现在的时间
dt = datetime.datetime.now()
print(dt)
print(type(dt))

datetime.strftime(fmt)格式化datetime对象
| 符号 | 说明 |
|---|---|
%a | 本地简化星期名称(例如Mon) |
%A | 本地完整星期名称(例如Monday) |
%b | 本地简化月份名称(例如Jan) |
%B | 本地完整月份名称(例如January) |
%c | 本地相应的日期表示和时间表示 |
%d | 月内中的一天(0-31) |
%H | 24小时制小时数(0-23) |
%I | 12小时制小时数(01-12) |
%j | 年内的一天(001-366) |
%m | 月份(01-12) |
%M | 分钟数(00-59) |
%p | 本地A.M.或P.M.的等价符 |
%S | 秒(00-59) |
%U | 一年中的星期数(00-53)星期天为星期的开始 |
%w | 星期(0-6),星期天为星期的开始 |
%W | 一年中的星期数(00-53)星期一为星期的开始 |
%x | 本地相应的日期表示 |
%X | 本地相应的时间表示 |
%y | 两位数的年份表示(00-99) |
%Y | 四位数的年份表示(0000-9999) |
%Z | 当前时区的名称(如果是本地时间,返回空字符串) |
%% | %号本身 |
#如何将datetime对象转换为任何格式的日期
import datetime
dt = datetime.datetime(year=2020,month=8,day=8,hour=11,minute=11,second=11)
s = dt.strftime("%Y%m%d %H:%M:%S")
print(s)
s = dt.strftime('%d %B, %Y, %A')
print(s)

#如何将给定日期转换为 "mmm-dd, YYYY" 的格式
import datetime
s = datetime.date(2020,8,8)
# s = datetime.datetime(year=2020,month=8,day=8,hour=11,minute=11,second=11)
s = dt.strftime('%b-%d,%Y')
print(s)

- datetime.date() Return the date part.
- datetime.time() Return the time part, with tzinfo None.
- datetime.year 年
- datetime.month 月
- datetime.day 日
- datetime.hour 小时
- datetime.minute 分钟
- datetime.second 秒
- datetime.isoweekday 星期几
#datetime案例说明
import datetime
s = datetime.datetime(year=2020,month=8,day=8,hour=11,minute=11,second=11)
print(dt.date())
print(type(dt.date()))
print(dt.time())
print(type(dt.time()))
print(dt.year)
print(dt.month)
print(dt.day)
print(dt.hour)
print(dt.minute)
print(dt.second)
print(dt.isoweekday())

在处理含有字符串日期的数据集或表格时,需要一种自动解析字符串的方法,无论它是什么格式的,都可以将其转化为 datetime 对象。这时,就要使用到 dateutil 中的 parser 模块。
parser.parse(timestr, parserinfo=None, **kwargs)
#如何在 python 中将字符串解析为 datetime对象
from dateutil import parser
s = '2020-08-08 2:2:2'
dt = parser.parse(s)
print(dt)
print(type(dt))

#如何将字符串日期解析为 datetime 对象
s1 = "2010 Jan 1"
s2 = '31-1-2000'
s3 = 'October10, 1996, 10:40pm'
s1 = parser.parse(s1)
s2 = parser.parse(s2)
s3 = parser.parse(s3)
print(s1,s2,s3,sep='\n')

【练习】计算以下列表中连续的天数。
输入:
[‘Oct, 2, 1869’, ‘Oct, 10, 1869’, ‘Oct, 15, 1869’, ‘Oct, 20, 1869’,‘Oct, 23, 1869’]
输出:
[8, 5, 5, 3]
import numpy as np
from dateutil import parser
date = ['Oct, 2, 1869', 'Oct, 10, 1869', 'Oct, 15, 1869', 'Oct, 20, 1869', 'Oct, 23, 1869']
date = [parser.parse(i) for i in date]
d = np.diff(date)
print(d)
l = [i.days for i in d]
print(l)

numpy diff函数
numpy.diff(a, n=1,axis=-1)沿着指定轴计算第N维的离散差值
- a:输入矩阵
- n:可选,代表要执行几次差值,默认1
- axis:默认值-1
date类
class date:
def __init__(self, year, month, day):
pass
def today(cls):
pass
date.today()获取当前日期信息
#如何在 Python 中获取当前日期和时间
import datetime
s = datetime.datetime.now()
print(s)
d = datetime.date.today()
print('日期:',d)

#如何统计两个日期之间有多少个星期六-直接相减
d1 = datetime.date(1869, 1, 2)
d2 = datetime.date(1869, 10, 2)
print(type(d1))
import datetime
d = (d2 - d1).days #datetime.date的days即int天数
print(d)
print(d//7 + 1)

time类
class time:
def __init__(self, hour, minute, second, microsecond, tzinfo):
pass
单位换算:
- 1秒 = 1000 毫秒(milliseconds)
- 1毫秒 = 1000 微妙(microseconds)
#如何使用datetime.time()类
import datetime
t = datetime.time(12, 9, 23, 10)
print(t)
print(type(t))

#如何将给定日期转换为当天开始的时间
import datetime
date = datetime.date(2019, 10, 2)
d = datetime.datetime(date.year,date.month,date.day)
print(d)
dt = datetime.datetime.combine(date,datetime.time.min)
print(dt)

注:
- datetime的datetime.combine是将年月日和时分秒合并在一起
import datetime
datetime.datetime.combine(datetime.date.today(), datetime.time.min)
timedelta类
timedelta 表示具体时间实例中的一段时间。你可以把它们简单想象成两个日期或时间之间的间隔。
它常常被用来从 datetime 对象中添加或移除一段特定的时间。
class timedelta(SupportsAbs[timedelta]):
def __init__(self, days, seconds, microseconds, milliseconds, minutes, hours, weeks,):
pass
def days(self):
pass
def total_seconds(self):
pass
#如何使用 datetime.timedelta() 类
import datetime
td = datetime.timedelta(days=30)
print(td)
print(type(td))
print(datetime.date.today())
print(datetime.date.today() + td)

dt1 = datetime.datetime(2020, 1, 31, 10, 10, 0)
dt2 = datetime.datetime(2019, 1, 31, 10, 10, 0)
td = dt1 - dt2
print(td)
print(type(td))

#不同的换算单位也可以直接相减
td1 = datetime.timedelta(days=30) # 30 days
td2 = datetime.timedelta(weeks=1) # 1 week
td = td1 - td2
print(td)
print(type(td))

练习题
- bday = 'Oct 2, 1969’是你的出生日期,
- 距离你出生那天过去多少天了?
- 距离你今年的下一个生日还有多少天?
- 将距离你今年的下一个生日的天数转换为秒数。
from dateutil import parser
import datetime
bDay = 'Oct 2, 1969'
dt1 = parser.parse(bDay).date()
dt2 = datetime.date.today()
dt3 = datetime.date(dt2.year, dt1.month, dt1.day)
print(dt1)
print(dt2)
print(dt3)
td = dt2 - dt1
print(td.days)
td = dt3 - dt2
print(td.days)
print(td.days * 24 * 60 * 60)
print(td.total_seconds())

参考文献:
https://blog.csdn.net/qq_37928340/article/details/89217148
https://blog.csdn.net/weixin_41931602/article/details/82794639
https://blog.csdn.net/hanshuobest/article/details/78558826
https://www.zhihu.com/question/267941361/answer/336845806
本文介绍了Python中的模块概念,包括命名空间、导入方式、包的创建和搜索路径等,并强调了避免使用`from...import *`的原因。接着详细讲解了datetime模块,涵盖了datetime类、date、time、timedelta的使用,以及如何处理日期和时间的计算问题。通过实例和练习题加深了理解。
883

被折叠的 条评论
为什么被折叠?



