python3.x 基础五:模块

1.定义

模块:本质是.py结尾的python文件,从逻辑上组织python代码,可以是变量,函数,类,逻辑,目的是实现一个功能,test.py 对应模块名:test

包:从逻辑上组织模块的,本质就是一个目录,必须带有__init__.py文件,导入模块指的是导入这个init文件

2.导入方法

import module_name,module_name2

相当于将所有代码赋值给一个变量,调用的时候需要使用前缀module_name.xxx指定

from module_name import * 

把所有内容导入本地运行,使用的时候可以直接使用变量名、函数名,不需要前缀

from module_name import func as alise

将部分内容导入本地运行,同时使用别名避免冲突,比如某一个函数、变量

 3.import的本质(路径搜索 搜索路径)

  • 把python文件解释一遍
  • 把所有代码赋值给一个变量,
  • 导入包的本质就是解释这个包下面的__init.py__文件
  • import module_name -->module_name.py -->module_name.py的路径-->sys.path

4.导入优化

from module import func / as alise

将重复调用的模块导入到本地,避免重新查找

5.模块分类

a:标准库

b:开源模块

c:自定义模块

 

标准常用库模块:

模块time

协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC

Epoch指的是一个特定的时间:1970-01-01 00:00:00 UTC

DST,夏令时,1表示是夏令时,0表示不是夏令时

表示方法有3种:

1.时间戳,以秒表示,从1970.1.1 00:00:00开始计秒

2.格式化时间字符串,以各种%格式年月日时分秒表现,也就是平时我们看到的YYYY-mm-DD HH:MM:SS格式

3.元组时间,将9个元素分别赋予固定变量表现,time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=9, tm_min=9, tm_sec=5, tm_wday=1, tm_yday=339, tm_isdst=0)

  • 时间变量
   timezone -- difference in seconds between UTC and local standard time
    altzone -- difference in  seconds between UTC and local DST time
    daylight -- whether local time should reflect DST
    tzname -- tuple of (standard time zone name, DST time zone name)
>>> time.timezone
-28800
与UTC标准时间相差秒数,早了8个小时 >>> time.altzone -28800
与夏令时相差秒数,没有使用夏令时相差8个小时 >>> time.daylight 0
没有使用夏令时
>>> time.tzname ('CST', 'CST')
标准时区,夏令时区
>>>
  •  时间方法:
   time() -- return current time in seconds since the Epoch as a float
    clock() -- return CPU time since process start as a float
    sleep() -- delay for a number of seconds given as a float
    gmtime() -- convert seconds since Epoch to UTC tuple
    localtime() -- convert seconds since Epoch to local time tuple
    asctime() -- convert time tuple to string
    ctime() -- convert time in seconds to string
    mktime() -- convert local time tuple to seconds since Epoch
    strftime() -- convert time tuple to string according to format specification
    strptime() -- parse string to time tuple according to format specification
    tzset() -- change the local timezone
>>> time.time()
1512436325.3465307
返回距离1970.1.1零秒的浮点型秒数
>>> time.clock()
0.025913
返回自CPU启动的浮点型时间
>>> time.sleep(1)
休眠1秒
>>> time.gmtime(time.time())
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=1, tm_min=13, tm_sec=11, tm_wday=1, tm_yday=339, tm_isdst=0)
将时间戳转换成UTC元组,我们是UTC+8,比UTC快8个小时
>>> time.localtime()
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=9, tm_min=14, tm_sec=23, tm_wday=1, tm_yday=339, tm_isdst=0)
将本地时间戳转换成本地元组时间
>>> time.asctime(time.localtime())
'Tue Dec  5 09:14:13 2017'
将元组时间转换成字符串时间
>>> time.ctime()
'Tue Dec  5 09:14:59 2017'
将时间戳转换成字符串时间
>>> time.mktime(time.localtime())
1512436704.0
将本地元组时间转换成UTC时间戳
>>> time.strftime('%Y-%m-%d',time.localtime())
'2017-12-05'
格式化时间,先格式,后时间,格式-元组,格式先后顺序无关
>>> time.strptime('2017-12-05','%Y-%d-%m')
time.struct_time(tm_year=2017, tm_mon=5, tm_mday=12, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=132, tm_isdst=-1)
时间解析,先时间,后解析,时间-元组,格式先后顺序有关,格式化格式对应字符串格式
  • 分类:

时间戳方法:time,clock,mktime

元组方法:gmtime,localtime,strptime

字符串方法:asctime,ctime,strftime

  • 时间元组含义
      year (including century, e.g. 1998)
      month (1-12)
      day (1-31)
      hours (0-23)
      minutes (0-59)
      seconds (0-59)
      weekday (0-6, Monday is 0)
      Julian day (day in the year, 1-366)
      DST (Daylight Savings Time) flag (-1, 0 or 1)
    If the DST flag is 0, the time is given in the regular time zone;
    if it is 1, the time is given in the DST time zone;
    if it is -1, mktime() should guess based on the date and time.
  •  时间转换

1.字符串->元组

>>> string_to_struct = time.strptime("2017/12/05","%Y/%m/%d")
>>> string_to_struct1 = time.strptime("2017/12/05 10:10:10","%Y/%m/%d %H:%M:%S")
>>> string_to_struct
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=339, tm_isdst=-1)
>>> string_to_struct1
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=10, tm_min=10, tm_sec=10, tm_wday=1, tm_yday=339, tm_isdst=-1)

2.元组->时间戳

>>> string_to_struct
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=339, tm_isdst=-1)
>>> time.mktime(string_to_struct)
1512403200.0
>>> time.mktime(string_to_struct1)
1512439810.0

3.时间戳->元组

time.gmtime(time.time() )
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=2, tm_min=24, tm_sec=22, tm_wday=1, tm_yday=339, tm_isdst=0)
>>> time.gmtime(time.time()-24*60*60)
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=4, tm_hour=2, tm_min=25, tm_sec=55, tm_wday=0, tm_yday=338, tm_isdst=0)

4.元组->字符串:格式化元组

>>> time.gmtime()
time.struct_time(tm_year=2017, tm_mon=12, tm_mday=5, tm_hour=2, tm_min=27, tm_sec=57, tm_wday=1, tm_yday=339, tm_isdst=0)
>>> time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
'2017-12-05 02:28:10'

5.strftime与strptime

strftime('fomat',struct) =string  格式,元组=格式化字符串

strptime('string','format) = struct 格式化字符串,格式=元组

6.相互间转换路径

  •  格式化含义
%y 两位数的年份表示(00-99%Y 四位数的年份表示(000-9999%m 月份(01-12%d 月内中的一天(0-31%H 24小时制小时数(0-23%I 12小时制小时数(01-12%M 分钟数(00=59%S 秒(00-59%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身 
  •  日期时间加减
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2017, 12, 5, 12, 8, 55, 706396)
>>> datetime.date.fromtimestamp(time.time())
datetime.date(2017, 12, 5)
>>> print(datetime.datetime.now() + datetime.timedelta(3))
2017-12-08 12:10:32.978267
默认是天数 >>> print(datetime.datetime.now() + datetime.timedelta(hours=3)) 2017-12-05 15:10:40.681483 >>> print(datetime.datetime.now() + datetime.timedelta(hours=+3)) 2017-12-05 15:10:49.099027
+也行 >>> print(datetime.datetime.now() + datetime.timedelta(minutes=30)) 2017-12-05 12:40:56.701895 >>> c_time = datetime.datetime.now() >>> c_time datetime.datetime(2017, 12, 5, 12, 11, 8, 369987) >>> c_time.replace(minute=3,hour=2) datetime.datetime(2017, 12, 5, 2, 3, 8, 369987) >>> c_time.replace(hour=2,minute=3) datetime.datetime(2017, 12, 5, 2, 3, 8, 369987) >>>

 模块random

choice(seq) method of Random instance
        Choose a random element from a non-empty sequence.

  • 非空序列返回一个随机元素
  • >>> random.choice(range(10))
    9

random(...) method of Random instance

random() -> x in the interval [0, 1).

  • 返回左闭右开,默认是0到1之间的浮点数
  • >>> random.random()
    0.41816400018068844
    >>> random.random()
    0.035185160469280996
    >>> random.random()
    0.9860034118082212
    View Code

randint(a, b) method of Random instance
        Return random integer in range [a, b], including both end points.

  • 返回左闭右闭,居于a,b之间的整数
  • >>> random.randint(1,10)
    7
    >>> random.randint(1,10)
    1
    >>> random.randint(1,10)
    10

randrange(start, stop=None, step=1, _int=<class 'int'>) method of Random instance
        Choose a random item from range(start, stop[, step]).

        This fixes the problem with randint() which includes the
        endpoint; in Python this is usually not what you want.

  • 返回左闭右开的整数,默认步长为1
  • >>> random.randrange(1,10,2)
    5

sample(population, k) method of Random instance
        Chooses k unique random elements from a population sequence or set.

  • 从一个范围里面取出k个元素组成随机列表
  • >>> list1=['a','b','c','d']
    >>> random.sample(list1,2)
    ['c', 'd']
    >>> random.sample(list1,2)
    ['b', 'c']
    >>> random.sample(range(10),2)
    [2, 6]
    >>> random.sample(range(10),4)
    [3, 7, 2, 1]
  • 返回16位的随机数

import random
def generate_num():
    list1=[]
    str1=''
    str2=''
    for i in range(0,4):
        for j in range(0,4):
            list1.append(str(random.randint(1,9)))
        str1=''.join(list1)
    i=0
    j=4
    for k in range(0,4):
        str2+=str1[i:j]+' '
        i=i+4
        j=j+4
    return(str2.strip())
print(generate_num())
#4169 2751 4887 7239
  • 产生4位随机验证码
import random
def random_func():
    list1=[]
    list1.append(str(random.randint(1,9)))
    list1.append(str(random.randint(1, 9)))
    i=random.randint(97,123)
    list1.append(chr(i))
    i = random.randint(65, 91)
    list1.append(chr(i))
    random.sample(list1,4)
    str1=''.join(list1)
    print(str1)
random_func()

模块os

>>> os.getcwd()
'/opt/pycharm-2017.2.4/bin'
获取当前工作目录
>>> os.chdir('/tmp')
改变工作目录到tmp
>>> os.getcwd() '/tmp' >>> os.curdir '.'
获取当前目录
>>> os.pardir '..'
获取当前目录的父目录
>>> os.makedirs('/tmp/a/b/c/d')
递归创建目录
>>> os.removedirs('/tmp/a/b/c/d')
递归删除目录,目录不为空无法删除
>>> os.mkdir('/tmp/a/b/c') Traceback (most recent call last): File "<stdin>", line 1, in <module> FileNotFoundError: [Errno 2] No such file or directory: '/tmp/a/b/c'
>>> os.mkdir('/tmp/a')
只能创建在已存在目录中创建目录
>>> os.rmdir('/tmp/a') >>> os.listdir('/tmp') ['+~JF8742810560838194690.tmp', ...
以列表显示目录下所有文件>>> os.mkdir('/tmp/os') >>> os.chdir('/tmp/os') >>> os.listdir('/tmp/os') [] >>> os.mkdir('/tmp/os/dir1') >>> os.remove('/tmp/os/dir1') Traceback (most recent call last): File "<stdin>", line 1, in <module> IsADirectoryError: [Errno 21] Is a directory: '/tmp/os/dir1'
只能删除文件,无法删除目录
>>> os.stat('/tmp/os/dir1') os.stat_result(st_mode=16893, st_ino=11141382, st_dev=2053, st_nlink=2, st_uid=1000, st_gid=1000, st_size=4096, st_atime=1512973378, st_mtime=1512973378, st_ctime=1512973378) 获取文件/目录信息
>>> os.sep '/'
操作系统路径分隔符,win:\\ linux:/
>>> os.linesep '\n'
获取换行符nwin下为"\t\n",Linux下为"\n"
>>> os.pathsep ':'
获取分割文件路径的分隔符
>>> os.name 'posix'
输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
>>> os.system("df -h") 文件系统 容量 已用 可用 已用% 挂载点 udev 3.8G 0 3.8G 0% /dev tmpfs 769M 9.6M 759M 2% /run /dev/sda5 230G 156G 63G 72% / tmpfs 3.8G 173M 3.6G 5% /dev/shm tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup tmpfs 769M 116K 769M 1% /run/user/1000 /dev/sdb 11M 11M 0 100% /media/yangzhenwei/XIAOMI 0
执行操作命令,但无法存储结果到变量
用这个命令可以存储结果:res1=os.popen('df -h').read()
>>> os.environ environ({'LANG': 'zh_CN.UTF-8',...
获取系统环境变量
>>> os.path.abspath('/tmp/os') '/tmp/os' >>> os.path.abspath('os') '/tmp/os/os'
获取path规范化绝对路径
>>> os.getcwd() '/tmp/os' >>> os.path.split('/tmp/os/os/os') ('/tmp/os/os', 'os')
将目录与文件已二元组返回,文件不需要预先存在
>>> os.path.dirname('/tmp/os/os/os') '/tmp/os/os'
获取目录名
>>> os.path.basename('/tmp/os/os/os') 'os'
获取文件名(目录名)
>>> os.path.exists('/tmp/os/os/os') False
>>> os.path.exists('/tmp/os/') True
输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
>>> os.path.isabs('/tmp/os') True >>> os.path.isabs('os') False
判断路径是否是绝对路径
>>> os.path.isfile('/tmp/os') False 
判断是否文件
>>> os.path.isdir('/tmp/os') True
判断是否目录
>>> os.path.join('/tmp/os','/tmp/os1','tmp/os2') '/tmp/os1/tmp/os2'
拼接目录
>>> os.path.getatime('/tmp/os') 1512973391.410328
>>> import time
>>> time.localtime(os.path.getatime('/tmp/os')) time.struct_time(tm_year=2017, tm_mon=12, tm_mday=11, tm_hour=14, tm_min=23, tm_sec=11, tm_wday=0, tm_yday=345, tm_isdst=0)
返回文件或目录最后的存取时间戳
a access
>>> os.path.getmtime('/tmp/os')
1512973378.6063702 >>>
返回文件或目录最后的修改时间戳

 

模块sys

>>> import sys
>>> sys.argv
['']
以列表形式获取参数
>>> sys.exit(1) yangzhenwei@T450:/opt/pycharm-2017.2.4/bin$ python3.5 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.exit(0)
yangzhenwei@T450:
/opt/pycharm-2017.2.4/bin$ python3.5 Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> sys.version Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'sys' is not defined >>> import sys >>> sys.version '3.5.2 (default, Nov 23 2017, 16:37:01) \n[GCC 5.4.0 20160609]'>>> sys.maxsize 9223372036854775807 >>> sys.platform 'linux' >>> sys.stdout.write('asdf:') asdf:5 >>> val = sys.stdin.readline()[:-1] >>> print(val) >>> val = sys.stdin.readline()[:-1] asdf >>> print(val) asdf >>>
读取一行输入

模块shutil

copyfileobj(fsrc, fdst, length=16384)
    copy data from file-like object fsrc to file-like object fdst

  • 拷贝文件内容fsrc到fdst,目标文件必须是已经打开
import shutil
str1='asdfasdfasd'
with open('../config/001.txt','w',encoding='utf-8') as fdw:
    fdw.write(str1)
with open('../config/001.txt','r',encoding='utf-8') as fdr1,\
        open('../config/001.txt.bak','r',encoding='utf-8') as fdr2:
    fdcontent=fdr1.readline()
    shutil.copyfile('../config/001.txt','../config/001.txt.bak')
with open('../config/001.txt.bak','r',encoding='utf-8') as fdr2:
    fdcontent = fdr2.readline()
    print(fdcontent)

 

copy(src, dst, *, follow_symlinks=True)
    Copy data and mode bits ("cp src dst"). Return the file's destination.

  • 相当于cp,拷贝内容和权限,
import shutil
str1='asdfasdfasd'
with open('../config/001.txt','w',encoding='utf-8') as fdw:
    fdw.write(str1)
with open('../config/001.txt','r',encoding='utf-8') as fdr:
    fdcontent=fdr.readline()
print('file content is:',fdcontent)
shutil.copyfile('../config/001.txt','../config/001.txt.bak')
with open('../config/001.txt.bak','r',encoding='utf-8') as fdr:
    copyfilecontent=fdr.readline()
print('copyfile content is:',copyfilecontent)
output:
file content is: asdfasdfasd
copyfile content is: asdfasdfasd

copymode(src, dst, *, follow_symlinks=True)
    Copy mode bits from src to dst.

  • 拷贝权限,内容,组,用户不变

copystat(src, dst, *, follow_symlinks=True)
    Copy all stat info (mode bits, atime, mtime, flags) from src to dst.

  • 权限位,状态信息

copy2(src, dst, *, follow_symlinks=True)
    Copy data and all stat info ("cp -p src dst"). Return the file's
    destination."

  • 相当于cp -p

copytree(src, dst, symlinks=False, ignore=None, copy_function=<function copy2 at 0x7f77bc1ad2f0>, ignore_dangling_symlinks=False)
    Recursively copy a directory tree.

    The destination directory must not already exist.
    If exception(s) occur, an Error is raised with a list of reasons.

  • 递归拷贝,目标目录不能预先存在,相当于cp -r

rmtree(path, ignore_errors=False, onerror=None)
    Recursively delete a directory tree.

  • 递归的删除目录

move(src, dst, copy_function=<function copy2 at 0x7f77bc1ad2f0>)
    Recursively move a file or directory to another location. This is
    similar to the Unix "mv" command. Return the file or directory's
    destination.

    If the destination is a directory or a symlink to a directory, the source
    is moved inside the directory. The destination path must not already
    exist.

  • 递归的移动目录,相当于mv,已存在的文件/目录会被覆盖

make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=0, owner=None, group=None, logger=None)
    Create an archive file (eg. zip or tar).

  • 创建归档文件
shutil.make_archive('/tmp/001','gztar','../config')
文件名,格式,被压缩目录

unpack_archive(filename, extract_dir=None, format=None)
    Unpack an archive.

shutil.unpack_archive('/tmp/001.tar.gz','/tmp/002/','gztar')
被解压文件名,指定解压后的目录,归档的格式

模块shelve

shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

import shelve
k1=shelve.open('../config/dbfile.txt')
k1['name']='alex'
k1['age']=18
k1.close()
k2=shelve.open('../config/dbfile.txt')
print(k2['name'],k2['age'])
k2.close()

模块xml

查看xml文件内容

import xml.etree.ElementTree as ET
tree = ET.parse("../config/xmlfile.xml")
#通过parse方法加载xml文件 root
=tree.getroot()
#将最顶级标签内容赋值保存
print(root.tag)
#打印顶级标签tag
for child in root: print(child.tag,child.attrib)
  #打印顶级标签的下一级标签tag和属性
for i in child: print(i.tag,i.text)
  #遍历下一级标签的tag和内容
for node in root.iter('year'): print(node.tag,node.text)
  #打印制定标签的tag和内容

修改xml文件

import xml.etree.ElementTree as ET
tree = ET.parse("../config/xmlfile.xml")
root=tree.getroot()
for node in root.iter('year'):
  #遍历指定节点year
    new_year = int(node.text) + 1000
  #取节点的文本内容并修改复制变量
    node.text=str(new_year)
  #用变量修改指定节点的文本内容
    node.set("updated","yes")
  #更新节点的属性信息,前面是k,后面是v
tree.write('../config/xmlfile.xml')
#将更新写入文件
for country in root.findall('country'):
  #遍历所有country节点 rank
=int(country.find('rank').text) if rank > 50: root.remove(country)
  #符合条件的country节点被删除,子节点也被删除 tree.write((
'../config/xmlfile1.xml'))

创建xml文件

import xml.etree.ElementTree as ET
new_xml =ET.Element('namelist')
#定义顶级标签名字 name
=ET.SubElement(new_xml,"name",attrib={'enrolled':'yes'})
#在顶级标签下定义name标签,并增加k/v属性 age
=ET.SubElement(name,"age",attrib={"checked":"no"})
#在name标签下定义age标签,增加K/V属性 sex
=ET.SubElement(name,"sex")
#在name标签下定义sex标签,没有属性 age.text
='18'
#给age标签赋值文本内容
name2=ET.SubElement(new_xml,"name",attrib={'enrolled':'yes'}) age=ET.SubElement(name2,"age",attrib={"checked":"no"}) age.text='19' et = ET.ElementTree(new_xml)
#生成文档对象 et.write(
"../config/new_xml.xml",encoding='utf-8',xml_declaration=True)
#将文档对象写入文件 ET.dump(new_xml)
#打印生成格式

模块yaml

 

模块configparser

生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser

生成配置文件

import configparser

config=configparser.ConfigParser()
config["DEFUALT"] = {"ServerAliveInterval":"45",
                     "Compression":"yes",
                    "CompressionLevel":"9"}
#定义default,下面带三个k/v config[
'www.com']={}
#定义www.com,空值 config[
"www.com"]['user']='alex'
#给www.com的user k增加v alex
config["com.www"]={}
#定义com.www,空值 topsecret
=config["com.www"]
#将com.www赋值topsecret topsecret[
'host port']='55500'
#给com.www增加k/v
topsecret['forwardx11']='no' config['DEFAULT']['forwardx11']='yes'
#给default增加k/v
with open('../config/config.config','w') as configfile: config.write(configfile)

最终生成如下

[DEFAULT]
forwardx11 = yes
compression = yes
serveraliveinterval = 45
compressionlevel = 9

[www.com] user = alex [com.www] host port = 55500 forwardx11 = no

读取配置文件

import configparser
config = configparser.ConfigParser()
print(config.sections())
#没有指定文件输出空的字典 config.read(
'../config/config.config')
#读取配置文件
print(config.sections())
#除了default,打印其他section名字
print('www.com' in config) print('name' in config) print(config['www.com']['User']) print(config['DEFAULT']['Compression'])
#类似字典获取value值
for k in config['DEFAULT']: print(k)
#遍历制定section的key
[]
['www.com', 'com.www']
True
False
alex
yes
serveraliveinterval
compression
compressionlevel
forwardx11

修改配置文件

import configparser
config = configparser.ConfigParser()
print(config.sections())
config.read('../config/config.config')
print(config.sections())
print(config['www.com']['user'])
sec = config.remove_section('www.com')
#使用remove_section删除一个section config.write(open(
'../config/config.config','w'))
#将修改写入文件
print(config.sections())

import configparser
config = configparser.ConfigParser()
# print(config.sections())
config.read('../config/config.config')
# print(config.sections())
print(config['com.www']['host port'])
config.set('com.www','host port','80')
#将section com.www的host port值改成80 config.write(open(
'../config/config.config','w')) print(config['com.www']['host port'])

模块hashlib

用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

>>> import hashlib
>>> m=hashlib.md5()
#使用md5加密
>>> print(m) <md5 HASH object @ 0x7fcf5f208a80> >>> m.update(b'hello')
#加密内容
>>> print(m.digest()) b']A@*\xbcK*v\xb9q\x9d\x91\x10\x17\xc5\x92'
#二进制格式hash值
>>> print(m.hexdigest()) 5d41402abc4b2a76b9719d911017c592
#十六进制格式hash值

中文和英文要显式指定编码格式

import hashlib
hash = hashlib.md5()
hash.update('admin'.encode('utf-8'))
print(hash.hexdigest())
hash.update('您好吗'.encode('utf-8'))
print(hash.hexdigest())
21232f297a57a5a743894a0e4a801fc3
b873962b10729c2f6564b2aa9667df3

其他加密方法使用格式

  • hashlib.md5()
  • hashlib.sha1()
  • hashlib.sha256()
  • hashlib.sha384()
  • hashlib.sha512

模块subprocess

用于替换os.system和os.spawn*模块

call(*popenargs, **kwargs):
        Run command with arguments.  Wait for command to complete, then
        return the returncode attribute.
            The arguments are the same as for the Popen constructor.  Example:
            >>> retcode = subprocess.call(["ls", "-l"])

  • 执行命令,等待命令完成,会在屏幕并返回结果,res存储的是命令执行后的状态,0为成功
  • 如果命令的执行过程报错了,返回非0失败
  • 不怎么用

check_call(*popenargs, **kwargs):
        Run command with arguments.  Wait for command to complete.  If the
        exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.
            The arguments are the same as for the Popen constructor.  Example:
            >>> subprocess.check_call(["ls", "-l"])
        0

  • 执行命令,等待命令完成,如果正确执行,则返回,否则抛出异常
  • 正确情况下,感觉和上面是一样的

getstatusoutput(cmd):
        Return (status, output) of executing cmd in a shell.
            Execute the string 'cmd' in a shell with 'check_output' and
        return a 2-tuple (status, output). Universal newlines mode is used,
        meaning that the result with be decoded to a string.

  • 以二元组的格式返回执行状态和结果,第二个元素类型是str,如果命令错误,也返回
  • 重点使用

getoutput(cmd):
        Return output (stdout or stderr) of executing cmd in a shell.
            Like getstatusoutput(), except the exit status is ignored and the return
        value is a string containing the command's output.  Example:
            >>> subprocess.getoutput('ls /bin/ls')
        '/bin/ls'

  • 返回命令执行结果

check_output(*popenargs, **kwargs):
        Run command with arguments and return its output.
            If the exit code was non-zero it raises a CalledProcessError.  The
        CalledProcessError object will have the return code in the returncode
        attribute and output in the output attribute.

  • 以byte类型返回结果,并不打印,需要用变量接收返回结果
res=subprocess.Popen("ifconfig|grep 10",shell=True)
# 屏幕打印结果
print('xx',res)
# 输出至屏幕,没有存储
res1=subprocess.Popen("ifconfig|grep 10",shell=True,stdout=subprocess.PIPE)
#屏幕不打印,保存到标准输出
print('dd',res1.stdout.read())
#将标准输出内容打印出来
# res1=subprocess.Popen("ifconfig|grep 10",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#发生错误保存到标准错误里
>>> res2=subprocess.Popen("sleep 10;echo 'xxx'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res2.stdout.read()






b'xxx\n'
>>> 
#必须是执行完之后才打印,否则进行等待

poll()
        Check if child process has terminated.  Returns returncode  attribute.

  •    检查命令执行结果,为0表示正确执行,如果是None表示未执行完毕
>>> res2=subprocess.Popen("sleep 10;echo 'xxx'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> 
>>> print(res2.poll())
None
>>> print(res2.poll())
None
>>> print(res2.poll())
None
>>> print(res2.poll())
0

wait()
        Wait for child process to terminate.  Returns returncode attribute.

  • 等待子进行完成执行,返回执行结果状态
>>> res2=subprocess.Popen("sleep 10;echo 'xxx'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res2.wait()

0
>>> 

terminate(self)
     |      Terminate the process with SIGTERM

  • 结束子进程,将不会有输出
>>> res2=subprocess.Popen("sleep 10;echo 'xxx'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> res2.terminate()
>>> res2.stdout.read()
b''

communicate(self, input=None, timeout=None)
     |      Interact with process: Send data to stdin.  Read data from
     |      stdout and stderr, until end-of-file is reached.  Wait for
     |      process to terminate.

  •  内容会拼接
>>> res2=subprocess.Popen(['python3.5'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
>>> res2.stdin.write(b"print(1)")
8
>>> res2.stdin.write(b"print(2)")
8
>>> res2.stdin.write(b"print(4)")
8
>>> res.communicate()
(None, None)

cwd -- 新启动的子shell默认工作目录

>>> res2=subprocess.Popen(['pwd'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,cwd='/tmp')
>>> res2.stdout.read()
b'/tmp\n'

linux shell sudu 预先填密码

echo "password"| sudo -S vi /etc/hosts
subprocess.Popen("echo 'password'| sudo -S vi /etc/hosts",shell=True)

 

 

模块logging

日志级别一般分为5个,默认级别是warning

debug,打印详细信息,一般调试的时候才用

info,输出一般信息

warning,输出警告信息

error,输出错误信息

critical,严重错误级别

  • 日志输出方法
import logging
logging.debug("debug ")
logging.info("info ")
logging.warning("warning")
logging.error("error")
logging.critical('critical error')
output:
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical error
  • 设置日志输出重定向到文件,并指定默认级别,此方法仅重定向文件,屏幕不再输出
logging.basicConfig(filename='../config/log.log',level=logging.INFO)
  • 格式化日志输出
logging.basicConfig(filename='../config/log.log',\
                    level=logging.INFO,\
                    format='%(asctime)s %(filename)s: %(lineno)d %(module)s %(process)d  %(levelname)s %(message)s',\
                    datefmt='%m/%d/%Y %I:%M:%S %p')
output:
12/11/2017 10:16:04 PM getjson.py: 15 getjson  CRITICAL critical error
12/11/2017 10:18:07 PM getjson.py: 12 getjson 6800  INFO info 
12/11/2017 10:18:07 PM getjson.py: 13 getjson 6800  WARNING warning
12/11/2017 10:18:07 PM getjson.py: 14 getjson 6800  ERROR error
12/11/2017 10:18:07 PM getjson.py: 15 getjson 6800  CRITICAL critical error
  • 日志格式
     |  %(name)s            Name of the logger (logging channel)
    Logger的名字
| %(levelno)s Numeric logging level for the message (DEBUG, INFO, | WARNING, ERROR, CRITICAL)
    数字形式的日志级别
| %(levelname)s Text logging level for the message ("DEBUG", "INFO", | "WARNING", "ERROR", "CRITICAL")
    文本形式的日志级别
| %(pathname)s Full pathname of the source file where the logging | call was issued (if available)
    调用日志输出函数的模块完整路径名
| %(filename)s Filename portion of pathname
    调用日志输出函数的模块文件名
| %(module)s Module (name portion of filename)
    调用日志输出函数的模块名
| %(lineno)d Source line number where the logging call was issued | (if available)
    调用日志输出函数语句所在的代码行
| %(funcName)s Function name
    调用日志输出函数的函数名
| %(created)f Time when the LogRecord was created (time.time() | return value)
    当前时间,用户unix标准的表示时间的浮点数
| %(asctime)s Textual time when the LogRecord was created
    字符串形式的当前时间,默认格式是'YYYY-mm-dd HH:MM:SS,xxx' 逗号后是毫秒
| %(msecs)d Millisecond portion of the creation time
    毫秒部分
| %(relativeCreated)d Time in milliseconds when the LogRecord was created, | relative to the time the logging module was loaded | (typically at application startup time)
    输出日志信息时,自Logger创建以来的毫秒数
| %(thread)d Thread ID (if available)
    线程ID
| %(threadName)s Thread name (if available)
    县城名
| %(process)d Process ID (if available)
    进程ID
| %(message)s The result of record.getMessage(), computed just as | the record is emitted
    用户输出的消息

 

  • 日志涉及4个主要类:
    • logger,提供应用程序可以直接使用的接口
    • handler将logger创建的日志记录发送到合适的目的地输出,包括远程,几个handler就发送到几个地方
    • filter提供了细度设备来决定输出那条日志记录,比较少用
    • formatter决定日志记录的最终输出格式

logger

  • 程序输出信息前需要获得一个logger,获取logger的方法:
  1. 图形界面获取logger:
    • LOG=logging.getLogger("chat.gui')
  2. 核心模块获取logger:
    • LOG=logging.getLogger("chat.kernel")
  • 指定日志级别:
  1. Logger.setLevel(lel)  最低级别debug,最高级别critical
  2. Logger.addFilter(filt)  Logger.removeFilter(filt) 添加或删除指定的filter
  3. Logger.addHandler(hdlr) Logger.removeHandler(hdlr) 增加或者删除指定的handler
  4. Logger.debug()  Logger.info() Logger.warning() Logger.error() Logger.critical() 设置日志5个级别

 handler

  • handler对象负责将相关信息发送到目的地,可以是控制台、文件、网络、自定义
  • addHandler()方法增加多个handler
  • Handler.setLevel(lel) 指定被处理的信息级别,低于lel级别信息将被忽略
  • Handler.setFormatter() 给指定handler选择一个格式
  • Handler.addFilter(filt) Handler.removeFilter(filt) 新增或者删除一个filter对象
  • logging.StreamHandler  屏幕输出,类似sys.stdout/sys.stderr,构造函数是StreamHandler([strm]),strm是个文件对象,默认是sys.stderr
  • logging.FileHandler 文件输出,构造函数FileHandler(filename,[mode]),filename是文件名,mode打开方式,默认是a
  • 步骤:
    1. 获取logger名字
    2. 设置输出handler,文件、屏幕
    3. 输出不同的日志格式
    4. 绑定handler和日志格式
    5. 绑定handler和logger
  • 日志截断
    • 文件截断:
      • logging.handlers.RotatingFileHandler 就是当文件达到某个大小,改名,备份,继续输出,如:xxx.log.1 xxx.log2 ...,
      • 构造函数是RotationgFileHandler(filename,[,mode[,maxBytes[,backupCount]]]) 文件名,模式,最大字节数,备份个数
    • 时间截断:
      • TimedRotatingFileHandler(filename[,when[,interval[,backupcount]]]) 文件名,when代表S/M/H/D/W/midnight,interval==0代表星期一,时间间隔

屏幕和文件同时输出:

#/usr/bin/env python
#-*- coding: utf-8 -*-
#Author:jenvid.yang
import logging
logger=logging.getLogger('logger_name')
logger.setLevel(logging.DEBUG)
#指定被处理的信息默认级别,低于debug级别不被处理

stream_handler=logging.StreamHandler()
#实例化一个streamhandler对象
stream_handler.setLevel(logging.DEBUG)
#设置streamhandler对象的日志级别

file_handler=logging.FileHandler('../filelog.log')
#实例化一个file对象
file_handler.setLevel(logging.WARNING)
#设置file对象日志级别

formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#设置一个新的日志格式

stream_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
#两个输出对象绑定输出格式

logger.addHandler(stream_handler)
logger.addHandler(file_handler)
#logger绑定两个输出对象

logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

 日志截断:

import logging
from logging import handlers
logger=logging.getLogger('logger_name')
fh=handlers.RotatingFileHandler(filename='../log.txt',maxBytes=5,backupCount=3)
formatter=logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.error('errorerror')

 

posted @ 2017-11-28 19:30  Jenvid  阅读(739)  评论(0编辑  收藏  举报