Python的模块在其它语言中通常称为库或类库,也就是lib。它是编程语言的第三级封装,第四级则是包,也就是模块的打包组合,而前两级分别是函数和类。封装的好处,自然不用多言,高内聚,松耦合,减少代码重复。同时,模块也是“轮子”的代表,大多数是前人已经实现并测试好的高效代码组合,它的存在使得我们不必重复“造轮子”,可以使用拿来主义。但是,个人认为一个合格的程序员,虽然不会去重复造轮子,但必须要具备造轮子的能力,至少你要看得懂他人造的轮子。

python模块的种类  

  在python中,通常是这样的,许多个方法和属性组成了类,许多个类组成了.py文件,许多个.py文件组成了模块。模块一般分为三种:

  •   自定义模块
  •   内置模块
  •   第三方模块(开源模块)

  自定义模块:你自己写的.py文件,通过import关键字,在另外的.py中文件被调用,那么它就成为一个自定义模块。

  内置模块:python官方提供的一些常用的经典的模块,比如os、sys、time、logging等等,他们很成熟,效率很高,使用广泛。

  第三方模块:非python官方提供的模块,例如django、requests。python的流行和其具有较多第三方开源模块是分不开的,这是一个良性的生态圈。

Python模块的导入  

  在python中,模块的导入方式通常有一下四种:

import module
from module.xx.xx import xx
from module.xx.xx import xx as rename
from module.xx.xx import *

  导入一个模块,也就是导入一个.py文件,解释器将会解释该文件;而导入一个包,则会导入该包下的__init__.py文件,解释器将解释这个文件。这里就涉及到了一个包的概念,通常我们会将一些处理某一大类问题的模块放在同一个文件夹下,便于管理和使用,文件夹下可能还有子文件夹,那么如何让解释器搜素到正确的模块呢?python设计了__init__.py这么一个文件(这个文件可以是空的,只要文件名一模一样就可以),它告诉解释器,当前它所属的文件夹内的所有文件都是模块。

  以上四种方法各有各的适用场合:

  1. 对于内置模块,一般使用第一种就比较好了,例如import os,sys,datetime

  2.而对于需要经常调用某个模块内的某个类或函数时,使用第二种就比较合适,可以一定程度减少代码输入,例如:

  首先,我们建立了一个模块do_something如下:

def print_welcome():
    print("welcome to login!")

  然后,我在另一个文件里要大量调用该print_welcome函数。当使用import do_something时,我们是这样调用的:   

import do_something

do_something.print_welcome()
......
do_something.print_welcome()
......
do_something.print_welcome()

  而,如果使用from do_something import print_welcome的话,使用更加简洁方便,我们是这样调用的:

from do_something import print_welcome

print_welcome()
......
print_welcome()
......
print_welcome()

  3. 当导入的许多模块里有出现相同名称的类或者函数等情况时,from xxx import xxx as xxx这种导入方式就比较好用了,它实际上是给模块取个别名。例如:

  在模块module_1中:

def func():

    print("this is module_1 !")

  在模块module_2中:

def func():

    print("this is module_2 !")

  在别的文件中,我们可以这样调用,就不会引起冲突了:

from module_1 import func as a
from module_2 import func as b

a()
b()

  4. 至于from xxx import *的方法,我们不太提倡。

Python模块的路径

  python的模块作为一个独立的文件,在文件系统中必然有其保存路径。我们在导入模块时,解释器不可能针对整个文件系统进行搜索,它必然是维护了一个指定的搜索路径集合,我们只有将python的模块存放在这些路径中才可以被顺利导入。那么,这个路径集合存放在哪里呢?在sys这个模块的path里,可以通过下面的方式查看:

import sys

for i in sys.path:
    print(i)

结果:

F:\Python\pycharm\s13
C:\Python35\python35.zip
C:\Python35\DLLs
C:\Python35\lib
C:\Python35
C:\Python35\lib\site-packages

  它的顺序是这样的,先是当前文件的存储目录,然后是python的安装目录,再是python目录里的site-packages,其实说白了就是”自定义”——“官方”——“第三方”目录。同时,由于存在多个目录,因此在自定义模块的时候,对模块的命名一定要注意,不要和官方标准模块和一些比较有名的第三方模块重名,一有不慎,就容易出现模块导入错误的情况发生。(注:site-packages在不同的操作系统里可能名称不一样)

  如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。例如:

import sys
import os

new_path = os.path.abspath('../')
sys.path.append(new_path)

内置模块

一、序列化json和pickle

  json和pickle模块主要用于对python的数据进行序列化,保存为字符串的格式。两者的的使用方法和几乎一模一样,都是主要使用下面四个方法:

  dump()  dumps()  load()  loads()

  json更加可以跨语言,跨平台,但只能对python的基本类型做操作,对python的类就无能为力。另外, json 的数据要求用双引号将字符串引起来,并且不能有多余的逗号。这是因为在别的语言中,双引号引起来的才是字符串,单引号引起来的是字符;python程序员习惯性的在列表、元组或字典的最后一个元素的后面加个逗号,这在json中是不允许的,需要特别注意。
  pickle虽然只能在python程序之间使用,但它能针对所有类型进行操作,包括类。因此它比较适合python本身复杂数据的存贮。注意:python的不同版本之间可能会有兼容性问题。
   下面是json的使用范例:
import json

s = '{"k1":"v1","k2":123}'      # 类似字典结构的字符串必须以单引号引起来,而大括号里的则需使用双引号
dic = json.loads(s)                   # loads方法是将json格式字符串转换成python的数据结构
print(dic)
print(type(dic))

 运行结果:
{'k1': 'v1', 'k2': 123}
<class 'dict'>
import json

dic = {"k1":"v1","k2":123}
s = json.dumps(dic)
print(s)
print(type(s))

运行结果:
{"k1": "v1", "k2": 123}
<class 'str'>

  与loads和dumps不同的是load和dump方法是将json格式的字符串在文件内进行读写

import json

dic = {"k1":"v1","k2":123}
s = json.dump(dic,open('file','w'))

运行结果:

在同级目录下生成file文件,并保存了{"k1":"v1","k2":123}字符串
import json

s = json.load(open('file'))
print(s)
print(type(s))

运行结果:
{'k1': 'v1', 'k2': 123}
<class 'dict'>

  pickle与json基本一样,但是不同的是,它的序列化字符串是不可认读的,不如json的来得直观。但是,pickle这里有个坑,在使用dump和load读写文件时,要使用rb或wb模式,也就是只接收bytes类型的数据,否则会报错。

import pickle

dic = {"k1":"v1","k2":123}
s = pickle.dumps(dic)
print(s)
print(type(s))

运行结果:

b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03K{u.'
<class 'bytes'>

二、time及datetime 

  时间模块是每个程序员必然会用到的。在python中,time和datetime模块为我们提供了大量的时间处理方法。其中的,time.time(),time.sleep(),time.localtime()非常常用。  

  time提供的功能更加接近于操作系统层面的,大多数函数是调用了所在平台C library的同名函数,并且围绕着 Unix Timestamp 进行,其所能表述的日期范围被限定在 1970 - 2038 之间,如果需要处理范围之外的日期,使用datetime模块会更好。

  time模块主要包括三种类型时间:struct_time,timestamp和string_time。理解了这三种类型的话,对于time模块里各种方法就会有融汇贯通的感觉。  

  • 时间戳(timestamp)               1970年1月1日之后的秒       即:time.time()
  • 格式化的字符串(string_time)      2016-06-11 12:0,             即:time.strftime('%Y-%m-%d')
  • 结构化时间(struct_time)           包含了:年、日、星期等...       即:time.localtime()

  三者之间的关系如下图:

下面是time模块的常用方法介绍:

import time
# time.sleep(1)       #让程序睡眠指定秒数,可以是浮点数
print(time.time())  #返回当前系统时间戳
print(time.ctime()) #输出当前系统时间的字符串格式,它可以接受时间戳格式的参数
print(time.ctime(time.time()-86640)) #将时间戳转为字符串格式
print(time.asctime(time.localtime()))#将格式化时间转为字符串格式
print(time.gmtime(time.time()-86640)) #将时间戳转换成struct_time格式,返回的是gmt时间,与北京时间差8小时
print(time.localtime(time.time()-86640)) #将时间戳转换成struct_time格式,返回的是本地时间
print(time.mktime(time.localtime()))    #与time.localtime()功能相反,将struct_time格式转回成时间戳格式
print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将struct_time格式转成指定的字符串格式
print(time.strptime("2016-01-28","%Y-%m-%d") )  #将字符串格式转换成struct_time格式

运行结果:

1465194377.782088
Mon Jun  6 14:26:17 2016
Sun Jun  5 14:22:17 2016
Mon Jun  6 14:26:17 2016
time.struct_time(tm_year=2016, tm_mon=6, tm_mday=5, tm_hour=6, tm_min=22, tm_sec=17, tm_wday=6, tm_yday=157, tm_isdst=0)
time.struct_time(tm_year=2016, tm_mon=6, tm_mday=5, tm_hour=14, tm_min=22, tm_sec=17, tm_wday=6, tm_yday=157, tm_isdst=0)
1465194377.0
2016-06-06 06:26:17
time.struct_time(tm_year=2016, tm_mon=1, tm_mday=28, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=28, tm_isdst=-1)

对于时间戳,通常用于算时间的差值,典型的用法是测试程序运行时间,例如:

import time

def func():
    pass

t1 = time.time()
func()
t2 = time.time()
result = float(t2) - float(t1)
print(result)

对于格式化字符串:"%Y-%m-%d %H:%M:%S",其中每一个字母所代表的意思可以查看官方文档,这里不一一列举。  

而对于一个结构化的时间对象,它的各项属性意义如下:

属性 意义
tm_year
tm_mon
tm_mday
tm_hour 小时
tm_min 分钟
tm_sec
tm_wday 星期几,以0开始
tm_yday 当日在当年的天数
tm_isdst 是否夏令时,默认-1,表示自动判断

 

 

    %Y  Year with century as a decimal number.
    %m  Month as a decimal number [01,12].
    %d  Day of the month as a decimal number [01,31].
    %H  Hour (24-hour clock) as a decimal number [00,23].
    %M  Minute as a decimal number [00,59].
    %S  Second as a decimal number [00,61].
    %z  Time zone offset from UTC.
    %a  Locale's abbreviated weekday name.
    %A  Locale's full weekday name.
    %b  Locale's abbreviated month name.
    %B  Locale's full month name.
    %c  Locale's appropriate date and time representation.
    %I  Hour (12-hour clock) as a decimal number [01,12].
    %p  Locale's equivalent of either AM or PM.

  

 

可以通过对象调用其各项属性,例如:

import time
s = time.localtime()
print("tm_year:  ",s.tm_year)

运行结果:

tm_year:   2016

datetime
datetime 可以理解为基于 time 进行的封装,它提供了更多实用的函数。在datetime 模块中包含了几个类,具体如下:

  • timedelta    # 主要用于计算时间跨度
  • tzinfo             # 时区相关
  • time              # 只关注时间
  • date              # 只关注日期
  • datetime       #  同时有时间和日期

  在实际实用中,用得比较多的是 datetime.datetime 和 datetime.timedelta。使用datetime.datetime.now()方法可以获得当前时刻的一个datetime.datetime 类的实例,该实例主要有以下属性及常用方法:

  • datetime.year
  • datetime.month
  • datetime.day
  • datetime.hour
  • datetime.minute
  • datetime.second
  • datetime.microsecond
  • datetime.tzinfo
import datetime

ti = datetime.datetime.now()
print(ti)
print(type(ti))
print(ti.year)
print(ti.month)
print(ti.day)

运行结果:

2016-06-06 14:36:00.763951
<class 'datetime.datetime'>
2016
6
6
0

  除了实例化对象后,datetime模块本身还提供了很多有用的方法,例如:

import time,datetime

print(datetime.date.today())    #输出格式 2016-06-06
print(datetime.date.fromtimestamp(time.time()-864400) )   #将时间戳转成日期格式
current_time = datetime.datetime.now()    #实例化当前时间
print(current_time)      #输出2016-01-26 19:04:30.335935
print(current_time.timetuple())    #返回struct_time格式

#datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])
print(current_time.replace(2016,7,7)) #输出2016-07-07 14:06:24.074900,返回当前时间,但指定的值将被替换

str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") #将字符串转换成日期格式
new_date = datetime.datetime.now() + datetime.timedelta(days=10) #比现在加10天
new_date = datetime.datetime.now() + datetime.timedelta(days=-10) #比现在减10天
new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) #比现在减10小时
new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) #比现在+120s
print(new_date)

运行结果:

2016-06-06
2016-05-27
2016-06-06 14:42:21.503262
time.struct_time(tm_year=2016, tm_mon=6, tm_mday=6, tm_hour=14, tm_min=42, tm_sec=21, tm_wday=0, tm_yday=158, tm_isdst=-1)
2016-07-07 14:42:21.503262
2016-06-06 14:44:21.523263

  其实,两个 datetime 对象直接相减就能获得一个 timedelta 对象。另外推荐,如果有需要计算工作日的需求,可以使用 business_calendar这个模块。

三、logging日志模块

  日志是每个程序都应该具备的一项功能,它能帮你调试代码、查找问题、警告通知等等。Python内置了一个名叫logging的日志模块,提供了标准的日志接口,可以通过它存储各种格式的日志,logging的日志可以分为 debuginfowarningerror and critical五个级别。在logging内部,每个级别由一个数字表示如下:

  CRITICAL = 50

  ERROR = 40
  WARNING = 30
  INFO = 20
  DEBUG = 10
  如果只是简单的将日志输入到屏幕,可以这么做:
import logging

logging.warning("user [jack] attempted wrong password more than 3 times")
logging.critical("server is down")

#输出
WARNING:root:user [jack] attempted wrong password more than 3 times
CRITICAL:root:server is down

  如果要将日志写入某个文件,那么可以这么做:

import logging

logging.basicConfig(filename='log.log', #这一行指定日志文件
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',## 这一行控制每条日志的格式
                    datefmt='%Y-%m-%d %H:%M:%S %p',  # 这一行控制时间格式
                    level=10)  # 系统只会将高于level的信息写入文件

logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')

对于basicConfig,有如下参数:

filename     #指定日志文件名
filemode     #和file函数意义相同,指定日志文件的打开模式,'w'或'a'
format       #指定输出的格式和内容,format可以输出很多有用信息,如上例所示:
      %(levelno)s      #打印日志级别的数值
      %(levelname)s    #打印日志级别名称
      %(pathname)s     #打印当前执行程序的路径,其实就是sys.argv[0]
      %(filename)s     #打印当前执行程序名
      %(funcName)s     #打印日志的当前函数
      %(lineno)d       #打印错误日志的行号
      %(asctime)s      #打印日志的时间
      %(thread)d       #打印线程ID
      %(threadName)s   #打印线程名称
      %(process)d      #打印进程ID
      %(message)s      #打印日志信息
datefmt   #指定时间格式,默认为logging.strftime()
          #用法:datefmt = '%a,%d %b %Y  %H:%M:S'
level     #设置日志级别,默认为logging.WARNING
stream    #指定将日志的输出流,可以指定输出到sys.stderr、sys.stdout或者文件,默认输出到sts.stderr

  

对于输出的格式,如上面例子中的asctime/name/levelname等,还有其它属性如下图:

图中红色字体部分是比较有用的属性,可以看出logging模块还是相当强大的,甚至能记录调用日志的

进程ID或者进程名,线程ID或者线程名。


而如果想要同时把日志打印在屏幕和保存在文件日志里,则必须对logging模块有更深的了解。

首先,我们需要了解logging模块的四个部分:loggers, handlers, filters, formatters。

loggers:提供让程序代码直接使用的接口

handlers:将logger产生的日志发送到希望的目的地

filter:用于过滤日志,将符合条件的日志输出

formatters:在输出前格式化日志,使之符合你想要的格式。

下面我们根据一个具体的例子来看:

import logging

# 创建logger
logger = logging.getLogger('jack') # 使用getLogger方法,并指定用户名
logger.setLevel(logging.DEBUG)  # 设置全局的日志记录等级为DEBUG

# 创建要发送到屏幕的handler,并设置其局部日志等级为DEBUG
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# 创建要发送到日志文件的handler,并设置其局部日志等级为WARNING
fh = logging.FileHandler("access.log") # 设置日志文件名为access.log
fh.setLevel(logging.WARNING)

# 创建一种formatter格式,你可以根据需要创建任意种
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 为先前创建好的Handlers添加formatter格式
ch.setFormatter(formatter)
fh.setFormatter(formatter)

# 为一开始创建的logger添加Handlers,也就是处理逻辑,有几个Handlers就添加几次
logger.addHandler(ch)
logger.addHandler(fh)

# 下面是应用程序的代码
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

屏幕显示:

2016-06-06 16:53:37,554 - jack - DEBUG - debug message
2016-06-06 16:53:37,555 - jack - INFO - info message
2016-06-06 16:53:37,555 - jack - WARNING - warn message
2016-06-06 16:53:37,555 - jack - ERROR - error message
2016-06-06 16:53:37,555 - jack - CRITICAL - critical message

access.log日志文件中的内容:

2016-06-06 16:53:37,555 - jack - WARNING - warn message
2016-06-06 16:53:37,555 - jack - ERROR - error message
2016-06-06 16:53:37,555 - jack - CRITICAL - critical message

  

  其实就是上面这么个过程,一步一步完成就可以了,逻辑其实很简单,学习模块其实就是学习一个软件,没什么复杂的。

未完待续  

  

python内置模块(1)的更多相关文章

  1. python内置模块(4)

    这一部分是python内置模块系列的最后一部分,介绍了一些小巧有用的内置模块. 目录: 1.random 2.shelve 3.getpass 4.zipfile 5.tarfile 6.bisect ...

  2. Python学习笔记【第八篇】:Python内置模块

    什么时模块 Python中的模块其实就是XXX.py 文件 模块分类 Python内置模块(标准库) 自定义模块 第三方模块 使用方法 import 模块名 form 模块名 import 方法名 说 ...

  3. Python内置模块与标准库

    Python内置模块就是标准库(模块)吗?或者说Python的自带string模块是内置模块吗? 答案是:string不是内置模块,它是标准库.也就是说Python内置模块和标准库并不是同一种东西. ...

  4. python内置模块[re]

    python内置模块[re] re模块: python的re模块(Regular Expression正则表达式)提供各种正则表达式的匹配操作,在文本解析.复杂字符串分析和信息提取时是一个非常有用的工 ...

  5. python内置模块[sys,os,os.path,stat]

    python内置模块[sys,os,os.path,stat] 内置模块是python自带功能,在使用内置模块时,需要遵循 先导入在 使用 一.sys 对象 描述 sys.argv 命令行参数获取,返 ...

  6. Python内置模块和第三方模块

    1.Python内置模块和第三方模块 内置模块: Python中,安装好了Python后,本身就带有的库,就叫做Python的内置的库. 内置模块,也被称为Python的标准库. Python 2.x ...

  7. python内置模块collections介绍

    目录 python内置模块collections介绍 1.namedtuple 2.deque 3.defaultdict 4.OrderedDict 5.ChainMap 6.Counter 7.小 ...

  8. python内置模块介绍(一)

     本文主要介绍模块列表如下: os sys re time datetime random shutil subprocess os模块 os.getcwd()                    ...

  9. python内置模块(time模块)

    常用的python内置模块 一.time模块 在python的三种时间表现形式: 1.时间戳,给电脑看的. - 自1970-01-01 00:00:00到当前时间,按秒计算,计算了多少秒. impor ...

  10. python 内置模块续(二)

    目录 python 内置模块补充 1.hashlib模块 简易使用: 高级使用: 进阶使用: 加盐处理: 校验文件一致性 2.logging日志模块 日志等级 常用处理 "四大天王" ...

随机推荐

  1. Android版-支付宝APP支付

    此项目已开源 赶快来围观 Start支持下吧 [客户端开源地址-JPay][服务端端开源地址-在com.javen.alipay 包名下] 上一篇详细介绍了微信APP支付 点击这里 此篇文章来详细介绍 ...

  2. scikit-learn主要模块和基本使用方法

    从网上看到一篇总结的很不错的sklearn使用文档,备份勿忘. 引言 对于一些开始搞机器学习算法有害怕下手的小朋友,该如何快速入门,这让人挺挣扎的.在从事数据科学的人中,最常用的工具就是R和Pytho ...

  3. Codeforces Round #384 (Div. 2) E. Vladik and cards 状压dp

    E. Vladik and cards 题目链接 http://codeforces.com/contest/743/problem/E 题面 Vladik was bored on his way ...

  4. 判断big endian和little endian的方法

    http://blog.sina.com.cn/s/blog_6ab0b9a80101awzr.html   不同体系的CPU在内存中的数据存储往往存在着差异.例如,Intel的x86系列处理器将低序 ...

  5. 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包。

    最近在升级 Visual Studio 2015 Update 3 的过程中,等了很长时间都没一点进展,于是就强行终止了升级程序,但VS也因此出了问题. 后来经过修复,不行,卸载再重装,仍然提示这个错 ...

  6. 理解vmp

    原文作者: 海风月影_百度空间 vmp里面只有1个逻辑运算指令 not_not_and 设这条指令为PP(a,b) = ~a & ~b 这条指令的神奇之处就是能模拟 not and or xo ...

  7. 记录一个__lll_lock_wait_private错误

    一个DBA同事昨天在执行一个命令行工具的时候发现程序hang住,问题挺有意思,值得记录下. 首先用pstack看了下程序的调用栈,这是个多线程程序,pstack结果看到几乎所有的线程都等在write调 ...

  8. 牢骚与javascript中的this

    最近在看关于拖延症的一本书<拖拉一点也无妨>,后面得出结论是自己写博客大部分处于两种状态,心情很好和心情很不好的时候.因为正常状态下感觉写博客吧,是件很麻烦的事情,不如去看看电影看看漫画啥 ...

  9. linux下 C++ 读取mat文件 MATLAB extern cyphon scipy 未完待续

    1.使用Matlab的C扩展,需要用户安装matlab. g++ -L/media/exsoftware/MATLAB/R2013b/bin/glnxa64 -Wl,-rpath,/media/exs ...

  10. iOS 企业证书发布app 流程

    企业发布app的 过程比app store 发布的简单多了,没那么多的要求,哈 但是整个工程的要求还是一样,比如各种像素的icon啊 命名规范啊等等. 下面是具体的流程 1.修改你的 bundle i ...