Python模块基础

模块

  • 文件是python在物理上组织代码的形式
  • 模块是python在逻辑上组织代码的形式
  • 每一个以.py结尾的python文件就是一个模块。将.py扩展名移除后的文件名就是模块名

1)创建模块

[root@localhost day03] vim star.py
hi = 'Hello World!'

def pstar(n=30):
    print('*' * n)

[root@localhost day03] python3
>>> import star
>>> star.hi
'Hello World!'
>>> star.pstar()
******************************

[root@localhost day03] vim a.py
import star

print(star.hi)
star.pstar(50)

[root@localhost day03] python3 a.py
Hello World!
**************************************************

2)导入模块的方法

>>> import sys    # 常用
>>> from random import randint, choice   # 常用,导入一部分方法
>>> randint(1, 100)
3
>>> choice('abcd')
'c'
>>> import time, os, string  # 一行导入多个模块,不推荐
>>> import pickle as p       # 导入模块时,为其起别名,不常用

3)加载(load)

  • 一个模块只被加载一次,无论它被入多少次
  • 只加载一次可以阻止多重导入时代码被多次执行
  • 如果两个文件相互导入,防止了无限的相互加载
  • 模块加载时,顶层代码会自动执行,所以只将函数放入模块的顶层是良好的编程习惯
>>> import this   # 打印the zone of python
>>> import this   # 不会再打印,因为只有第一次import会触发load行为

4)模块导入的特性

  • 需求:某些代码在程序文件直接运行时执行;当程序文件被当作模块导入时不执行
  • 特特殊属性__name__它是一个变量,它有两种值
    • 当程序文件直接运行时,它的值是__main__
    • 当程序文件被当作模块导入时,它的值是模块名
[root@localhost day03]# vim foo.py
print(__name__)
[root@localhost day03]# vim bar.py
import foo
[root@localhost day03]# python3 foo.py
__main__
[root@localhost day03]# python3 bar.py
foo
if __name__ == '__main__':   # 仅当此脚本直接运行时才执行语句。输入main可以自动补全该语句
	print('aaaaa')    

random

>>> import random
>>> random.choice('abc')   # 随机选一个字符
'a'
>>> random.choice('abc')
>>> random.choice(('aaaa', 'bbb', 'ccc'))    # 随机选一个单词
'bbb'
>>> random.choice(('aaaa', 'bbb', 'ccc'))
'bbb'
>>> random.choice(('aaaa', 'bbb', 'ccc'))
'aaaa'
>>> random.randint(1, 100)  # 随机产生1-100内的数字,包括1和100
53
>>> random.randint(1, 100)
12

shutil

import shutil
>>> shutil.copy('/etc/hosts', '/tmp/zj2.txt')   # cp /etc/hosts /tmp/zj2.txt
>>> shutil.move('/tmp/zj.txt', '/var/tmp')      # mv /tmp/zj.txt /var/tmp
>>> shutil.copytree('/etc/security', '/tmp/anquan')  # cp -r
>>> shutil.rmtree('/tmp/anquan')   # rm -rf /tmp/anquan 
# chown student:student /tmp/zj2.txt
>>> shutil.chown('/tmp/zj2.txt', user='student', group='student')

subprocess

  • subprocess模块主要用于执行系统命令
  • subprocess模块允许你产生新的进程,连接到它们的输入/输出/错误管道,并获得它们的返回代码
>>> import subprocess
>>> subprocess.run(['ls', '/home'])
CompletedProcess(args=['ls', '/home'], returncode=0)
>>> subprocess.run(['ls', '/root'])
05  1.py  test  zhuji
CompletedProcess(args=['ls', '/root'], returncode=0)
>>> subprocess.run('ls')
test  05  1.py
CompletedProcess(args='ls', returncode=0)
>>> subprocess.run('ls ~', shell=True)  #使用shell环境运行
05  1.py  nsd2019  test  zhuji
CompletedProcess(args='ls ~', returncode=0)
>>> a = subprocess.run('ls ~', shell =True)  #无法直接保存输出结果
05  1.py  nsd2019  test  zhuji
>>> a 
CompletedProcess(args='ls ~', returncode=0)
>>> a = subprocess.run('ls ~', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)   #定义属性保存,当固定格式使用
>>> a 
CompletedProcess(args='ls ~', returncode=0, stdout=b'05\n1.py\ntest\nzhuji\n', stderr=b'')
>>> a.stdout
b'05\n1.py\nnsd2019\ntest\nzhuji\n'
>>> print(a.stdout.decode())
05
1.py
test
zhuji

time

  • 时间戳:自1970年1月1日0时到某一个时间点之间的秒数
  • UTC时间:世界协调时。
>>> time.time()        # 时间戳
1584495297.0802724
>>> time.sleep(3)      # 相当于shell中的sleep 3
>>> time.ctime()       # UTC
'Wed Mar 18 09:36:50 2020'
>>> time.localtime()   # struct_time9元组
time.struct_time(tm_year=2020, tm_mon=3, tm_mday=18, tm_hour=9, tm_min=37, tm_sec=14, tm_wday=2, tm_yday=78, tm_isdst=0)
>>> t1 = time.localtime()
>>> t1.tm_mday         # 今天的日期
18
>>> t1.tm_yday         # 今天是今年的第几天
78
>>> time.strftime('%Y-%m-%d %a %H:%M:%S')  # 返回当前时间的自定义字符串形式
'2020-03-18 Wed 09:41:07'
# 可以将时间字符串转成相应的9元组形式
>>> t2 = time.strptime('2019-3-10 12:30:00', '%Y-%m-%d %H:%M:%S')

在这里插入图片描述

  • 过滤日志文件
import time

logfile = 'mylog.log'
# 取出日志文件的每一行,判断时间,如果是9点到12点之间的,则打印
t9 = time.strptime('2019-05-15 09:00:00', '%Y-%m-%d %H:%M:%S')
t12 = time.strptime('2019-05-15 12:00:00', '%Y-%m-%d %H:%M:%S')

with open(logfile) as fobj:
    for line in fobj:
        t = time.strptime(line[:19], '%Y-%m-%d %H:%M:%S')
        # if t9 <= t <= t12:
        #     print(line, end='')
        if t > t12:
            break
        if t > t9:
            print(line, end='')

datetime

>>> from datetime import datetime
>>> datetime.now()   # 返回当前的时间对象: 年,月,日,时,分,秒,毫>秒
datetime.datetime(2020, 3, 18, 10, 48, 16, 934977)
>>> t.year, t.month, t.day, t.hour, t.minute, t.second, t.microsecond
(2020, 3, 18, 10, 49, 16, 189267)
>>> t.strftime('%Y-%m-%d %H:%M:%S')   # 把datetime对象转成指定格式的字符串
'2020-03-18 10:49:16'
# 把字符串转成datetime对象
>>> datetime.strptime('2050-1-1 0:00:00', '%Y-%m-%d %H:%M:%S')
datetime.datetime(2050, 1, 1, 0, 0)

# 计算100天1小时之前、之后的时间
>>> from datetime import datetime, timedelta
>>> days = timedelta(days=100, hours=1)
>>> t = datetime.now()
>>> t + days
datetime.datetime(2020, 6, 26, 12, 19, 17, 90805)
>>> t - days
datetime.datetime(2019, 12, 9, 10, 19, 17, 90805)
  • 过滤日志文件
from datetime import datetime

logfile = 'mylog.log'
# 取出日志文件的每一行,判断时间,如果是9点到12点之间的,则打印
t9 = datetime.strptime('2019-05-15 09:00:00', '%Y-%m-%d %H:%M:%S')
t12 = datetime.strptime('2019-05-15 12:00:00', '%Y-%m-%d %H:%M:%S')

with open(logfile) as fobj:
    for line in fobj:
        t = datetime.strptime(line[:19], '%Y-%m-%d %H:%M:%S')
        if t > t12:
            break
        if t > t9:
            print(line, end='')

os

>>> os.getcwd()   # pwd
'/root/nsd2019/nsd1910/py02/day01'
>>> os.listdir()  # ls
>>> os.listdir('/tmp')  # ls /tmp
>>> os.mkdir('/tmp/demo')  # mkdir /tmp/demo
>>> os.mkdir('/tmp/nsd1910/demo')  # 报错,不能创建层级目录
>>> os.makedirs('/tmp/nsd1910/demo')  # mkdir -p /tmp/nsd1910/demo
>>> os.chdir('/tmp/demo')  # cd /tmp/demo
>>> os.environ['PATH']   # 取出环境变量PATH的值
'/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin:/root/bin'

>>> os.listdir()
[]
>>> import shutil
>>> shutil.copy('/etc/hosts', '.')
'./hosts'
>>> shutil.copytree('/etc/security', 'anquan')
'anquan'
>>> os.symlink('/etc/passwd', 'mima')  # ln -s /etc/passwd mima
>>> os.mknod('mytest')  # touch mytest
>>> os.listdir()
['hosts', 'anquan', 'mima', 'mytest']
>>> os.rename('mytest', 'mytest.txt')
>>> os.listdir()
['hosts', 'anquan', 'mima', 'mytest.txt']

# Linux的权限数字是8进制数
>>> os.chmod('hosts', 0o755)
>>> os.chmod('hosts', 0o644)
>>> shutil.rmtree('anquan')   # rm -rf anquan
>>> os.remove('hosts')        # rm -f hosts
>>> os.rmdir('/tmp/nsd1910/demo')   # 只能删除空目录
>>> os.stat('/etc/hosts')  # 查看文件状态,相当于 stat /etc/hosts
os.stat_result(st_mode=33188, st_ino=67160698, st_dev=64768, st_nlink=1, st_uid=0, st_gid=0, st_size=158, st_atime=1584492969, st_mtime=1370615492, st_ctime=1580547233)
>>> a = os.stat('/etc/hosts')
>>> a.st_size   # 取出文件大小的字节数
158

>>> os.listdir()
['mima', 'mytest.txt']
>>> os.path.abspath('mytest.txt')   # 返回绝对路径
'/tmp/demo/mytest.txt'
>>> os.path.basename('/tmp/demo/mytest.txt')  # 返回最右面一个/后面的内容
'mytest.txt'
>>> os.path.dirname('/tmp/demo/mytest.txt')  # 返回最右面一个/前面的内容
'/tmp/demo'
>>> os.path.split('/tmp/demo/mytest.txt')
('/tmp/demo', 'mytest.txt')
>>> os.path.join('/tmp/demo', 'mytest.txt')
'/tmp/demo/mytest.txt'
>>> os.path.splitext('hello.txt')  # 切出扩展名
('hello', '.txt')

>>> os.path.isabs('/sss/aaa/ccc/')  # 是绝路径的格式吗?
True
>>> os.path.isdir('/etc')   # 存在并且是目录吗?
True
>>> os.path.isfile('/etc')  # 存在并且是文件吗?
False
>>> os.path.islink('/etc/grub2.cfg')  # 存在并且是软链接吗?
True
>>> os.path.ismount('/')  # 存在并且是挂点吗?
True
>>> os.path.exists('/tmp/xyz.txt')  # 存在吗?
False
  • os.walk方法
[root@localhost demo] cp /etc/{hosts,passwd,issue} .
[root@localhost demo] touch aaa/{a,b,c}.txt
[root@localhost demo] touch bbb/{d,e}.doc
[root@localhost demo] touch ccc/{f,g}.jpg
[root@localhost demo] ls -R /tmp/demo/
/tmp/demo/:
aaa  bbb  ccc  hosts  issue  passwd

/tmp/demo/aaa:
a.txt  b.txt  c.txt

/tmp/demo/bbb:
d.doc  e.doc

/tmp/demo/ccc:
f.jpg  g.jpg

>>> list(os.walk('/tmp/demo'))
>>> a = list(os.walk('/tmp/demo'))
>>> len(a)
4
>>> a[0]
('/tmp/demo', ['aaa', 'bbb', 'ccc'], ['hosts', 'passwd', 'issue'])
>>> a[1]
('/tmp/demo/aaa', [], ['a.txt', 'b.txt', 'c.txt'])
>>> a[2]
('/tmp/demo/bbb', [], ['d.doc', 'e.doc'])
>>> a[3]
('/tmp/demo/ccc', [], ['f.jpg', 'g.jpg'])
# os.walk是由多个元组构成的
# 每个元组有三项: (路径字符串,该路径下目录列表,该路径下文件列表)
# 模拟ls -R
import os
for _path, _dir, _file in list(os.walk('/tmp/demo')):
    print(_path)
    for d in _dir:
        print('\033[34;1m%s\033[0m' % d, end='\t')
    for f in _file:
        print(f, end='\t')
    print('\n')
    
# 效果:
/tmp/demo:
aaa     bbb     ccc     hosts   passwd  issue

/tmp/demo/aaa:
a.txt   b.txt   c.txt

/tmp/demo/bbb:
d.doc   e.doc

/tmp/demo/ccc:
f.jpg   g.jpg

pickle

  • 普通的文件操作,只能把str或bytes类型数据写入文件
  • pickle模块可以把任意的数据类型存到文件中,还可以无损地取出来
>>> import pickle
>>> shopping_list = ['fbm', 'sj', 'pg']
>>> with open('/tmp/a.data', 'wb') as fobj:
...   pickle.dump(shopping_list, fobj)

>>> import pickle
>>> with open('/tmp/a.data', 'rb') as fobj:
...   l1 = pickle.load(fobj)
...
>>> type(l1)
<class 'list'>
>>> l1
['fbm', 'sj', 'pg']
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章