Python 常用内建模块

常用内建模块

os 模块

os 模块中主要包含创建和管理进程或者文件系统内容(比如文件和目录)的函数, os 模块为平台特定的一些模块做了包装, 使得所有平台访问的函数接口相同, 这样就具备了可移植性。下面是 os 模块下一些常用的函数:

方法 说明 用法举例
os.getcwd() 获取当前所在的目录 os.getcwd()
os.chdir() 切换目录 os.chdir('..') (.. 为父级目录, 这里表示切换到上一级目录, 相当于命令行的 cd ..)
os.getenv() 获取系统变量的值(若变量不存在返回 None) os.getenv('SHELL')
os.environ.getenv() 获取系统变量的值(若变量不存在会引发异常) os.environ.getenv('SHELL')
os.listdir() 列出目录下的全部文件 os.listdir('dir'), 列出 dir 目录下的全部文件
os.walk() 递归地遍历指定的目录, 对于每个目录都会生成一个元组, 其中包含了目录的路径、该目录下所有的子目录以及该目录下所有文件的列表。它是一个生成器, 可以用 list() 转换成一个列表 os.walk('dir'), list(os.walk('dir'))
os.makedir() 创建一个目录, 只能创建单层目录, 若创建多层目录会报错 os.makedir('dir'), 创建一个名为 dir 的目录
os.makedirs() 创建多层目录 os.makedirs('/dir2/dir3')
os.remove() 删除指定文件 os.remove('1.txt'), 删除当前目录下的 1.txt 文件
os.rmdir() 删除目录 os.rmdir('dir1'), 删除当前目录下的 dir 目录
os.rename() 重命名文件或者目录 os.rename('dir2', 'dir1'), 将 dir2 目录重命名为 dir1

os.path 模块、

os 模块下有一个独有的 path 子模块, 可以使用 os.path.函数名字 的方式调用, 也可以 import os.pathos.path 模块是和路径有关的。下面是此模块下一些常用的函数:

方法 说明
os.path.basename() 获得指定文件路径的文件名字
os.path.dirname() 获得文件路径的目录名字
os.path.exists() 判断文件或者目录是否存在
os.path.isdir() 判断指定路径是否是目录
os.path.isfile() 判断指定路径是否是文件
os.path.join() 拼接路径
os.path.split() 路径拆分
os.path.splitext() 获得路径的后缀
In: import os

In: p = '/home/jiangyang/a.txt'

In: os.path.basename(p) # 获得指定文件路径的文件名字
Out:
a.txt

In: os.path.dirname(p) # 获得文件路径的目录名字
Out:
/home/ubuntu

In: os.path.join('\\Users', 'jiangyang', 'flask\\app.py') # windows 下
Out:
\Users\jiangyang\flask\app.py

In: os.path.join('/Users', 'jiangyang', 'flask/app.py') # Ubuntu 下
Out:
/Users/jiangyang/flask/app.py

In: os.path.split(p) # 路径拆分
Out:
('/home/ubuntu', 'a.txt')

In: os.path.splitext(p) # 获得路径的后缀
Out:
('/home/ubuntu/a', '.txt')

sys 模块

sys 模块提供了特定系统的配置和操作

方法 说明
sys.platform 用来构建解释器的操作系统平台
sys.version 构建时的版本信息, 包含完整的版本号和构建日期、编译器、平台信息等
sys.version_info 同样是版本信息, 但不是字符串, 可以直接获得对应类型版本的信息
sys.path[0] 搜索模块的路径列表
sys.modules.get() 已经导入的模块列表
sys.getrefcount() 查看对象的引用计数
sys.getsizeof() 以字节(byte)为单位返回对象大小。这个对象可以是任何类型的对象。 所以内置对象都能返回正确的结果 但不保证对第三方扩展有效,因为和具体实现相关。

sys.getrefcount

Python 使用引用计数和垃圾回收来完成字段的内存管理, 当一个对象的引用数降为 0, 就会自动标记为回收。在实际开发中, 可能因为 debug 或者调试的需要, 需要了解引用计数, 就可以使用 sys.getrefcount()。

import sys

d = []

print(sys.getrefcount(d))
# 输出 2

x = d

print(sys.getrefcount(d))
# 输出 3

del x

print(sys.getrefcount(d))
# 输出 2

上面的计数比预期多一个, 是因为 getrefcount() 本身也会维护一个临时引用。

sys.getsizeof

了解对象的引用计数不足以发现内存泄漏, 可以使用 sys.getsizeof 辅助, 这样可以确定对象消耗内存的情况。

# 打印 Python 内置数据结构占用的字节数
for obj in ({}, [], (), 'string', 1, 12.3):
    print(obj.__class__.__name__, sys.getsizeof(obj))

# 输出:
dict 240
list 64
tuple 48
str 55
int 28
float 24

命令行参数 sys.argv

在命令行下运行一个 Python 程序, 可以通过 sys.argv 获取脚本的名字和参数。有个 argv.py, 代码如下:

import sys

script_name, *args = sys.argv

print(f'Script: {script_name}')
print(f'Arguments: {args}')
> python argv.py
Script: argv.py
Arguments: []

> python argv.py -v
Script: argv.py
Arguments: ['-v']

> python argv.py -v -v -e 'foo'
Script: argv.py
Arguments: ['-v', '-v', '-e', "'foo'"]

csv 模块

逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。 纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。

>>> with open('test.csv', 'wt') as f:
...     writer = csv.writer(f) # 把文件对象传给 csv.writer()
...     writer.writerow(('ID', '用户', '类型')) # 写入标题
...     for i in range(5):
...         row = (i, f'用户{i}', f'类型{i}')
...         writer.writerow(row)

In: cat test.csv
Out:
ID,用户,类型
0,用户0,类型0
1,用户1,类型1
2,用户2,类型2
3,用户3,类型3
4,用户4,类型4

>>> with open('test.csv', 'rt') as f:
...     reader = csv.reader(f)
...     for line in reader:
...         print(line)

# 输出:
['ID', '用户', '类型']
['0', '用户0', '类型0']
['1', '用户1', '类型1']
['2', '用户2', '类型2']
['3', '用户3', '类型3']
['4', '用户4', '类型4']

>>> with open('test.csv', 'rt') as f:
...     reader = csv.DictReader(f) # 键为第一行写入的键名, 值是对应的字段的值
...     for line in reader:
...         print(line)
...         print(line['类型'])

# 输出:

OrderedDict([('ID', '0'), ('用户', '用户0'), ('类型', '类型0')])
类型0
OrderedDict([('ID', '1'), ('用户', '用户1'), ('类型', '类型1')])
类型1
OrderedDict([('ID', '2'), ('用户', '用户2'), ('类型', '类型2')])
类型2
OrderedDict([('ID', '3'), ('用户', '用户3'), ('类型', '类型3')])
类型3
OrderedDict([('ID', '4'), ('用户', '用户4'), ('类型', '类型4')])
类型4

datetime 模块

datetime 模块用来完成日期和时间的解析、格式化和算术运算等。

In: import datetime

In: now = datetime.datetime.now() # 获取当前时间
In: now
Out: datetime.datetime(2018, 4, 14, 21, 49, 7, 733048)

In: now.year, now.month, now.day, now.hour, now.minute
Out: (2018, 4, 14, 21, 49)

In: today = datetime.date.today()
In: today
Out: datetime.date(2018, 4, 14)
In: today.year, today.month, today.day
Out: (2018, 4, 14)

In: d1 = datetime.date(2010, 9, 1)
In: d1
Out: datetime.date(2010, 9, 1)

# 可以使用 datetime.timedelta 对象进行时间的运算, 支持秒、分钟、小时、天、周
In : print('seconds :', datetime.timedelta(seconds=1))
...: print('minutes :', datetime.timedelta(minutes=1))
...: print('hours :', datetime.timedelta(hours=1))
...: print('days :', datetime.timedelta(days=1))
...: print('weeks :', datetime.timedelta(weeks=1))
...:
Out:
seconds : 0:00:01
minutes : 0:01:00
hours : 1:00:00
days : 1 day, 0:00:00
weeks : 7 days, 0:00:00

In: hour = datetime.timedelta(hours=1)
In: hour.total_seconds
Out: <built-in method total_seconds of datetime.timedelta object at 0x0000028F5609F418>
In hour.total_seconds() # 获得一个小时的秒数
Out: 3600.0

In: today = datetime.date(2010, 9, 1)
In: today + datetime.timedelta(days=1) # 加上一天
Out: datetime.date(2010, 9, 2)
In: today - datetime.timedelta(days=1) # 减去一天
Out: datetime.date(2010, 8, 31)

时间格式化

In: dt_format = '%Y-%m-%d %H:%M:%S'

In: s = datetime.datetime.now().strftime(dt_format)
In: print('strftime:'s)
Out: strftime: 2018-04-14 22:17:27

In: d = datetime.datetime.strptime(s, dt_format)
In: print('strptime:', d)
Out: strptime: 2018-04-14 22:17:27

In: d
Out: datetime.datetime(2018, 4, 14, 22, 17, 27)

random 模块

random 模块用于生成随机数。

方法 说明
random.random() 在 [0, 1) 的范围内返回一个随机数
random.uniform(a, b) 在 [a, b) 范围内返回一个随机数
random.seed() 改变随机数生成器的种子,可以在调用其他随机模块函数之前调用此函数
random.randint(a, b) 在 [a, b] 范围内返回一个随机整数
random.randrange ([start,] stop [,step]) 返回指定递增基数集合中的一个随机数,基数缺省值为1。start : 指定范围内的开始值,包含在范围内。stop: 指定范围内的结束值,不包含在范围内。step: 指定递增基数。
sample(seq, n) 从序列seq中选择n个随机且独立的元素
random.choices(seq, k=a) 从序列seq中选择a个随机的元素, 元素有可能重复
random.choice(seq) 从序列seq中返回随机的元素
In: import random
In: import time

In: for i in range(5):
...     print(f'{random.random():.4f}', end='\t') # random.random() 返回一个范围 0-1 的随机数
Out: 0.4204  0.7056  0.0160  0.4581  0.1351


In: for i in range(5):
...     print(f'{random.uniform(10, 20):.4f}', end='\t') # random.uniform() 可以改变随机数的范围
...
Out: 11.0320 14.0456 19.2699 19.1666 11.2022


In: t = time.time() # 生成一个时间戳
In: random.seed(t) # 改变随机数生成器的种子

In: for i in range(5):
...     print(f'{random.random():.4f}', end='\t')
Out: 0.8145  0.0111  0.9593  0.6878  0.1719

In: random.seed(t)

# 种子相同, 随机数是相同的
In: for i in range(5):
...     print(f'{random.random():.4f}', end='\t')
Out: 0.8145  0.0111  0.9593  0.6878  0.1719


In: for i in range(5):
...     print(f'{random.randint(1, 100)}', end='\t') # random.randint() 从指定范围内随机取一个整数
Out: 100     22      30      30      36


In: for i in range(5):
...     print(f'{random.randrange(0, 101, 5)}', end='\t')
Out: 80      100     95      95      85


In: random.sample(range(10), 3) # random.sample() 从列表中随机取样, 取样结果不重复
Out: [8, 7, 9]


In: random.choices(range(10), k=3) # random.choices() 从列表中随机取样, 取样结果可能重复
Out: [2, 2, 9]


In: random.choice(['a', 'b', 'c']) # random.choice() 随机取一个元素
Out: 'b'

logging 模块

在代码中使用 print() 打印输出是临时性的调试用途的方案。如果希望在线上记录应用日志或者错误日志等, 可以使用 Python 自带的日志模块 logging。

常用的日志记录类型有两种, 一种是写到文件里面, 另外一种是终端输出。日志文件存储下来是为了未来回溯的方便, 终端输出是以便于实时查看。

logging 模块自带了 6 种级别的日志类型。级别如下(变量值越高说明级别越高):

日志级别 变量值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0
In: import logging


In: logging.warning('Watch out!')
Out: WARNING:root:Watch out!


In: logging.debug("This message won't be printed")
# 无输出


In: logging.basicConfig(level=logging.WARNING) # 使用 basicConfig() 指定默认的日志级别


# getLogger() 自定义 logger 实例, 不同的项目会有自己固定的 logger, 如果能找到 logger 的名字, 就能拿到对应日志的实例
In: logger1 = logging.getLogger('package1.module1')
In: logger2 = logging.getLogger('package1.module2')

In: logger1.warning('This message comes from module1')
Out: WARNING:package1.module1:This message comes from module1
In: logger2.warning('This message comes from module2')
Out: WARNING:package1.module2:This message comes from module2

In: logger2.debug("This message won't be printed")
# 无输出

把日志写入文件

import logging

logging.basicConfig(filename='myapp.log',
level=logging.INFO) # 日志文件为 myapp.log, 级别是 INFO
logging.info('Started') # 写入一行 INFO 的日志 Started
print(logging.root.handlers) # 日志的处理器。root 是默认的一个 logger, 也就是日志实例, 否则得使用 getLogger() 的方式去获得一个 Logger 实例
> python loging_to_file.py
[<FileHandler /home/jiangyanglinlan/myapp.log (NOTSET)>]

> cat myapp.log
INFO:root:Started

最佳使用 logging 的方案

In : import logging
...:
...: logger = logging.getLogger() # 获得一个 logger 的实例
...: handler = logging.StreamHandler() # 实例化 logging 模块自带的 handler
...: formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') # 定制日志格式, name 为 logger 的名字(默认是 root), levelname 为日志的级别, message 是对应的日志内容
...: handler.setFormatter(formatter) # 设置 formatter
...: logger.addHandler(handler) # 给 logger 添加 handler
...: logger.setLevel(logging.DEBUG) # 设置 logger 的级别
...: logger.debug('This is a %s', 'test')
...:
DEBUG:root:This is a test
2018-04-02 18:34:08,443 root DEBUG this is a tes

logging 模块内置日志格式

格式 说明
%(name)s 生成日志的Logger名称。
%(levelno)s 数字形式的日志级别,包括DEBUG, INFO, WARNING, ERROR和CRITICAL。
%(levelname)s 文本形式的日志级别,包括’DEBUG’、 ‘INFO’、 ‘WARNING’、 ‘ERROR’ 和’CRITICAL’。
%(pathname)s 输出该日志的语句所在源文件的完整路径(如果可用)。
%(filename)s 文件名。
%(module)s 输出该日志的语句所在的模块名。
%(funcName)s 调用日志输出函数的函数名。
%(lineno)d 调用日志输出函数的语句所在的代码行(如果可用)。
%(created)f 日志被创建的时间,UNIX标准时间格式,表示从1970-1-1 00:00:00 UTC计算起的秒数。
%(relativeCreated)d 日志被创建时间与日志模块被加载时间的时间差,单位为毫秒。
%(asctime)s 日志创建时间。默认格式是 “2003-07-08 16:49:45,896”,逗号后为毫秒数。
%(msecs)d 毫秒级别的日志创建时间。
%(thread)d 线程ID(如果可用)。
%(threadName)s 线程名称(如果可用)。
%(process)d 进程ID(如果可用)。
%(message)s 日志信息。

相关阅读链接

1.https://pymotw.com/3/
2.https://pymotw.com/2/
3.https://www.python.org/dev/peps/pep-3132/
4.https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
5.https://zh.wikipedia.org/wiki/%E6%A2%85%E6%A3%AE%E6%97%8B%E8%BD%AC%E7%AE%97%E6%B3%95
6.https://www.python.org/dev/peps/pep-3101/
7.https://www.python.org/dev/peps/pep-0282/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容