PyStudyModule1

Pymodulestudy

1.inspect模块

函数注解中需要做位置参数的判断,无法和字典对应时,使用inspect模块,其提供获取对象的信息的函数,可以检查函数和类、类型检查

(1)signature

(callable),获取签名(函数签名包含了函数名参数类型所在的类名称空间其他信息判断函数需要传入几个参数可以使用inspect.signature

import inspect
def add(x: int, y: int, *args, **kwargs) ->int:return x - y
sig = inspect.signature(add)
print(sig, type(sig))
print(0, sig.parameters)
for i, item in enumerate(sig.parameters.items()):name, param = itemprint(i + 1, name, param.annotation, param.kind, param.default)
1 x  POSITIONAL_OR_KEYWORD 
2 y  POSITIONAL_OR_KEYWORD 
3 args  VAR_POSITIONAL 
4 kwargs  VAR_KEYWORD 
print(1, sig.return_annotation)
print(2, sig.parameters['y'].annotation)
print(3, sig.parameters['args'])
print(4, sig.parameters['args'].annotation)
print(5, sig.parameters['kwargs'])
print(6, sig.parameters['kwargs'].annotation)
(x:int, y:int, *args, **kwargs) -> int 
output:
0 OrderedDict([('x', ), ('y', ), ('args', ), ('kwargs', )])
1 
2 
3 *args
4 
5 **kwargs
6 

(2)方法

inspect.isfunction(add)
inspect.ismethod(add)                # 是否是类的方法
inspect.isgenerator(add)             # 是否是生成器对象
inspect.isgeneratorfunction(add)     # 是否生成器函数
inspect.isbuiltin(print)             # 是否内建对象
inspect.ismodule(print) 
inspect.isclass(print)

(3)Parameter对象

parameter保存在元组中,只读,name:参数名;annotation:参数注解,可能没定义;default:参数缺省值,可能没定义;empty:特殊的类,用来标记default属性或注释annotation属性的空值;kind:实参如何绑定到形参,就是形参大的类型

POSITONAL_ONLY    值必须是位置参数提供
VAR_POSITIONAL    值作为关键字或位置参数提供
VAR_POSIOTN       可变位置参数,*args
KEYWORD_ONLY      keyword-only参数
VAR_KEYWORD       可变关键字参数,**kwargs
def check(fn):def wrapper(*args, **kwargs):sig = inspect.signature(fn)params = sig.parameters      #有序字典 {变量名:参数对象}values = tuple(params.values())
#         print(0, values)for i, j in enumerate(args): #(4, 5) 要检查的参数子在args里面,要迭代它if isinstance(j, values[i].annotation):
#                 print(values[i].annotation)print('=-=-=-=-=')else:print('=!=!=!=!=')for k, v in kwargs.items():print(k, v)if isinstance(v, params[k].annotation): #params[k]有序字典用key获取valueprint(params[k].annotation)print('=-=-=-=-=')else:print('=!=!=!=!=')return fn(*args, **kwargs)return wrapper
@check     #add = check(add)
def add(x:int, y: int=7) ->int:return x, y
# add(4, 5)
# add(4, y=5)
# add(x=4, y=5)
add(4, 'a')
=-=-=-=-=
=!=!=!=!=
Out[73]:
(4, 'a')
-------------------------------------------------------------------
# 检查输入的参数类型是否为要求类型
def check(fn):def wrapper(*args, **kwargs):sig = inspect.signature(fn)params = sig.parameters      #有序字典 {变量名:参数对象}values = tuple(params.values())print(0, values)for i, j in enumerate(args): #(4, 5) 要检查的参数子在args里面,要迭代它print(i, j)if values[i].annotation != inspect._empty and not isinstance(j, values[i].annotation):
#                 print(values[i].annotation)print(j, '=!=!=!=!=')for k, v in kwargs.items():
#             print(k, v)    # y:'5'if params[k].annotation != params[k].empty and not isinstance(v, params[k].annotation):
#                 print(params[k].annotation) inspect._empty == params[k].empty == inspect.Paramter.emptyprint(v, '=!=!=!=!=')return fn(*args, **kwargs)return wrapper
@check     #add = check(add)
def add(x, y: int=7) ->int:return x, y
# add(4, 5)
# add(4, y=5)
# add(x=4, y=5)
add('a', y='5')
0 (, )
0 a
5 =!=!=!=!=
Out[67]:
('a', '5')

2.functools模块

(1)reduce

reduce 数据减少,可迭代对象不能为空,初始值没提供就在可迭代对象中区一个元素

reduce(function, sequence[, initial]) -> value
import functools
def fn(x):print(x)print(y)print('-' * 10)return x + y
functools.reduce(fn, range(1, 4))
1 2
----------
3 3
----------
6
functools.reduce(lambda x, y: x + y, range(5, 10), 100)      # 原来以5开头,换成以100开头
135
functools.reduce(lambda x, y: x * y, range(1, 6))             # 阶乘
120

(3)partial

partial 偏函数,把函数部分的参数固定下来,为部分的参数添加了一个固定的默认值,形成一个新的函数并返回;行partial生成的新函数,是对原函数的封装

f = functools.partial(func, *args, **keywords)
import functools
import inspect
def add(x, y):return x + y
add1 = functools.partial(add, 4)
add1(5)
9
id(add), id(add1)
(2212138548760, 2212138584728)
inspect.signature(add1)

add2 = functools.partial(add, x=5)
inspect.signature(add2)

add2(x=2, y=3)
add3 = functools.partial(add, 4, 5)
functools.partial(, 4, 5)
inspect.signature(add3)

add3()
9
add3(1)       #报错def add(x, y, *args):print(x, y)print(args)return x + y
add4 = functools.partial(add, 1, 2, 3, 4)
add('a', 'b')
a b
()
Out[44]:
'ab'
inspect.signature(add4)
#原理
import functools
import inspect
def add(x, y):print(x, y)return x + y
add1 = functools.partial(add, 1, y=5)
def partial(func, *args, **keywords):def newfunc(*fargs, **fkeywords):newkeywords = keywords.copy()newkeywords.update(fkeywords)  # {'x':5, 'y':5} return func(*args, *fargs, **newkeywords) # add(1, 4, x=5, y=5)newfunc.func = funcnewfunc.keywords = keywordsreturn newfunc
add1.func, add1.args, add1.keywords
(, (1,), {'y': 5})
add1()
1 5
6
add1(4,x=5)       #报错

(4)缓存

@functools.lru.cathe(maxsize=128,type=False),maxsize为None时,禁用LRU,缓存可无限增长;maxsize是二的幂时,LRU功能执行的最好;type设置为True时,不同类型的函数参数将单独缓存

import time
import functools
@functools.lru_cache()
def add(x, y):time.sleep(2)return x + y
key1 = functools._make_key((), {'x':1, 'y':2}, False)
t1 = tuple(key1)
print(t1)
print(hash(t1))
print(key1.hashvalue)
functools.partial
#使用前提:(1)同样的函数参数一定得到同样的结果(2)函数执行过长,执行多次
本质:函数调用的参数==>返回值
缺点:不支持缓存过期,key无法过期、失效;不支持清除操作;不支持分布式,是一个单机的缓存
适用:需要时间换空间的时候

3.io模块

os模块操作和返回路径全是字符串类型

(1)StringIO

io模块中的类,临时的存放文本的buff,可以像文件一样操作它,当close方法被调用的时候,buff 会被释放

getvalue()获取全部内容,和文件没关系

from io import StringIO
sio = StringIO()  # 内存中的构建和操作
print(sio.readable(), sio.writable(), sio.seekable())
sio.write('gg\njava00')
print(sio.readline())
print(sio.getvalue())  # 无视指针,输出全内容
sio.close()
True True True
gg
java00

(2)ByteIO

pio模块中的类,内存空开辟的一个二进制模式的buff,可以像文件一样操作它,close() 方法被调用时,buff会被释放

from io import BytesIO
bio = StringIO()  # 内存中的构建和操作
print(bio.readable(), bio.writable(), bio.seekable())
bio.write('gg\njava00')
print(bio.readline())
print(bio.getvalue())  # 无视指针,输出全内容
bio.close()
True True True
gg
java00

(3)file-like对象

类文件对象,可以向文件对象一样操作它

socket文件对象、输入输出对象(stdin、stdout)都是类文件对象

from sys import stdout, stderr
f = stdout
print(type(f))
# f.write('pyton java')

4.pathlib模块

(1)使用pathlib模块,用path对象来操作文件和目录

from pathlib import Path
p = Path()
pathlib.Path
p = Path('a', 'b', 'c/d')
PosixPath('a/b/c/d')
p = Path('/etc')
PosixPath('/etc')

(2)路径拼接和分解

操作符:Path对象 / Path对象,Path对象 / 字符串或者字符串 / Path对象

分解:parts属性,可以返回路径中的一部分

joinpath(*other) 连接多个字符串到Path中,str获取路径的字符串,bytes获取路径字符串的bytes

P = Path()
p
PosixPath('.')
p = p / 'a'
p
PosixPath('.')
p1 = 'b' / p
p1
PosixPath('b/a')
p2 = Path('c')
p3 = p2 / p1
PosixPath('c/b/a')
print(p3.parts)
('c', 'b', 'a')
p3.joinpath('python', 'java', 'golang')
PosixPath('c/b/a/python/java/golang')p1 = Path('q/w/e/r')
print(str(p1), bytes(p1))
q/w/e/r b'q/w/e/r'

(3)目录

parent 目录的逻辑父目录,parents父目录序列,可迭代对象,索引0是直接的父

In [19]: p = Path('/a/b/c/d')
In [20]: print(p.parent)
/a/b/c
In [21]: print(p.parent.parent)
/a/b
In [22]: print(p.parents)      # 惰性的

In [23]: for x in p.parents:...:     print(x)...:
/a/b/c
/a/b
/a
/

目录的组成:

name:目录的最后一个部分

suffix:目录最后一个部分的扩展名,suffix返回多个扩展名列表

stem:目录的最后一个部分,没有后缀

name = stem + suffix

with_suffix(suffix):有扩展名替换,无则补充扩展名

with_name(name):替换最后一个部分并返回一个新的路径

p = Path('hello/java/python/php')
p.name
Out[31]: 'php'
p.suffix
Out[32]: ''
p = Path('hello/java/python/php/java.jar.gz')
In [35]: p.suffix
Out[35]: '.gz'
In [36]: p.name
Out[36]: 'java.jar.gz'
In [37]: p.stem
Out[37]: 'java.jar'
In [38]: p.with_name('java.tar')
Out[38]: PosixPath('hello/java/python/php/java.tar')
In [40]: p.with_suffix('.py')
Out[40]: PosixPath('hello/java/python/php/java.jar.py')
In [41]: p = Path('jj')
In [42]: p.with_suffix('.txt')
Out[43]: PosixPath('jj.txt')

(4)方法

1)全局方法

cwd() 返回当前工作目录,home() 返回当前家目录

2)判断方法
is_dir() 是否是目录,存在返回True
is_file() 是否是普通文件,文件存在返回True
is_symlink() 是否是软链接
is_socket() 是否是socke()文件
is_block_device() 是否块设备
is_char_device()  是否字符设备
is_absolute()  是否是绝对路径
resolve()  返回一个新的路径(当前Path对象的绝对路径),若是软链接直接被解析
absolute()   获取绝对路径
exist()  目录或文件不存在
rmdir() 删除空目录,没提供判断目录为空的方法
touch(mode=666, exist_ok=True)  创建一个新文件
as_url()  将新的绝对路径返回成URL,eg:'file:///etc/haha'
mkdir(mode=777, parents=False, exist_ok=False)
parents,是否创建父目录,True等于mkdir -p;False时目录不存在,抛异常;exist_ok参数,python3.5加入,False时,路径存在,抛异常FileExistsError;True时,FileExistsError被忽略
iterdir() 迭代当前目录,不递归
In [27]: p = Path()
In [28]: p /= 'a/b/c'
In [29]: p
Out[29]: PosixPath('a/b/c')
In [30]: p.exists()
p.mkdir() # FileNotFoundError
In [36]: p.mkdir(parents=True)
(py36) [Iverson@Linux mz]$ ls
a
# 创建目录
p.mkdir() # FileNotFoundError
p.mkdir(parents=True)
p.exists() # True
p.mkdir(parents=True)
p.mkdir(parents=True,exist_ok=True)
p /= 'readme.txt'
p.parent.rmdir() #
p.parent.exists() # False '/a/b/c'
p.mkdir() # FileNotFoundError
p.mkdir(parents=True) # 成功# 遍历,并判断文件类型,如果是目录是否可以判断其是否为空目录?
for x in p.parents[len(p.parents)-1].iterdir():print(x, end='\t')if x.is_dir():flag = Falsefor _ in x.iterdir():flag = Truebreakprint('dir','Not Empty' if flag else 'Empyt',sep='\t')elif x.is_file():print('file')else:print('other file')
.python-version	file

(5)通配符

1)globe(pattern)

通配给定的模式;rglob(patter) 通配给定的模式,递归目录,都**返回生成器**

?代表一个字符,*表示任意字符,[abc]或[a-z] 表示一个字符

In [74]: p = Path()
In [75]: p
Out[75]: PosixPath('.')
In [77]: p.glob('test*')         # 生成器
Out[77]: 
In [78]: next(p.glob('test*'))
Out[78]: PosixPath('test.py')
In [79]: list(p.glob('test*'))        # 返回当前目录对象下的test开头的文件
Out[79]: [PosixPath('test.py')]
In [80]: list(p.glob('**/*.py'))   # 递归所有目录,等同rglob
Out[80]: [PosixPath('f.py'), PosixPath('hehe.py'), PosixPath('test.py')]
In [81]: g = p.rglob('*.py')     # 生成器,递归
In [82]: g
Out[82]: 
In [83]: next(g)
Out[83]: PosixPath('f.py')
In [84]: next(g)
Out[84]: PosixPath('hehe.py')
In [85]: next(g)
Out[85]: PosixPath('test.py')
In [87]: list(p.rglob('*.???'))           # 匹配扩展名为3个字符的文件 
Out[87]: [PosixPath('hahatest.txt')]
In [92]: list(p.rglob('[a-z]*.???'))                # 匹配字母开头的且扩展名是3个字符的文件
Out[92]: [PosixPath('hahatest.txt'), PosixPath('pyt.txt')]
2)match(pattern)

模式匹配,成功返回True

In [93]: Path('a/b.py').match('*.py')
Out[93]: True
Path('a/b.py').match('*.py') # True
Path('/a/b/c.py').match('b/*.py') # True
Path('/a/b/c.py').match('a/*.py') # False
Path('/a/b/c.py').match('a/*/*.py') # True
Path('/a/b/c.py').match('a/**/*.py') # True
Path('/a/b/c.py').match('**/*.py') # True
3)stat()

相当于stat命令;lstat() 同stat,但如果时符号链接,显示符号链接本身文件信息

(py36) [Iverson@Linux b]$ ls t
t
(py36) [Iverson@Linux b]$ ll t
lrwxrwxrwx. 1 Iverson Iverson 4 Jan 26 22:35 t -> f.pyfrom pathlib import Path
p = Path('f.py')
p.stat()
Out[100]: os.stat_result(st_mode=33204, st_ino=26988122, st_dev=2050, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=1548512068, st_mtime=1548512068, st_ctime=1548512068)p1 = Path('t')
p1.stat()
Out[102]: os.stat_result(st_mode=33204, st_ino=26988122, st_dev=2050, st_nlink=1, st_uid=1000, st_gid=1000, st_size=0, st_atime=1548512068, st_mtime=1548512068, st_ctime=1548512068)p1.lstat()
Out[103]: os.stat_result(st_mode=41471, st_ino=26988148, st_dev=2050, st_nlink=1, st_uid=1000, st_gid=1000, st_size=4, st_atime=1548513320, st_mtime=1548513318, st_ctime=1548513318)

(6)文件操作

1)Path.open(mode='r', buffering=1, encoding=None, errors=Nonr, newline=None) 类似内建函数open。返回一个文件对象

2)Path.read_bytes() 以'rb'读取路径对应文件,并返回二进制流

3)Path.read_text(encoding=None, errors=None) 'rt'方式读取路径对应文件,返回文本

4)Path.write_bytes(data) 以'wb'方式写入数据到路径对应文件

5)Path.write_text(data, encoding=None, errors=None) 以'wt'方式写入字符串到路径对应文件

In [104]: p = Path('python java and javascript')
In [105]: p.write_bytes(b'golang')
Out[105]: 6
In [106]: p.read_bytes()
Out[106]: b'golang'
In [107]: p = Path('python java and javascript')
In [108]: p.write_text('golang')
Out[108]: 6
In [109]: p.read_text()
Out[109]: 'golang'from pathlib import Path
In [115]: p = Path('test.py')
In [116]: p.write_text('hello python')
Out[116]: 12
In [117]: print(p.read_text())
hello python
In [118]: with p.open() as f:...:     print(f.read(5))...:
hello

4.OS模块

操作系统平台

(1)属性

os.name windows是nt,linux是posix;os.uname() unix支持;sysplatform windows显示32,linux显示linux

from os import path
p = path.join('hello', 'java', 'python')
print(type(p), p)
print(path.exists(p))
print(path.split(p))
print(path.abspath('.'))
 hello/java/python
False
('hello/java', 'python')
/home/Iverson/py368/mz
上面linux
下面windows
p = path.join('d:/', p, 'first.py')
print(path.dirname(p))
print(path.basename(p))
print(path.splitdrive(p)) # windows下的方法
d:/hello\java\python
first.py
('d:', '/hello\\java\\python\\first.py')p0 = 'c://python/java'
path.abspath(p1)
'/home/Iverson/py368/mz/c:/python/java'from os import path
print(os.path.dirname(__file__))
D:/python-code/hwork/fileio
print(os.path.abspath(__file__))
D:\python-code\hwork\fileio\findwords1.py
p1 = 'c:/python/java/javascript'
print(p1, path.basename(p1))
while p1 != path.dirname(p1):p1 = path.dirname(p)print(p1, path.basename(p1))
c:/python/java/javascript javascript
c:/python/java java
c:/python python
c: c:

(2)方法

os.listdir('l路径名') 返回指定目录内容列表,不递归

os也有open、read、write等,可直接使用内建函数open、read、write

os.stat(path, *, dir_fd=None, follow_sysmlink=True) 本质上使用linux的stat

path:路径的string或bytes,或文件描述符

follow_sysmlink True 显示文本信息,False且如果时软连接显示本身,对于软连接可以使用os.lstat()

os.chmod('path, mode, *, dir_fd=None, follow_sysmlink=True)

os.chmod('haha.txt', 0o777)

os.chown(path, uid, gid)

5.shutil模块

shutil是一个高级文件操作的库,可以避免copy文件丢失文件数据信息(权限等)。

(1)copy

copyfileobj(fsrc, fdsc[, length]) 文件对象的复制,fsrc指定和fdst是open打开的文件对象,复制内容。fdst要求可写,length指定了表示buffer的大小

copyfile(src, dst, *, follow_symlinks=True) src、dst为文件的路径字符串

以上均仅仅copy文件内容,元信息不能copy到目标文件

copymode(src, dst, *, follow_symlinks=True) 仅仅复制权限

copystat(src, dst, *, follow_symlinks=True) 复制元数据,stat包含权限

copy(src, dst, *, follow_symlinks=True) 复制文件内容、权限和部分元数据,不包括创建时间和修改时间

opy2 比copy多了复制全部元数据,但需要平台支持

import shutil
with open('d:/nfile/test.txt', 'a+') as f:f.write('who are you?')f.flush()f.seek(0)                          # 不加seek会copy不到内容,因为文件指针已经指到EOFwith open('d:/nfile/test0.txt', 'w+') as f1:shutil.copyfileobj(f, f1)shutil.copyfile('d:/nfile/test.txt', 'd:/nfile/test0.txt')
shutil.copymode('d:/nfile/test.txt', 'd:/nfile/test0.txt')

copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) 递归复制目录。默认使用copy2,也就是带更多的元数据复制。 src、dst必须是目录,src必须存在,dst必须不存在。ignore = func ,提供一个callable(src, names) -> ignored_names,提供一个函数,它会被调用。src是源目录, names是os.listdir(src)的结果,就是列出src中的文件名,返回值是要被过滤的文件名的set类型数据

import shutil
import os
from pathlib import Pathp = Path('d:/nfile/a/b/c/d')
p1 = p / 'test.txt'
p1.mkdir(parents=True, exist_ok=True)
p1.touch()
dst = Path('d:/nfile/target/a')
src = p.parents[len(p.parents) - 2]
print(len(p.parents) - 2)
print(type(src))
print(os.listdir(src))
def ignore(src, names):print(src, names)# lst = []# for name in names:#     if name.endswith('txt'):#         lst.append(name)# g = filter(lambda x: x.endswith('txt'), names)# {name for name in names if name.endswith('txt')}return set(filter(lambda x: x.endswith('txt'), names))
shutil.copytree(str(src), str(dst), ignore=ignore, copy_function=shutil.copy) # copy_function=shutil.copy 只带mode
              # p.parents不可迭代,但可索引
3

['a', 'sample.txt', 'test.csv', 'test.txt', 'test0.txt', 'test0.txt.bak', 'test1.txt', 'test1.txt.bak', 'test2.txt', 'xuliehua']

(2)rm

shutil.rmtree(path, ignore_errors=False, οnerrοr=None) 如同rm -rf 递归删除,ignore_errors为True,忽略错误,为False或者omitted时onerror生效,onerror为callable,接受函数function、path和execinfo

shutil.rmtree('c:/tmp') # 类似 rm -rf

(3)move

move(src, dst, copy_function=copy2) 递归移动文件、目录到目标,返回目标。 本身使用的是 os.rename方法。 如果不支持rename,如果是目录则copytree再删除源目录。 默认使用copy2方法。

os.rename('c:/t.txt','o:/temp/t')
os.rename('test3','/tmp/py/gg.txt')

shutil还有打包功能。生成tar并压缩。支持zip、gz、bz、xz。

6.csv模块

csv:被行分隔符、列分隔符分成行和列的文本文件。不指定字符编码,行分隔符为\r\n,最后一行可以没有换行符,列分隔符为逗号或制表符

read(csvfile, dialect='excel', **fmtparams) fanhuiread对象,是一个行迭代器

write(csvfile, dialect='excel', **fmtparams) 返回DictWriter的实例,主要方法有writerow、writerows; writerow(iterable)

import csv
from pathlib import Path
p = Path('d:/nfile/test.csv')
with open(str(p)) as f:reader = csv.reader(f)print(next(reader))print(next(reader))for line in reader:print(line)
['num', ' name', ' age', ' comment']
['1', ' jama', ' 21', " 'shadadiao'"]
['2', ' feiwu', ' 32', " 'I'm nice boy'"]
['3', ' pig', ' 89', ' "1abv']
['2xyz"']
rows = [[4,'rose',22,'tom'],(5,'jack',24,'jerry'),(6,'justforyou',22,'just\t"in'),"qwerwrw",((1,),(2,))]
row = rows[0]
with open(str(p), 'a') as f:writer = csv.writer(f)writer.writerow(row)writer.writerows(rows)

7.configparser模块

configparser模块的ConfigParser类就是用来操作。 可以将section当做key,section存储着键值对组成的字典,可以把ini配置文件当做一个嵌套的字典。默认使用的 是有序字典。

read(filenames, encoding=None) 读取ini文件,可以是单个文件,也可以是文件列表。可以指定文件编码。

sections() 返回section列表。缺省section不包括在内。

add_section(section_name) 增加一个section。

has_section(section_name) 判断section是否存在 options(section) 返回section的所有option,会追加缺省section的option has_option(section, option) 判断section是否存在这个option

get(section, option, *, raw=False, vars=None[, fallback]) 从指定的段的选项上取值,如果找到返回,如果没有找到就去找DEFAULT段有没有。

getint(section, option, *, raw=False, vars=None[, fallback])

getfloat(section, option, *, raw=False, vars=None[, fallback])

getboolean(section, option, *, raw=False, vars=None[, fallback]) 上面3个方法和get一样,返回指定类型数据。 items(raw=False, vars=None)

items(section, raw=False, vars=None) 没有section,则返回所有section名字及其对象;如果指定section,则返回这个指定的section的键值对组成二元 组。

set(section, option, value) section存在的情况下,写入option=value,要求option、value必须是字符串。 remove_section(section) 移除section及其所有option

remove_option(section, option) 移除section下的option。

write(fileobject, space_around_delimiters=True) 将当前config的所有内容写入fileobject中,一般open函数使用w模式

from configparser import ConfigParser
file = 'test.ini'
newfile = 'sql.ini'
cfg = ConfigParser()
read_ok = cfg.read(file)
print(read_ok)     # ini name
print(cfg.sections())    # [DEFAULT]不打印
print(cfg.has_section('client'))
['test.ini']
['mysql', 'mysqld']
Falsefor k, v in cfg.items():print(k, type(k))print(v, type(v))print(cfg.items(k))print()
DEFAULT     # 字典套字典  DEFAULT mysql mysqld为键, ini下具体配置为值(键值对)
 
[('a', 'test')]mysql 
 
[('a', 'test'), ('default-character-set', 'utf8')]mysqld    #  'default-character-set', 'utf8'没打印
 
[('a', 'test'), ('datadir', '/dbserver/data'), ('port', '33060'), ('character-set-server', 'utf8'), ('sql_mode', 'NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES')]for k, v in cfg.items('mysqld'):   # 就是字典print(k, type(k))print(v, type(v))print()
a 
test datadir 
/dbserver/data port 
33060 character-set-server 
utf8 sql_mode 
NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES tmp = cfg.get('mysqld', 'port')
print(type(tmp), tmp)
print(cfg.get('mysqld', 'a'))
 33060                  # str
testprint(cfg.get('mysqld', 'GG', fallback='python'))  # 缺省值
pythontmp = cfg.getint('mysqld', 'port')
print(type(tmp), tmp)
 33060if cfg.has_section('test'):cfg.remove_section('test')
cfg.add_section('test')
cfg.set('test', 'test1', '1')
cfg.set('test', 'test2', '2')
with open(newfile, 'w') as f:cfg.write(f)
cfg['test']['x'] = '100' # key不存在
cfg['test2'] = {'test2': '1000'} # section不存在
print('x' in cfg['test'])
print('x' in cfg['test2'])
True
Falseprint(cfg._dict) # 返回默认的字典类型,默认使用有序字典
# 内部方式
for k, v in cfg._sections.items():print(k, v)
mysql OrderedDict([('default-character-set', 'utf8')])
mysqld OrderedDict([('datadir', '/dbserver/data'), ('port', '33060'), ('character-set-server', 'utf8'), ('sql_mode', 'NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES')])
test OrderedDict([('test1', '1'), ('test2', '2')])for k, v in cfg._sections['mysqld'].items():print(k, v)
datadir /dbserver/data
port 33060
character-set-server utf8
sql_mode NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

8.pickle

实例自己的属性需要单独序列化

(1)函数

dumps:对象序列化为bytes对象

loads:从bytes对象反序列化

dump:对象序列化到文件中

load:对象反序列化,从文件中读取数据

import picklefilename = 'd:/nfile/xuliehua'
x = 99
y = 'a'
lst = list('678')
d = {'a': 1, 'b': 'qwer', 'c': [0, 1, 2, 3]}
# 序列化
with open(filename, 'wb') as f:pickle.dump(x, f)pickle.dump(y, f)pickle.dump(lst, f)pickle.dump(d, f)
# 反序列化
with open(filename, 'rb') as f:print(f.read(), f.seek(0))for i in range(4):x = pickle.load(f)print(x, type(x))
99 
a 
['6', '7', '8'] 
{'a': 1, 'b': 'qwer', 'c': [0, 1, 2, 3]} 

(2)应用

1)本地序列化较少,大多应用到网络传输中。

2)将数据序列化后通过网络传输到远程节点,需要大量的序列化,远程服务器的服务接收到数据,按照对应的数据类型进行反序列化,否则会报错。

3)在python中程序之间可以使用pickle模块解决序列化和反序列化,若是跨平台、语言、协议就不太适合了,需要公共协议,比如XML、Json、Protocol Buffer。(pickle限制python版本、限制协议)

7.Json模块

(1)Json数据类型

值必须双引号引起来的字符串(string)、数值(number)、true、false、null、对象、数组(array)

字符串有双引号引起来的任意字符的组合,包括转义自字符;数值有正负、整数、浮点数;对象是无序的键值对的集合,key必须为字符串,需要双引号包围这个字符串,value任意合法的值;数组为有序值的集合

(2)Python与Json

True、False、None、str、int、float、list、dict

true、false、null、string、integer、float、array、object

(3)方法

dumps:json编码

loads:json解码

dump:json编码并存入文件中

load:json解码,从文件中读取数据

大多不写入文件中,直接从内存中直接网络传输到远程节点,其服务接收,使用dumps()和loads()居多

import json
d = {'name': 'Jack', 'age': 80, 'hobby': ['basketball', 'music']}
j = json.dumps(d)
print(j, type(j))
{"name": "Jack", "age": 80, "hobby": ["basketball", "music"]} d1 = json.loads(j)
print(d1)
print(id(d), id(d1))
{'name': 'Jack', 'age': 80, 'hobby': ['basketball', 'music']}
2326128497360 2326129337256

9.msgpack模块

MessagePack是一个基于二进制高效的对象序列化的类库,可用于跨语言通信,可以像Json那样,在多种语言之间交换结果对象,但是比Json更快更轻巧。

(1)安装

pip install msgpack

(2)方法

packb序列化对象,提供了dumps来兼容pickle和json;unpacb反序列化对象,提供loads来兼容

pack序列化对象保存到文件对象,提供dump来兼容;unpack反序列化对象保存到文件对象,提供load来兼容

json用途广泛;packle仅适用python,二进制形式;msgpack速度快,号称比protocol buffer快4倍(在某种条件下)

转载于:https://my.oschina.net/u/3844908/blog/3006340


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部