Python之旅——task8

模块与datetime模块

1 模块

模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 Python 标准库的方法。

1.1 什么是模块

容器 -> 数据的封装
函数 -> 语句的封装
类 -> 方法和属性的封装
模块 -> 程序文件

1.2 命名空间

命名空间因为对象的不同,也有所区别,可以分为如下几种:

内置命名空间(Built-in Namespaces):Python运行起来,它们就存在了。内置函数的命名空间都属于内置命名空间,所以,我们可以在任何程序中直接运行它们。
全局命名空间(Module:Global Namespaces):每个模块创建它自己所拥有的全局命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间,也会因为模块的不同而不相互干扰。
本地命名空间(Function & Class:Local Namespaces):模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间。如果函数返回了结果或者抛出异常,则本地命名空间也结束了。

以上三者的关系为内置命名空间包含全局命名空间,全局命名空间又包含本地命名空间。

1.3 导入模块

  1. import 模块名
import  time
  1. from 模块名 import 函数名
from random import randint
  1. import 模块名 as 新名字
import  time  as  t

1.4 if _name_ == ‘_main_’

对于很多编程语言来说,程序都必须要有一个入口,而 Python 则不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
_name_:是内置变量,可用于表示当前模块的名字。

import const

print(__name__)
# __main__

print(const.__name__)
# const

由此我们可知:如果一个 .py 文件(模块)被直接运行时,其__name__值为__main__,即模块名为__main__。

所以,if _name_ == '_main_'的意思是:当 .py 文件被直接运行时,if _name_ == '_main_'之下的代码块将被运行;当 .py 文件以模块形式被导入时,if _name_ == '_main_'之下的代码块不被运行。

1.5 搜索路径

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量中。

1.6 包

包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

创建包分为三个步骤:

  1. 创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字
  2. 在文件夹中创建一个_init_.py 的模块文件,内容可以为空。
  3. 将相关的模块放入文件夹中。

例子:一套统一处理声音文件和数据的模块
针对不同类型的音频数据,有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果)。

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 就可以了。

  1. import直接导入子模块
import sound.effects.echo
#导入子模块:sound.effects.echo
# 使用时;

```python
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
2. from...import...导入

```python
from sound.effects import echo
# 导入echo,可以省去较长的前缀
echo.echofilter(input, output, delay=0.7, atten=4)
  1. 直接导入其中的一个函数
from sound.effects.echo import echofilter
# 导入子模块: echo,并且可以直接使用他的 echofilter() 函数:
echofilter(input, output, delay=0.7, atten=4)

注意当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。

# 导入全部的子模块
from sound.effects import *

导入语句遵循如下规则:如果包定义文件 _init_.py 存在一个叫做_all_ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。
通常我们并不主张使用 * 这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。

练习题

  1. 怎么查出通过 from xx import xx导⼊的可以直接调⽤的⽅法?

可以使用help()函数来查看

  1. 了解Collection模块,编写程序以查询给定列表中常见的元素。

题目说明: 输入:language = [‘PHP’, ‘PHP’, ‘Python’, ‘PHP’, ‘Python’, ‘JS’, ‘Python’, ‘Python’,‘PHP’, ‘Python’]
输出:Python

Collection模块:

collections模块在内置的数据类型,比如:int、str、list、dict等基础之上额外提供了几种数据类型。

1.namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典

from collections import Counter

language = ['PHP', 'PHP', 'Python', 'PHP', 'Python', 'JS', 'Python', 'Python','PHP', 'Python']

count_most = Counter(language)
print(max(count_most.keys()))

#Python

2 datetime模块

datetime 是 Python 中处理日期的标准模块,它提供了 4 种对日期和时间进行处理的类:datetime、date、timetimedelta。

2.1 datatime类

class datetime(date):
    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.now(tz=None) 获取当前的日期时间,输出顺序为:年、月、日、时、分、秒、微秒
datetime.timestamp() 获取以 1970年1月1日为起点记录的秒数
datetime.fromtimestamp(tz=None) 使用 unixtimestamp 创建一个 datetime。

import datetime

time_now = datetime.datetime.now()
print(time_now)
# 2020-08-06 15:09:02.034480

datetime.strftime(fmt) 格式化 datetime 对象。

import datetime
change = datetime.datetime(year=2020, month=8, day=6, hour=15, minute=18, second=00)
s = change.strftime("'%Y/%m/%d %H:%M:%S")
print(s)  # 2020/08/06 15:18:00
import datetime
change = datetime.date(2020, 8,6)
print(change.strftime('%b-%d,%Y')) #Aug-06,2020

datetime.date() 返回日期部分
datetime.time() 返回时间部分
datetime.year 年
datetime.month 月
datetime.day 日
datetime.hour 小时
datetime.minute 分钟
datetime.second 秒
datetime.isoweekday 星期几

在处理含有字符串日期的数据集或表格时,我们需要一种自动解析字符串的方法,无论它是什么格式的,都可以将其转化为 datetime 对象。这时,就要使用到 dateutil 中的 parser 模块。

parser.parse(timestr, parserinfo=None, **kwargs)
from dateutil import parser

s = '2020-08-06'
dt = parser.parse(s)
print(dt)  # 2020-08-06 00:00:00
s_2 = 'August 06, 2020, 03:28pm'
dt_2 = parser.parse(s_2)
print(dt_2)  # 2020-08-06 15:28:00

2.2 data类

class date:
    def __init__(self, year, month, day):
        pass
    def today(cls):
        pass

date.today() 获取当前日期信息。

例子:如何统计两个日期之间有多少个星期六?

import datetime
d1 = datetime.date(2020, 3, 25)
d2 = datetime.date(2020, 8, 6)
dt = (d2 - d1).days
print(dt) #134
print(d1.isoweekday())  # 3
print(dt // 7 + 1)  # 20

2.3 time类

class time:
    def __init__(self, hour, minute, second, microsecond, tzinfo):
        pass

使用:

import datetime
tim = datetime.time(15, 36, 00, 36000)
print(tim) #15:36:00.036000

2.4 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
import datetime

td = datetime.timedelta(days=20)
print(td)  # 20 days, 0:00:00
print(datetime.date.today())  # 2020-08-06
print(datetime.date.today() + td)  # 2020-08-26

dt1 = datetime.datetime(2020, 8, 6, 15, 40, 0)
dt2 = datetime.datetime(2019, 8, 6, 15, 40, 0)
td = dt1 - dt2
print(td)  # 366 days, 0:00:00

td1 = datetime.timedelta(days=30)  
td2 = datetime.timedelta(weeks=1)  
td = td1 - td2
print(td)  # 23 days, 0:00:00

如果将两个 datetime 对象相减,就会得到表示该时间间隔的 timedelta 对象。 同样地,将两个时间间隔相减,可以得到另一个
timedelta 对象。

练习题

  1. 假设你获取了用户输入的日期和时间如 2020-1-21 9:01:30 ,以及一个时区信息如 UTC+5:00 ,均是 str ,请 编写一个函数将其转换为timestamp。
import datetime
from dateutil import parser
def to_timestamp(dt_str, tz_str):
    dt = parser.parse(dt_str + tz_str)
    print(dt.timestamp())
dt='2020-6-1 08:10:30'
tz='+7:00'
dt1='2020-5-31 16:10:30'
tz1='-09:00'
to_timestamp(dt,tz)
to_timestamp(dt1,tz1)
#1590973830.0
#1590973830.0
  1. 编写Python程序以选择指定年份的所有星期日。
import datetime
def all_sundays(year):
    flag = 1
    day_1 = datetime.datetime(year=year, month=1, day=1)
    day_2 = datetime.datetime(year=year, month=12, day=31)
    n_day = (day_2 - day_1).days
    td = datetime.timedelta(days=1)
    for i in range(n_day+1):
        if day_1.isoweekday() == 7:
            d = datetime.date(day_1.year, day_1.month, day_1.day)
            print(d)
        day_1 += td
all_sundays(2020)
'''
2020-01-05
2020-01-12
2020-01-19
2020-01-26
2020-02-02
2020-02-09
2020-02-16
2020-02-23
2020-03-01
2020-03-08
2020-03-15
2020-03-22
2020-03-29
2020-04-05
2020-04-12
2020-04-19
2020-04-26
2020-05-03
2020-05-10
2020-05-17
2020-05-24
2020-05-31
2020-06-07
2020-06-14
2020-06-21
2020-06-28
2020-07-05
2020-07-12
2020-07-19
2020-07-26
2020-08-02
2020-08-09
2020-08-16
2020-08-23
2020-08-30
2020-09-06
2020-09-13
2020-09-20
2020-09-27
2020-10-04
2020-10-11
2020-10-18
2020-10-25
2020-11-01
2020-11-08
2020-11-15
2020-11-22
2020-11-29
2020-12-06
2020-12-13
2020-12-20
2020-12-27
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值