一、模块介绍
Python Module(模块),就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。
文件名就是模块名加上后缀.py,在模块内部,模块名存储在全局变量__name__中,是一个string,可以直接在module中通过__name__引用到module name。
模块分为三种:
- 自定义模块
- 内置标准模块(又称标准库)
- 开源模块
导入模块:
- import: 使客户端(导入者)以一个整体获取一个模块。
- from:容许客户端从一个模块文件中获取特定的变量名。
- reload:在不中止Python程序的情况下,提供了一个重新载入模块文件代码的方法。
语法:
import module
from module.xx.xx import xx
from module.xx.xx import xx as rename
from module.xx.xx import * #一般不推荐使用
示例:
推荐方法一:
import cal #当前目录直接调用模块
from my_module import cal #二层目录调用模块
from web1,web2,web3 import cal #多层目录调用模块
推荐方法二:
from web1,web2,web3.cal import add
注意:不支持的调用方式
from web1.web2 import web3 #执行__init__文件,唯一不支持的调用方式
print(web3.cal.add(2,6))
模块路径
import sys
import os
pre_path=os.path.abspath('.../')
sys.path.append(pre_path) #添加路径,添加环境变量临时生效
for i in sys.path: #获取路径,
print(i)
注意:
环境变量:永久生效方法:我的电脑--->系统属性--->环境变量--->Path路径中添加,以";" 分割。
二、包(package)的概念
我们先设想一下,如果不同的人编写的模块名相同怎么办?为了避免冲突,Python又引进了按目录
来组织模块的方法,称为包(package)。
假设,如下图,我的两个time_file.py模块名字重名了,但是这两个模块的功能都不相同,如果这两个模块都在同一级目录中,那么我在其他地方要调用这个time_file.py模块,那么这个时候就会发生冲突,
在这里我们就可以通过包来组织模块,避免冲突。
方法是:选择一个顶层包名,引入包以后,只要顶层的包名不与别人冲突,那这个包里面的模块都不会与别人冲突了。
请注意:每个包目录下来都会有一个__init__.py的文件,这个文件必须是存在的,否则,Python就不把这个目录当成普通目录,而不是一个包,__init__.py可以是空文件,
也可以有python代码,__init__.py本身就 是一个文件,它的模块命就是对应的包名,它一般做接口文件。
三、time模块
时间相关的操作,时间有三种表示方式:
时间戳
1970年1月1日之后的秒,即:time.time()
格式化的字符串 2016-12-12 10:10, 即:time.strftime('%Y-%m-%d')
结构化时间 元组
即:time.struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
即:time.localtime()
1.返回当前的时间戳 time.time()
import time
print(time.time()) #当前时间的时间戳
#1528284151.432538
2.将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
time.localtime([secs])
print(time.localtime())
print(time.localtime(1528284151.432538))
>>>>
time.struct_time(tm_year=2018, tm_mon=6, tm_mday=6, tm_hour=19, tm_min=22, tm_sec=31, tm_wday=2, tm_yday=157, tm_isdst=0)
time.struct_time(tm_year=2018, tm_mon=6, tm_mday=6, tm_hour=19, tm_min=22, tm_sec=31, tm_wday=2, tm_yday=157, tm_isdst=0)
3.gmtime([secs]) 和localtime()方法类似,
gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time
print(time.gmtime())
>>>>>>
time.struct_time(tm_year=2018, tm_mon=6, tm_mday=6, tm_hour=11, tm_min=28, tm_sec=2, tm_wday=2, tm_yday=157, tm_isdst=0)
4.mktime(t) : 将一个struct_time转化为时间戳。
print(time.mktime(time.localtime()))
>>>>
1528284613.0
5.asctime([t]) : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。
参数为空时,默认为当前时间
print(time.asctime(time.localtime()))
print(time.asctime())
>>>>
Wed Jun 6 19:33:52 2018
Wed Jun 6 19:33:52 2018
6.ctime([secs]) : 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为
None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
print(time.ctime())
>>>>>
Wed Jun 6 19:38:34 2018
7. strftime(format[, t]) : 把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。
如果t未指定,将传入time.localtime()。如果元组中任何一个元素越界,ValueError的错误将会被抛出。
print(time.strftime("%Y-%m-%d %X", time.localtime()))
>>>>
2018-06-06 19:41:51
8 time.strptime(string[, format])
把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X'))
>>>>>
time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1)
9.sleep(secs) 线程推迟指定的时间运行,单位为秒。
10.这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。
而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。
而第二次之后的调用是自第一次调用以后到现在的运行时间,即两次时间差。
四、random 模块 (随机数)
1.random() 用于生成一个0到1的随机符点数: 0 <= n < 1.0
print(random.random())
>>>>>
0.47674138932530974
2.randint(x,y) 用于生成一个指定范围内的整数
print(random.randint(1,2))
>>>>
2
3.randrange()从指定范围内,按指定基数递增的集合中获取一个随机数
print(random.randrange(1,10))
>>>>
8
4.uniform() 用于生成一个指定范围内的随机符点数
print(random.uniform(1, 10))
>>>>
5.244662335538338
5.choice() 从序列中随机生成一个随机元素
print(random.choice('nice'))
>>>>
e
6.shuffle(list) 用于将一个列表中的元素打乱
li = ['nick','jenny','car',]
random.shuffle(li)
print(li)
>>>>>
['nick', 'car', 'jenny']
7.sample()从指定序列中随机获取指定长度的片断
li = ['nick','jenny','car',]
print(random.sample(li,2)) #从li中随机获取2个元素,作为一个片断返回
>>>> ['jenny', 'nick']
验证码实例:
五、os模块
os模块是与操作系统交互的一个接口
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下为"\r\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
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所指向的文件或者目录的最后修改时间
1.getcwd 获取当前工作路径
chdir('...') 改变当前脚本工作路径
import os
print(os.getcwd())
os.chdir('F:\python')
print(os.getcwd())
执行结果
F:\复习
F:\python
2.递归创建空目录
os.makedirs('dirnamel/dirname2') #创建两层
执行结果
3.removedirs 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.removedirs('dirnamel/dirname2')
4、 listdir 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
print(os.listdir())
>>>>>
['.idea', 'a', 'dingxi', 'dingxi2', 'dingxi3', 'Lry', 'module', 'rizhi', 'test', 'test.py', 'venv', 'yesterday2', 'yesterday3', '__pycache__', '元组和字典.py', '内置函数.py', '函数', '函数式编程.py', '列表.py', '字符串.py', '文件处理.py', '模块.py', '装饰器.py', '迭代器和生成器.py', '集合.py']
5. stat 获取文件/目录信息
stat 结构:
- st_mode: inode 保护模式
- st_ino: inode节点号。
- st_dev: inode驻留的设备。
- st_nlink: inode 的链接数。
- st_uid: 所有者的用户ID。
- st_gid: 所有者的组ID。
- st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
- st_atime: 上次访问的时间。
- st_mtime: 最后一次修改的时间。
- st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
print(os.stat("模块.py"))
>>>>>
['.idea', 'a', 'dingxi', 'dingxi2', 'dingxi3', 'Lry', 'module', 'rizhi', 'test', 'test.py', 'venv', 'yesterday2', 'yesterday3', '__pycache__', '元组和字典.py', '内置函数.py', '函数', '函数式编程.py', '列表.py', '字符串.py', '文件处理.py', '模块.py', '装饰器.py', '迭代器和生成器.py', '集合.py']
os.stat_result(st_mode=33206, st_ino=10133099161584003, st_dev=2259195232, st_nlink=1, st_uid=0, st_gid=0, st_size=1164, st_atime=1528373189, st_mtime=1528373189, st_ctime=1528283987)
6.os.system(("dir")) 显示目录和文件
print(os.system(('dir')))
>>>>>
������ F �еľ��� ������
�������� 86A8-9560
F:\��ϰ ��Ŀ¼
2018/06/07 20:08 <DIR> .
2018/06/07 20:08 <DIR> ..
2018/06/07 20:06 <DIR> .idea
2018/06/06 03:36 64 a
2018/06/06 02:08 925 dingxi
2018/06/06 02:15 922 dingxi2
2018/06/06 02:30 0 dingxi3
2018/06/05 22:59 2,694 Lry
2018/06/06 18:45 <DIR> module
2018/06/06 02:56 216 rizhi
2018/06/06 18:45 <DIR> test
2018/06/03 11:34 30 test.py
2018/06/06 18:43 <DIR> venv
2018/06/05 23:20 13 yesterday2
2018/06/05 23:16 216 yesterday3
2018/06/03 11:34 <DIR> __pycache__
2018/06/01 13:47 3,288 Ԫ����ֵ�.py
2018/06/03 11:34 4,135 ���ú���.py
2018/06/01 16:03 1,373 ����
2018/06/01 17:12 1,942 ����ʽ���.py
2018/05/31 14:46 1,885 �б�.py
2018/06/01 13:01 4,105 �ַ���.py
2018/06/06 03:36 6,206 �ļ�����.py
2018/06/07 20:08 1,193 ģ��.py
2018/06/06 15:36 4,069 װ����.py
2018/06/03 20:46 4,099 ��������������.py
2018/06/01 14:58 1,216 ����.py
20 ���ļ� 38,591 �ֽ�
7 ��Ŀ¼ 104,774,754,304 �����ֽ�
0
7. os.path.split 将文件分割成目录和文件名
print(os.path.split(r'F:\复习\模块.py'))
>>>>
('F:\\复习', '模块.py')
8.os.path.dirname 返回path的目录,加了r转义
print(os.path.dirname(r'F:\复习\模块.py'))
#返回path的目录。其实就是os.path.split(path)的第一个元素
>>>> F:\复习
9.文件路径的综合使用
#获取当前路径的文件名
print(__file__)
>>>>
F:/复习/模块.py
#返回上一层目录
print(os.path.dirname(__file__))
>>>
F:/复习
#返回他的绝对路径
print(os.path.abspath(__file__))
>>>>
F:\复习\模块.py
#将path分割成目录和文件名
print(os.path.split(os.path.abspath(__file__)))
>>>>
('F:\\复习', '模块.py')
##返回当前文件的上一层目录
print(os.path.dirname(os.path.abspath(__file__)))
>>>>
F:\复习
#返回上二层的目录
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
>>>>
F:\
10.ps.path.hasename 返回path最后的文件名
print(os.path.basename(r'F:\复习\模块.py'))
>>>>
模块.py
11.os.path.join 路径拼接
import os
a="F:\python\模块"
b="pickle_s1.py"
print(os.path.join(a,b))# 路径拼接
>>>>
F:\python\模块\pickle_s1.py
os.path.join 路径和文件名拼接
print(os.path.join("d:\\"))
print(os.path.join("d:\\","www","baidu","test.py"))
>>>>
print(os.path.join("d:\\"))
print(os.path.join("d:\\","www","baidu","test.py"))
12.\test\bb\123.txt os.path.join拼接出这个路径
print(os.path.join(os.path.dirname(os.path.abspath(__file__)),"bb","123.txt"))
>>>>
F:\复习\bb\123.txt
六、sys模块
1.sys.argv 命令行参数List,第一个元素是程序本身路径
2.sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
import sys
print(sys.path)
>>>>>
['F:\\复习', 'F:\\复习', 'F:\\复习\\venv\\Scripts\\python36.zip', 'D:\\Python\\Python36-32\\DLLs', 'D:\\Python\\Python36-32\\lib', 'D:\\Python\\Python36-32', 'F:\\复习\\venv', 'F:\\复习\\venv\\lib\\site-packages', 'F:\\复习\\venv\\lib\\site-packages\\setuptools-39.0.1-py3.6.egg', 'F:\\复习\\venv\\lib\\site-packages\\pip-9.0.3-py3.6.egg', 'D:\\JetBrains\\PyCharm 2018.1.4\\helpers\\pycharm_matplotlib_backend']
import sys
for i in sys.path:
print(i)
>>>>>
F:\复习
F:\复习
F:\复习\venv\Scripts\python36.zip
D:\Python\Python36-32\DLLs
D:\Python\Python36-32\lib
D:\Python\Python36-32
F:\复习\venv
F:\复习\venv\lib\site-packages
F:\复习\venv\lib\site-packages\setuptools-39.0.1-py3.6.egg
F:\复习\venv\lib\site-packages\pip-9.0.3-py3.6.egg
D:\JetBrains\PyCharm 2018.1.4\helpers\pycharm_matplotlib_backend
3.sys.version 获取Python解释程序的版本信息
print(sys.version)
>>>>
3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]
4.sys.exit(n) 退出程序,正常退出时exit(0)
5.sys.maxint 最大的Int值
6.sys.platform 返回操作系统平台名称
7.进度条的实现
for i in range(10):
sys.stdout.write('*')
time.sleep(1)
sys.stdout.flush()
七、json & pickle(* * * *)
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存 到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。
dumps()函数执行和dump() 函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。
loads()函数执行和load() 函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的str对象, 直接返回的对象。
json
1.把一个字典,写入到文件中
dic='{''name'':''Alex'',''age'':19}' #一定要注意写成字符串形式
f=open('hello','w')
f.write(dic)
2.使用json方法把字典转换成json形式的字符串写入文件中
推荐使用:
import json
dic={'name':'Alex','age':19}
dic=json.dumps(dic)
f=open('hello','w')
f.write(dic)
import json
dic={'name':'Alex','age':19}
f = open('hello', 'a')
dic=json.dump(dic,f)
3.json序列化
把文件中json类型的字符串读取出来转换成字典
f = open('hello','r')
f = json.loads(f.read())
print(f)
print(type(f))
>>>>>
{'name': 'Alex', 'age': 19}
<class 'dict'>
#不推荐使用
f=open('hello','r')
f=json.load(f)
print(f)
print(type(f))
注意的知识点:
1.无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
import json
# dic="{'1':'1'}" #json不认单引号
# dit=str({"1":"1"})
# dic=str(dit)
dit='{"1":"1"}'
print(json.loads(dit))
>>>>
{'1': '1'}
2.先创建一个json_test文件,写入内容
{"name":"ALEX"}
#只要符合json规范就可以把值取出来。 另一种示例:{'name':"alvin"} #如果是'name' 的值是单引号就会报错。
with open('json_test.py','r') as f:
data=f.read()
data=json.loads(data)
print(data['name'])
>>>>>
ALEX
json的dumps,loads,dump,load功能总结:
json.dumps(x) 把python的(x)原对象转换成json字符串的对象,主要用来写入文件。
json.loads(f) 把json字符串(f)对象转换成python原对象,主要用来读取文件和json字符串
json.dump(x,f) 把python的(x)原对象,f是文件对象,写入到f文件里面,主要用来写入文件的
json.load(file) 把json字符串的文件对象,转换成python的原对象,只是读文件
pickle序列化
1.pickle转换后的结果是bytes(字节)
import pickle
dic={'name':'alvin','age':23,'sex':'male'}
print(type(dic))
j=pickle.dumps(dic)
print(type(j))
>>>>>
<class 'dict'>
<class 'bytes'>
2.
dic={'name':'alvin','age':23,'sex':'male'}
j=pickle.dumps(dic)
f=open('序列化对象_pickle','wb') #w是写入的str,wb写入bytes
f.write(j) #等价于pickle.dump(dic.f)
f.close()
>>>>>
�}q (X nameqX alvinqX ageqKX sexqX malequ.
生成一个不可读文件,但是计算机可以解析
3、反序列化
f=open('序列化对象_pickle','rb')
data=pickle.loads(f.read())
print(data['age'])
>>>>
23
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。
八、shelve模块
shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型
1.
#添加键值对到文件中,会生成三个文件,并写入字典内容
import shelve
f = shelve.open(r'shelve1') # 目的:将一个字典放入文本 f={}
f['stu1_info']={'name':'alex','age':'18'}
f['stu2_info']={'name':'alvin','age':'20'}
f['school_info']={'website':'oldboyedu.com','city':'beijing'}
f.close()
执行结果:
会生成三个文件:shelvel.dat,shelve1.dir,shelve1.bak,其中shelvel.bak中内容如下:
'stu', (0, 49)
'stu1', (512, 50)
'school', (1024, 60)
九、xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
<?xml version="1.0"?>
<data> #根
<country name="Liechtenstein"> #节点
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore"> #节点
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama"> #节点
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
xml数据
xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:
1.查询
import xml.etree.ElementTree as ET #ET为模块名的简写,自定义
tree=ET.parse('xml') #解析文件,相当于读取
root=tree.getroot() #获取根
print(root.tag)
>>>>>
data
#遍历xml文档
for i in root:
print(i.tag,i.attrib) #tag是标签,attrib属性
for j in i:
print(j.tag,j.attrib)
>>>>>
country {'name': 'Liechtenstein'}
rank {'updated': 'yes'}
year {}
gdppc {}
neighbor {'name': 'Austria', 'direction': 'E'}
neighbor {'name': 'Switzerland', 'direction': 'W'}
country {'name': 'Singapore'}
rank {'updated': 'yes'}
year {}
gdppc {}
neighbor {'name': 'Malaysia', 'direction': 'N'}
country {'name': 'Panama'}
rank {'updated': 'yes'}
year {}
gdppc {}
neighbor {'name': 'Costa Rica', 'direction': 'W'}
neighbor {'name': 'Colombia', 'direction': 'E'}
#只遍历‘year’节点下的内容
for note in root.iter('year'):
print(note.tag,note.text)
>>>>>
year 2008
year 2011
year 2011
2.修改
import xml.etree.ElementTree as ET
tree=ET.parse('xml')
root=tree.getroot()
for note in root.iter('year'):
new_year=int(note.text)+1
note.text=str(new_year)
note.set('updated','yes') #修改通过set,加个属性yes
tree.write('xml') #最后写入,可以覆盖,也可以新建
3.删除
import xml.etree.ElementTree as ET tree=ET.parse('xml') root=tree.getroot()
for country in root.findall('country'): #对country节点进行遍历
rank = int(country.find('rank').text) #find找到rank
if rank >50:
root.remove(country) #移除
tree.write('xml') #最后写入,可以覆盖,也可以新建
4.XML的编写
import xml.etree.ElementTree as ET
new_xml =ET.Element('namelist') #创建根
name = ET.SubElement(new_xml,'name',attrib={'enrolled':'yes'}) #创建子节点,并添加属性
age=ET.SubElement(name,'age',attrib={'checked':'NO'})
sex=ET.SubElement(name,'sex')
sex.text='33'
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) #创建子节点
age=ET.SubElement(name2,'age')
age.text='19'
et=ET.ElementTree(new_xml) #生成文档对象
et.write('test_xml.xml',encoding='utf8',xml_declaration=True)
ET.dump(new_xml)
执行结果
<?xml version='1.0' encoding='utf8'?>
<namelist>
<name enrolled="yes">
<age checked="NO" />
<sex>33</sex>
</name>
<name enrolled="no">
<age>19</age>
</name>
</namelist>