首页 > 技术文章 > python基础——模块

maxgongzuo 2016-09-02 17:39 原文

模块就是其他语言的类库,分三种:内置模块、自定义模块、第三方模块

模块要先导入后使用

模块的作用:代码归类

 

导入模块:

import commons
commons.login()    #执行commons模块的login()方法

import commons as obj    #导入模块并设置别名
obj.login()

obj = _import_("commons")    #以字符串导入模块
obj.login()

obj = _import_("lib.commons", fromlist=True)    #默认只导入lib,加上fromlist=True参数则导入lib.commons

 

能被导入模块的位置:

import sys
print(sys.path)

 

把当前py文件的路径加入sys.path

#__file__    当前py文件所在路径
print(__file__)

import os
#os.path.abspath()   获取某个文件的绝对路径
#os.path.dirname()   某文件的上级目录
print(os.path.abspath(__file__))    #当前py文件的绝对路径
print(os.path.dirname(os.path.abspath(__file__)))   #当前py文件的上一级路径

import sys,os
sys.path.append(os.path.dirname(os.path.abspath(__file__))) #把当前py文件的上一级路径加入sys.path

 

在Linux或Windows中输入命令

import os
os.system("ps -ef")    #在linux中调用命令

res = os.system("ifconfig")    #命令结果赋值给变量
print(res)    #ifconfig执行成功,res=0

res = os.popen("ifconfig").read()    #把命令执行过程赋值给变量
print(res)

 

from调用模块

from sys import path    #直接调用模块内功能
print(path)    

from lib import commons    #文件夹下调用模块
commons.xx

#lib和src文件夹下都有commons模块
from lib import commons as lib_commons
from src import commons as src_commons
lib_commons.xx
src_commons.xx

 

第三方模块安装

requests模块

pip3安装
pip3 install requests
源码安装
python3 setup.py install

pip使用 http://www.ttlsa.com/python/how-to-install-and-use-pip-ttlsa/

 

模块中的特殊变量

#__file__    当前py所在路径

#__package__    当前py文件所在的包
print(__package__)
#__name__    只有执行当前文件时,当前文件的特殊变量__name__ == "__main__"

cat S1.py
def run1():
    print('run1')
def run2():
    print('run2')
if __name__ == "__main__":
    run1()
run2()


cat S2.py
import S1    #import S1的时候,S1的__name__不是"__main__",所用不会执行run1(),只执行run2()

 

 ==========================================================================================

sys模块

sys.argv           #命令行参数List,第一个元素是程序本身路径
sys.exit(n)        #退出程序,正常退出时exit(0)
sys.version        #获取Python解释程序的版本信息
sys.maxint         #最大的Int值
sys.path           #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       #返回操作系统平台名称

 

 os模块

os.getcwd()                 #获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")         #改变当前脚本工作目录;相当于shell下cd
os.curdir                   #返回当前目录: ('.')
os.pardir                   #获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2')    #可生成多层递归目录
os.removedirs('dirname1')   #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')         #生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')         #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')       #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()                 #删除一个文件
os.rename("oldname","new")  #重命名文件/目录
os.stat('path/filename')    #获取文件/目录信息
os.sep                      #操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep                  #当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep                  #用于分割文件路径的字符串
os.name                     #字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")   #运行shell命令,直接显示
os.environ                  #获取系统环境变量
os.path.abspath(path)       #返回path规范化的绝对路径
os.path.split(path)         #将path分割成目录和文件名二元组返回
os.path.dirname(path)       #返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)      #返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)        #如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)         #如果path是绝对路径,返回True
os.path.isfile(path)        #如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)         #如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)      #返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)      #返回path所指向的文件或者目录的最后修改时间

 

 

系统命令subprocess模块

#call    执行命令,返回状态码
ret = subprocess.call(["ls", "-l"], shell=False)
ret = subprocess.call("ls -l", shell=True)

#check_call    执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
subprocess.check_call(["ls", "-l"])
subprocess.check_call("exit 1", shell=True)

#check_output    执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
subprocess.check_output(["echo", "Hello World!"])
subprocess.check_output("exit 1", shell=True)
#subprocess.Popen(...)    用于执行复杂的系统命令
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True)
obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev')
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) #标准输入、标准输出、标准错误都是管道。换行符统一为\n obj.stdin.write("print('hello world')\n") obj.stdin.write("print(2)") obj.stdin.close() cmd_out = obj.stdout.read() obj.stdout.close() cmd_error = obj.stderr.read() obj.stderr.close() print(cmd_out) print(cmd_error)
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)")

out_error_list = obj.communicate()    #标准输出和标准错误都输入到列表
print(out_error_list)
import subprocess
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out_error_list = obj.communicate('print("hello")') print(out_error_list)

 

 

 正则表达式re模块

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次
'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
 
 
'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符结尾,同$
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
 
'(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
re.match(pattern, string, flags=0) 从头开始匹配
re.search(pattern, string, flags=0) 匹配包含
re.findall(pattern, string, flags=0) 获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元组
re.split(pattern, string, maxsplit=0, flags=0) 以匹配到的字符当做列表分隔符
re.sub(pattern, repl, string, count=0, flags=0)      替换匹配成功的指定位置字符串
 # pattern: 正则模型
 # string : 要匹配的字符串
 # repl   : 要替换的字符串或可执行对象
 # count  : 指定匹配个数
 # maxsplit:指定分割个数
 # falgs  : 匹配模式
     X  VERBOSE     Ignore whitespace and comments for nicer looking RE's.
     I  IGNORECASE  Perform case-insensitive matching.
     M  MULTILINE   "^" matches the beginning of lines (after a newline)
                    as well as the string.
                    "$" matches the end of lines (before a newline) as well
                    as the end of the string.
     S  DOTALL      "." matches any character at all, including the newline.
 
     A  ASCII       For string patterns, make \w, \W, \b, \B, \d, \D
                    match the corresponding ASCII character categories
                    (rather than the whole Unicode categories, which is the
                    default).
                    For bytes patterns, this flag is the only available
                    behaviour and needn't be specified.
      
     L  LOCALE      Make \w, \W, \b, \B, dependent on the current locale.
     U  UNICODE     For compatibility only. Ignored for string patterns (it
                    is the default), and forbidden for bytes patterns.

 

 

configparser

用于处理特定格式的文件,其本质上是利用open来操作文件。

# 特定格式如下
 
[section1] # 节点
k1 = v1    #
k2:v2       #
 
[section2] # 节点
k1 = v1    #
import configparser 
config = configparser.ConfigParser() #在内存中打开一个对象
config.read('tample.ini', encoding='utf-8') #读tample.ini文件
ret = config.sections() #获取所有节点
print(ret) 

ret = config.items('section1') #获取指定节点下所有的键值对
print(ret) 

ret = config.options('section1') #获取指定节点下所有的建
print(ret) 

v = config.get('section1', 'k1') #获取指定节点下指定key的值,默认str格式
# v = config.getint('section1', 'k1') #key值为int值
# v = config.getfloat('section1', 'k1') #key值为float值
# v = config.getboolean('section1', 'k1') #key值为布尔值
print(v)

has_sec = config.has_section('section1') #检查节点
print(has_sec) 
 
config.add_section("SEC_1") #添加节点
config.write(open('tample.ini', 'w')) #从内存写入文件

config.remove_section("SEC_1") #删除节点
config.write(open('tample.ini', 'w')) 

has_opt = config.has_option('section1', 'k1') #检查指定节点下的键值对
print(has_opt) 

config.remove_option('section1', 'k1') #删除键值对
config.write(open('tample.ini', 'w')) 

config.set('section1', 'k10', "123") #删除键值对
config.write(open('tample.ini', 'w'))

 

 

序列化相关

1.json  多语言通用,适用于跨语言的简单数据类型

import json
dic={"k1":"v1"}
print(dic,type(dic))
ret=json.dumps(dic) #将python的基本数据类型转换成字符串形式
print(ret,type(ret))

dic=json.loads(ret) #将字符串转换成基本数据类型,要使用双引号
print(dic,type(dic))

json.dump(dic,open("db","w")) #先序列化,然后写入文件
dic=json.load(open("db","r")) #读取文件然后反序列化
print(type(dic),dic)

2.pickle  python专用,适用于python所有数据类型(不同python版本件不一定通用)

import pickle
li=[11,22,33]
r=pickle.dumps(li)  #序列化成python的bytes形式
print(r)
ret=pickle.loads(r) #反序列化,支持包括复杂数据类型在内的任何数据类型
print(ret)

pickle.dump(li,open("db","wb")) #序列化然后写入文件
li=pickle.load(open("db","rb")) #读取文件然后反序列化
print(li,type(li))

 

XML模块 

import xml.etree.ElementTree as ET
from xml.etree import ElementTree as ET

 

时间模块

time  #常用取时间戳

import time

print(time.time())    #时间戳,从1970年开始到现在的时间(秒)
print(time.ctime()) #当前系统时间
print(time.ctime(time.time()-86400))    #一天前,将时间转换为字符串
print(time.gmtime())    #时间戳转换为strucktime格式,返回0时区时间,可加时间戳参数
#print(time.gmtime(1473042698.6790164))
print(time.localtime()) #时间戳转换为strucktime格式,返回当前时区时间,可加时间戳参数
x=time.localtime()
print(x.tm_year,x.tm_mon,x.tm_mday)
print(time.mktime(time.localtime()))    #与localtime相反,把stucktime转换为时间戳

print("-----")
time.sleep(2)   #停顿2秒
print("-----")

tm1=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
print(tm1) #将 strucktime格式化输出字符串
tm2=time.strptime("2016-09-05 11:12","%Y-%m-%d %H:%M")
print(tm2)  #将格式化字符串转换为stucktime格式

datetime  #常用取时间

import time
import datetime

print(datetime.date.today())    #当前日期
print(datetime.datetime.now())  #当前时间
print(datetime.datetime.now().replace(2014,9,12))   #替换时间
print(datetime.datetime.now().timetuple())  #返回strucktime格式

print(datetime.datetime.now()+datetime.timedelta(days=10))  #十天后
print(datetime.datetime.now()+datetime.timedelta(days=-10))  #十天前
#timedelta(days=, seconds=, microseconds=,milliseconds=, minutes=, hours=, weeks=)

 

格式化输出占位符
    %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.

 

random

#产生六位随机验证码
import random
l=[]
for i in range(6):
    r=random.randrange(1,3)  #50%几率
    if  r == 1:
        num=random.randrange(0,10)
        c=str(num)  #数字转字符串
        l.append(c)
    else:
        temp=random.randrange(65,91)    #产生65到90的随机数,65<=temp<91
        c=chr(temp)  #ascii数字转字母
        l.append(c)

result="".join(l)   #列表各元素合并
print(result)

 

logging模块

logging的日志可以分为5个级别。

LevelWhen it’s used
DEBUG Detailed information, typically of interest only when diagnosing problems.
INFO Confirmation that things are working as expected.
WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.
ERROR Due to a more serious problem, the software has not been able to perform some function.
CRITICAL

A serious error, indicating that the program itself may be unable to continue running.

import logging
logging.basicConfig(filename='test.log',level=logging.INFO,
                    format='%(asctime)s %(message)s',datefmt='%m/%d/%Y %I:%M:%S %p')
#打印到test.log文件里,日志级别为INFO,默认WARNING,format格式
logging.debug("DEBUG")
logging.info("INFO")
logging.warning("WARNING")
logging.error("ERROR")
logging.critical("CRITICAL")

日志format格式:

%(name)s

Logger的名字

%(levelno)s

数字形式的日志级别

%(levelname)s

文本形式的日志级别

%(pathname)s

调用日志输出函数的模块的完整路径名,可能没有

%(filename)s

调用日志输出函数的模块的文件名

%(module)s

调用日志输出函数的模块名

%(funcName)s

调用日志输出函数的函数名

%(lineno)d

调用日志输出函数的语句所在的代码行

%(created)f

当前时间,用UNIX标准的表示时间的浮 点数表示

%(relativeCreated)d

输出日志信息时的,自Logger创建以 来的毫秒数

%(asctime)s

字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

%(thread)d

线程ID。可能没有

%(threadName)s

线程名。可能没有

%(process)d

进程ID。可能没有

%(message)s

用户输出的消息

logging模块的类

logger提供了应用程序可以直接使用的接口;

handler将(logger创建的)日志记录发送到合适的目的输出;

filter提供了细度设备来决定输出哪条日志记录;

formatter决定日志记录的最终输出格式。

logger
每个程序在输出信息之前都要获得一个Logger,Logger通常对应了程序的模块名,
比如图形界面模块可以这样获得它的Logger:LOG=logging.getLogger("chat.gui")
而核心模块可以这样:LOG=logging.getLogger("chat.kernel")
Logger.setLevel(ERROR):指定最低的日志级别,低于ERROR的级别将被忽略。
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

handler
handler对象负责发送相关的信息到指定目的地。
可以通过addHandler()方法添加多个多handler,
Handler.setLevel(lel):指定被处理的信息级别,
Handler.setFormatter():给这个handler选择一个格式

1) logging.StreamHandler
使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。
它的构造函数是:StreamHandler([strm])
其中strm参数是一个文件对象。默认是sys.stderr

2) logging.FileHandler
和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。
它的构造函数是:FileHandler(filename[,mode])
filename是文件名,必须指定一个文件名。
mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。

3) logging.handlers.RotatingFileHandler
这个Handler类似于上面的FileHandler,但是它可以管理文件大小。
当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出。
比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把文件改名为chat.log.1。如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2最后重新创建 chat.log,继续输出日志信息。
它的构造函数是:RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。

4) logging.handlers.TimedRotatingFileHandler
这个Handler和RotatingFileHandler类似,间隔一定时间就自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,新的文件附加当前时间。
它的构造函数是:TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
filename与backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨

import logging
from logging import handlers
# 创建logger
logger = logging.getLogger('TEST-LOG')
logger.setLevel(logging.DEBUG)

# 创建StreamHandler,用于控制台输出
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 创建FileHandler,用于文件输出
fh = logging.FileHandler("access.log")
fh.setLevel(logging.WARNING)
# 创建TimedRotatingFileHandler,文件输出,按时间自动截取
th = handlers.TimedRotatingFileHandler(filename="log_file",when="S",interval=5,backupCount=3)

# 创建formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 把formatter格式加给handler
ch.setFormatter(formatter)
fh.setFormatter(formatter)
th.setFormatter(formatter)

# 把handler加给logger
logger.addHandler(ch)
logger.addHandler(fh)
logger.addHandler(th)

# 打日志
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

 

推荐阅读