Python_模块

所谓的模块就是一个py文件,里面包含了各种各样的功能,分为:内置模块,扩展模块,自定义模块。

import模块的使用

模块的加载顺序:

现在运行的时候开辟一块全局命名空间,然后在导入的时候会先从上至下的读取import模块的内容,并开启一块新的命名空间(我个人称为模块空间),然后在全局引用的时候会将对象指向模块空间的值

import my_module,os

money = 10
# print(my_module.money)

# def read1():
#     print('=========')
# my_module.read1()
money =1
print(id(money))
my_module.change()      #内部含有money = 0
print(money,id(money))

模块的别名as

import my_module as my

需要注意:别名之后就不可以使用原来的模块名字了

使用场景:

#mysql.py
def sqlparse():
    print('from mysql sqlparse')
#oracle.py
def sqlparse():
    print('from oracle sqlparse')

db_type=input('>>: ')
if db_type == 'mysql':
    import mysql as db
elif db_type == 'oracle':
    import oracle as db

db.sqlparse() 

from … import…

from也是导入的作用,只不过要配合后面的import使用

常用功能是导入某一个模块下的某一个方法,如果是多个可以使用,(逗号)分割或者__all__

from my_module import (read1,read2)

也可以是所有,用import * 来表示

from my_module import *

注意:

* 把my_module中所有的不是以下划线(_)开头的名字都导入到当前位置,大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题。

在被导入的模块中加入就可以避免一些问题:

__all__=['money','read1']

模块的加载与修改

如果一个模块在执行的同时被修改了,那么还是会按照之前的原貌进行,因为加载的时候,会先从上至下执行一遍,然后加载到模块空间,随后的修改不会修改到内存中,如果想要实时生效可以使用reload

import time,importlib
import my_module

time.sleep(10)
# importlib.reload(my_module)               #打开注释,对比结果
my_module.read1()

模块查找范围(优先级)

在导入模块的时候,会先去检查这个模块是否被加载到内存中,如果已经没有,那么就去解释器中寻找,然后去sys.path路径中去依次寻找

内存中已经加载的模块->内置模块->sys.path路径中包含的模块

注意:

  1. py模块文件的命名规范与变量的命名规范一样,不能与内置模块重命名、不能数字开头、遵循PEP8规范
  2. sys.path的顺序是从左到右依次查找的,如果有zip压缩包会当成一个目录,(可以使用 sys.path.append(‘module.zip’) 添加)
  3. 至于.egg文件是由setuptools创建的包,这是按照第三方python库和扩展时使用的一种常见格式,.egg文件实际上只是添加了额外元数据(如版本号,依赖项等)的.zip文件。

序列化

把其他数据类型转换成字符串就是序列化;

序列化模块的三种类型:

json

优点:支持的语言种类非常多,C、C++、Java、Perl……,基本上所有语言都支持

缺点:支持的数据类型有限,只有 数字、字符串、列表、字典,不支持元组,文件序列化或者反序列化都只能一行一行,否则会取不出来

pickle

优点:支持Python语言中的所有格式,序列化默认是byte形式

缺点:只能在Python平台中使用;load的时候对象必须存在或者在内存里

shelve

Python 3.*新出的一种序列化模块

优点:提供了一个类似于非关系形的简单数据库,将序列化的结果直接保存到一个shelve文件里,可以方便的保存Python的内存对象,操作简单,字典方式读取,可以多人同时操作

缺点:新出的类型,在只读模式下有bug,依旧可以写入。不可以很多人同时操作

Json

import json

在网络中序列化:

dic  = {"IT小哲":(180,18,"Boy")}
ret = json.dumps(dic,ensure_ascii=False)
print('旧的类型',type(dic),'-'*20,repr(dic))
print('新的类型',type(ret),'-'*20,repr(ret))

res = json.loads(ret)
print('反序列化',type(res),'-'*20,repr(res))

在文件中序列化:

dic = {"IT小哲":(180,18,"Boy")}
f = open("IT小哲",'a',encoding='utf-8')
json.dump(dic,f,ensure_ascii=False)
f.close()

r = open("IT小哲",'r',encoding='utf-8')
res=json.load(r)
print(type(res),res)
输出带格式:
data = {'username':['李华','二愣子'],'sex':'male','age':18}
json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False)

print(json_dic2)
----

{
    "age":18,
    "sex":"male",
    "username":[
        "李华",
        "二愣子"
    ]
}

序列化多个:

默认序列化是在在一行的里面,如果需要序列化多个需要换行写入时加上\n

dic1 = {"IT小哲1":(180,18,"Boy")}
dic2 = {"IT小哲2":(180,18,"Boy")}
dic3 = {"IT小哲3":(180,18,"Boy")}

f = open("IT小哲",'a',encoding='utf-8')
str1 = json.dumps(dic1,ensure_ascii=False)
f.write(str1 + '\n')
str2 = json.dumps(dic2,ensure_ascii=False)
f.write(str2 + '\n')
str3 = json.dumps(dic3,ensure_ascii=False)
f.write(str3 + '\n')
f.close()

f= open("IT小哲",'r',encoding='utf-8')
for line in f:                                  #一般情况下读取文件最好是用for循环去迭代着读取,节省内存
    print(json.loads(line))
f.close()                                       #记得关闭文件

序列化的四种的方法:

dumps是直接序列化到文件 dump是序列到内存

loads反序列化文件 load反序列化内存

pickle

单行:

import pickle

dic1 = {(180,18,'Boy'):'IT小哲1'}
# dic2 = {"IT小哲2":(180,18,"Boy")}
# dic3 = {"IT小哲3":(180,18,"Boy")}

ret = pickle.dumps(dic1)
print(ret)

Read =pickle.loads(ret)
print(Read)

多行:

import pickle

dic1 = {'IT小哲1':(180,18,'Boy')}
dic2 = {"IT小哲2":(180,18,"Boy")}
dic3 = {"IT小哲3":(180,18,"Boy")}

f = open("IT小哲",'ab')
pickle.dump(dic1,f)
pickle.dump(dic2,f)
pickle.dump(dic3,f)

多行读取:

f = open("IT小哲",'rb')
ret = pickle.load(f)
ret1 = pickle.load(f)
ret2 = pickle.load(f)
print(ret1,ret2,ret)

while True:
    try:
        print(pickle.load(f))
    except EOFError:
        break

序列化类:

class A:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return '格式化输出'
a = A('alex',80)

# ret = pickle.dumps(a)
# print(ret)
# obj = pickle.loads(ret)
# print(obj.__dict__)

import json
b=json.dumps(a.__dict__)    
print(b)
c=json.loads(b)
print(c)

因json格式只能接受字典、列表、数字、字符串,所以直接序列化对象会报错

hashlib摘要算法:

将可hash(不可变)的数据类型转换成数字,一般用于加密和校验,有两种方法:md5和SHA

SHA它拥有更多的级别,相比于MD5更加安全,但是他在加密的时候占用的CPU资源比MD5更高,MD5是早期的一个校验方法、相比于sha更加更加节省性能,但缺点就是没有sha安全

import hashlib

m = hashlib.md5()
m.update('ITzhe'.encode('utf-8'))
print(m.hexdigest())

或者 字节形式加密

m = hashlib.md5()
m.update(b'ITzhe')
print(m.hexdigest())

加盐

m = hashlib.md5('IT-Boy'.encode('utf-8'))
m.update('ITzhe'.encode('utf-8'))
print(m.hexdigest())

动态加盐

username = input('输入用户名>>>')
m = hashlib.md5('username'.encode('utf-8'))
m.update('ITzhe'.encode('utf-8'))
print(m.hexdigest())

对多行进行加密

import hashlib
m = hashlib.md5(b'ITzhe')               #盐
m.update(b'123')
m.update(b'456')
m.update(b'789')
print(m.hexdigest())

如果是多行加密,最后的结果是一样的

对不可读文件(电影、图片)校验

def check(filename):
    md5obj = hashlib.md5()
    with open(filename,'rb') as f:
        while True:
            Read = f.read(1024)
            if Read:
                md5obj.update(Read)
            else:
                break
    return md5obj.hexdigest()

File = check('IT小哲')
print(File)

电影、图片没有行的概念,只有二进制的字节、所以每次读取1024个字节

SHA的加密算法和MD5是一样的,只不过把MD5换成SHA1即可

configparser 配置模块

生成配置文件

import configparser

config = configparser.ConfigParser()
config["DEFAULT"] = {'A':45,                                #给[DEFAULT]节 添加内容
                      'Compression': 'yes',                 
                     'CompressionLevel': '9',
                     'ForwardX11':'yes'
                     }

config['module-1'] = {'user':'root'}
config['module-2'] = {'Host Port':'50022','ForwardX11':'no'}
with open('test.conf','w') as f:
    config.write(f)
-------------------------------------------------------------
[DEFAULT]                                                   #节
forwardx11 = yes                                            #项
a = 45
compression = yes
compressionlevel = 9

[module-1]
user = root

[module-2]
forwardx11 = no
host port = 50022

取值

config = configparser.ConfigParser()
config.read('test.conf')

#查看节,不包含default
print(config.sections())        #['module-1', 'module-2']

#查看节是否在文件里
print('module-1' in config)     #True
print('module-3' in config)     #False

#查看节下面的某项
print(config['module-1']['user']    #root

#如果是取某个节的所有值:
print(config['DEFAULT'])
for key in config['module-1']:
    print(key)
#或者
print(config.options('module-1'))

#打印某节下面的所有值,以字典形式
print(config.items('module-1'))

#以字典key形式取值value
print(config.get('module-1','user'))    

#重新写入
config.write(open('new2.ini', "w"))

注意:

  1. 必须要有[DEFAULT]节
  2. 默认是小写(不管是不是ini格式)

logging 日志模块

简单配置

import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %y %H:%M:%S',
                    filename = 'log'
                    )

logging.debug('debug message')          # debug 调试模式 级别最低
logging.info('info message')            # info  显示正常信息
logging.warning('warning message')      # warning 显示警告信息
logging.error('error message')          # error 显示错误信息
logging.critical('critical message')

优点:使用简单

缺点:format会中文乱码,不能同时输出到文件和屏幕

配置logger对象

import logging
#实例化一个获取日志的对象叫做logger
logger = logging.getLogger()

#得到文件句柄
fh = logging.FileHandler('test.log',encoding='utf-8')
#设置时间格式
fmt = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
#将格式赋给文件句柄(关联)
fh.setFormatter(fmt)
#给loger这个对象添加一个管理者,并将fh文件句柄传给logger
logger.addHandler(fh)
#设置loger的日志级别(全局)
logger.setLevel(logging.DEBUG)

logger.debug('debug message')       # debug 调试模式 级别最低
logger.info('info message')         # info  显示正常信息
logger.warning('warning message')   # warning 显示警告信息
logger.error('error message')       # error 显示错误信息
logger.critical('critical message')

输出到屏幕:

pm = logging.StreamHandler()
fmt = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s' )
pm.setFormatter(fmt)
logger.addHandler(pm)

优点:不受编码的影响,可以指定字符集,可以同时输出到屏幕和日志

缺点:相比于简单配置相对于复杂,需要先实例化对象、然后得到文件句柄,然后格式化再关联

collections队列模块

deque双端队列

默认队列是从右边添加的,用 deque可以从左边添加、删除等操作

from collections import deque

dq =deque()
dq.append(1)
dq.append(2)
dq.append(3)
dq.appendleft(4)
print(dq)
#从右边删除
print(dq.pop())
#从左边删除
print(dq.popleft())

OrderedDict

创建字典可以按照你指的的排序

from collections import OrderedDict

dic = OrderedDict([('k1','v1'),('k3','v3'),('k2','v2')])
print(dic)

time时间模块

格式化时间

print(time.strftime('%Y-%m-%d'))
print(time.strftime('%H:%M:%S'))
print(time.strftime('%x'))
print(time.strftime('%X'))
print(time.strftime('%c'))

时间戳时间

print(time.time())

结构化时间

print(time.localtime())

三种格式的转换

结构化时间 ==》时间戳localtime()

print(time.localtime(1500000000))

时间戳 ==》结构化时间 time.mktime()

print(time.mktime(time.localtime(1500000000)))

结构化时间 ==》字符串时间 time.strftime()

ret = time.localtime(0)
#print(ret)
print(time.strftime('%Y-%m-%d %H:%M:%S',ret))

结构化时间《== 字符串时间 time.strptime()

ret = time.localtime(2000000000)
#print(ret)
print(time.asctime(ret))

random 随机

import random

小数

print(random.uniform(1,10))

整数

print(random.randint(1,5))          #包含1,5
print(random.randrange(1,3))        #不包含3
print(random.randrange(1,10,2))        #步长

print(random.choice([1,'88',[6,9]]))    #随机一个元素
print(random.sample([1,'88',[6,9]],2))  #返回随机两个元素

打乱列表

item = [1,3,4,6,7,9]
random.shuffle(item)
print(item)

生成验证码:

ret =(random.randint(100000,999999))
m = hashlib.md5()
m.update(str(ret).encode('utf-8'))      #对象必须先转换成str
a=m.hexdigest()
print(a[:5])

sys Python解释器模块

import sys

退出方法,()不写默认是0,如果有报错就可以指定数字

print('#'*6)
sys.exit(0)
print('-'*6)

显示Python版本

print(sys.version)

显示系统位数

print(sys.platform)

显示系统路径

print(sys.path)

sys.argv就是将程序本身和给程序参数返回一个list,会打印文件本身的名字和所在路径

print(sys.argv)

默认是返回文件名和路径名的列表,如果在列表添加内容,argv会接受参数传给列表,并且[1] [2] [3]依次排序,[0]是文件本身

if sys.argv[1] == 'Zhe' and sys.argv[2] == '3714':
    print('登陆成功')
else:
    sys.exit(403)
print('我能完成的功能')

可以配合os模块进行系统命令的调用

import os
os.system("echo 111")

OS模块

os.system("bash command")   运行shell命令,直接显示,执行成功会返回状态码0
os.popen("bash command).read()  运行shell命令,获取执行结果,而且会多返回一个换行符
os.environ                  获取系统环境变量


os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd
os.curdir                   返回当前目录: ('.')
os.pardir                   获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')        可生成多层递归目录
os.removedirs('dirname1')               若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')                     生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')                     删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')                   列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()                             删除一个文件
os.rename("oldname","newname")          重命名文件/目录
os.stat('path/filename')                获取文件/目录信息

os.sep                      输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep                  输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep                  输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name                     输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

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所指向的文件或者目录的最后修改时间
os.path.getsize(path)       返回path的大小

optparse模块

相比于sys模块,optparse更加清晰

from optparse import OptionParser

class OP:
    def __init__(self):
        parser = OptionParser()
        parser.add_option("-s", "--server", dest="server", help="ftp server ip_address")
        parser.add_option("-P", "--port", type="int", dest="port", help="ftp server port")
        parser.add_option("-u", "--username", dest="username", help="username info")
        parser.add_option("-p", "--password", dest="password", help="password info")

        self.options,self.args = parser.parse_args()

    def run(self):
        if not self.options or not self.args:
            exit("ERROR")

if __name__ == '__main__':
    op = OP()
    op.run()

执行效果:

python tests.py -s 192.168.1.1 -P 22 -u amdin -p 123456 QQ

参考链接

paramiko


import paramiko

ssh = paramiko.SSHClient()

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

ssh.connect(hostname='192.168.56.11',port=22,username='root',password='123456')

stdin,stdout,stderr = ssh.exec_command("df -h")

result = stdout.read().decode("utf-8")
print(result)

ssh.close()

https://www.cnblogs.com/hwlong/p/9126281.html

发表评论