【Python之路】第六篇--Python基础之模块
模块,用一砣代码实现了某个功能的代码集合。
类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。
如:os 是系统相关的模块;file是文件操作相关的模块
模块分为三种:
自定义模块
第三方模块
内置模块
1、定义模块
情景一:
情景二:
情景三:
2、导入模块
Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用,如果想要使用模块,则需要导入。导入模块有一下几种方法:
- import module
- from module.xx.xx import xx
- from module.xx.xx import xx as rename
- from module.xx.xx import *
导入模块其实就是告诉Python解释器去解释那个py文件
导入一个py文件,解释器解释该py文件
导入一个包,解释器解释该包下的 __init__.py 文件 【py2.7】
那么问题来了,导入模块时是根据那个路径作为基准来进行的呢?即:sys.path
- import sys
- print(sys.path)
- 结果:['', 'C:\\Windows\\SYSTEM32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34', 'C:\\Users\\admin\\AppData\\Roaming\\Python\\Python34\\site-packages', 'C:\\Python34\\lib\\site-packages']
- # sys.path 第一个值为当前路径
- # site-packages 存放所有第三方安装的模块
如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。
- import sys
- import os
- project_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- sys.path.append(project_path)
- 或者:
- sys.path.append("D:")
例子:
- # 导入全部内容
- import s1
- # 导入函数f1
- from s1 import f1
- f1()
- ***************************
- # lib 包名
- # 导入lib 下的account.py 中的login函数
- from lib.account import login
- login()
- # 方法二:
- from lib import account
- account.login()
- # 方法三:
- import lib.account
- lib.account.login()
- ***************************
- # 别名
- from lib import account as BBB
- BBB.login()
模块
内置模块是Python自带的功能,在使用内置模块相应的功能时,需要【先导入】再【使用】
一、sys
用于提供对Python解释器相关的操作:
- sys.argv 命令行参数List,第一个元素是程序本身路径
- sys.exit(n) 退出程序,正常退出时exit(0)
- sys.version 获取Python解释程序的版本信息
- sys.maxint 最大的Int值
- sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
- sys.platform 返回操作系统平台名称,如win32
- sys.stdin 输入相关
- sys.stdout 输出相关
- sys.stderror 错误相关
- sys.stdout.flush() 强制刷新到屏幕
- sys.stdout.write("\r") 每一次清空原行
- sys.stdout.write("hello") 输出后 没有换行
- print() 自动换行
- #!/usr/bin/env python
- # -*-coding:utf-8 -*-
- import sys
- import time
- for i in range(1,101):
- sys.stdout.write('\r')
- sys.stdout.write(' %i%% %s'%(i,i*'#'))
- sys.stdout.flush()
- time.sleep(0.1)
- sys.stdout.flush() 强制刷新到屏幕
- sys.stdout.write("\r") 每一次清空原行
- %% 防止转义
进度条百分比
二、os
用于提供系统级别的操作:
- os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
- os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
- os.curdir 返回当前目录: ('.')
- os.pardir 获取当前目录的父目录字符串名:('..')
- os.makedirs('dir1/dir2') 可生成多层递归目录,存在则报错
- os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推,只删除空文件夹
- os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
- os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
- os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
- os.remove() 删除一个文件
- os.rename("oldname","new") 重命名文件/目录
- os.stat('path/filename') 获取文件/目录信息
- os.sep 操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
- os.linesep 当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
- os.pathsep 用于分割文件路径的字符串
- 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所指向的文件或者目录的最后修改时间
例子:
- import os
- # os.path.exists 如果path存在,返回True;如果path不存在,返回False
- bool_path = os.path.exists("D://123")
- print(bool_path)
- # False
- # os.path.dirname 返回path的目录。其实就是os.path.split(path)的第一个元素
- dir_path = os.path.dirname("D:\Youdao\YoudaoNote")
- print(dir_path)
- # D:\Youdao
- # os.path.join 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
- name_path = os.path.join('D:\yy','tt.txt')
- print(name_path)
- # D:\yy\tt.txt
- # os.stat('path/filename|dirname') 获取文件/目录信息
- st = os.stat('D:\yy\Launcher.xml')
- print(st)
- # os.stat_result(st_mode=33206, st_ino=2814749767142260, st_dev=1726123312, st_nlink=1, st_uid=0, st_gid=0, st_size=209, st_atime=1457605409, st_mtime=1470828693, st_ctime=1457605409)
三、time
时间相关的操作,时间有三种表示方式:
时间戳 从1970年1月1日到现在一共过去了多少秒,即:time.time()
格式化的字符串 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
结构化时间 元组包含了:年、日、星期等... time.struct_time 即:time.localtime()
常用方法:
- print(time.time()) # 返回当前系统时间戳
- print(time.clock()) # 计算cpu执行时间
- print(time.gmtime()) # UTC时间,结构化tuple
- print(time.localtime()) # 本地时间,结构化tuple
- print(time.strftime(format,tuple)) # format格式 : %Y:%m:%d %H:%M:%S , tuple:结构化时间
- print(time.strptime(string time,format)) # string time 对应的format格式 , 返回结构化时间
- print(time.ctime(时间戳)) # 时间戳 => string , Sat Nov 26 19:49:21 2016 ,当前系统时间
- print(time.mktime(tuple)) # 结构化时间tuple => 时间戳
时间戳 => 时间数组(结构化时间):
- import time
- print( time.localtime(时间戳) ) # 时间戳 float类型 => 结构化时间,tuple
- import datetime
- print( datetime.datetime.fromtimestamp(时间戳) ) # 时间戳float => datetime.datetime
datetime => time 结构化时间
- datetime对象.timetuple()
时间加减:
- print(datetime.datetime.now()) #返回 2016-11-26 20:04:32.586288
- print(datetime.datetime.fromtimestamp(time.time()) ) # 时间戳直接转成日期格式 2016-11-26
- print(datetime.datetime.now() + datetime.timedelta(3)) # 当前时间+3天
- print(datetime.datetime.now() + datetime.timedelta(-3)) # 当前时间-3天
- print(datetime.datetime.now() + datetime.timedelta(hours=3)) # 当前时间+3小时
- print(datetime.datetime.now() + datetime.timedelta(weeks=1)) # 当前时间+1周
- # timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
- c_time = datetime.datetime.now()
- print(c_time.replace(minute=3,hour=2)) #时间替换
关系转换例子
datetime <=> string
datetime -> string
- datetime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- print(datetime)
- # 2016-11-26 20:20:20
string -> datetime
- datetime.datetime.strptime("2016-11-26 20:20:20", "%Y-%m-%d %H:%M:%S")
datetime <=> date
datetime -> date
- datetime.datetime.now().date()
date -> datetime
- today = datetime.date.today()
- datetime = datetime.datetime.combine(today, datetime.time())
四、序列化
Python中用于序列化的两个模块
json 只能序列化 列表,变量,字符串,字典
pickle 可以序列化 任何类型 因为只有python支持
Json 模块提供了四个功能:dumps、dump、loads、load
pickle 模块提供了四个功能:dumps、dump、loads、load
- Functions:
- dump(object, file)
- dumps(object) -> string
- load(file) -> object
- loads(string) -> object
- *************************************
- import pickle
- data = { 'name' : 'alex' ,'age' : 18 }
- # pickle.dumps 将数据通过特殊的形式转换为只有python语言认识的字符串
- p_str = pickle.dumps(data)
- print(p_str)
- # pickle.dump 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件
- with open('ab.txt','wb')as f:
- pickle.dump(data,f)
- # 从文件中读取
- with open('ab.txt','rb')as f:
- data = pickle.load(f)
- print(data)
- ************************************
- import json
- # json.dumps 将python基本数据类型 => 将字符串
- # 将数据通过特殊的形式转换为所有语言都认识的字符串
- j_str = json.dumps(data)
- print(j_str)
- # json.loads 将字符串 => python基本数据类型
- # 用于将字典,列表,元组形式的字符串 装换成 字典,列表,元组
- # 注意: 如果 字典内的元素 是字符串要用双引号! ,
- list_str = '[11,22,33,44]'
- dic_str = '{"v1":"k1","v2":"k2"}'
- json.loads(dic_str)
- # json.dump 将数据通过特殊的形式转换为所有语言都认识的字符串,并写入文件
- with open('js.txt','w')as f:
- json.dump(data,f)
- dic = { 'k1':123 , 'k2' : 'v2' }
- json.dump(dic,open('db','w'))
- # 从文件中读取
- with open('js.txt', 'r')as f:
- data = json.load(f)
- print(data)
- r = json.load(open('db','r'))
- print(r,type(r))
五、hashlib
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法
- import md5
- hash = md5.new()
- hash.update('admin')
- print hash.hexdigest()
md5-废弃
- import sha
- hash = sha.new()
- hash.update('admin')
- print hash.hexdigest()
sha-废弃
- import hashlib
- # ######## md5 ########
- hash = hashlib.md5()
- # help(hash.update)
- hash.update(bytes('admin', encoding='utf-8')) # (方法一) update() 接收二进制类型 / 同一对象,连续两次不同值的update 等于拼接!!
hash.update('admin'.encode('utf8)) # (方法二) 转换成二进制形式- print(hash.hexdigest()) # 16进制方式表示
- ######## sha1 ########
- hash = hashlib.sha1()
- hash.update(bytes('admin', encoding='utf-8'))
- print(hash.hexdigest())
- # ######## sha256 ########
- hash = hashlib.sha256()
- hash.update(bytes('admin', encoding='utf-8'))
- print(hash.hexdigest())
- # ######## sha384 ########
- hash = hashlib.sha384()
- hash.update(bytes('admin', encoding='utf-8'))
- print(hash.hexdigest())
- # ######## sha512 ########
- hash = hashlib.sha512()
- hash.update(bytes('admin', encoding='utf-8'))
- print(hash.hexdigest())
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
- import hashlib
- # ######## md5 ########
- hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8"))
- hash.update(bytes('admin',encoding="utf-8"))
- print(hash.hexdigest())
python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密
- import hmac
- h = hmac.new(bytes('898oaFs09f',encoding="utf-8"))
- h.update(bytes('admin',encoding="utf-8"))
- print(h.hexdigest())
登录与注册
六、requests
Python标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了。它是为另一个时代、另一个互联网所创建的。它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务。
- import urllib.request
- f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
- result = f.read().decode('utf-8')
发送GET请求
- import urllib.request
- req = urllib.request.Request('http://www.example.com/')
- req.add_header('Referer', 'http://www.python.org/')
- r = urllib.request.urlopen(req)
- result = f.read().decode('utf-8')
发送携带请求头的GET请求
注:更多见Python官方文档:https://docs.python.org/3.5/library/urllib.request.html#module-urllib.request
Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作。
- response = requests.get('http://www.baidu.com')
- response.encoding = 'utf-8' # 注意编码问题
- result = response.text
- print(result)
1、安装模块
- pip3 install requests
2、使用模块
- # 1、无参数实例
- import requests
- ret = requests.get('https://github.com/timeline.json')
- print(ret.url)
- print(ret.text)
- # 2、有参数实例
- import requests
- payload = {'key1': 'value1', 'key2': 'value2'}
- ret = requests.get("http://httpbin.org/get", params=payload)
- print(ret.url)
- print(ret.text)
GET请求
- # 1、基本POST实例
- import requests
- payload = {'key1': 'value1', 'key2': 'value2'}
- ret = requests.post("http://httpbin.org/post", data=payload)
- print(ret.text)
- # 2、发送请求头和数据实例
- import requests
- import json
- url = 'https://api.github.com/some/endpoint'
- payload = {'some': 'data'}
- headers = {'content-type': 'application/json'}
- ret = requests.post(url, data=json.dumps(payload), headers=headers)
- print(ret.text)
- print(ret.cookies)
POST请求
- requests.get(url, params=None, **kwargs)
- requests.post(url, data=None, json=None, **kwargs)
- requests.put(url, data=None, **kwargs)
- requests.head(url, **kwargs)
- requests.delete(url, **kwargs)
- requests.patch(url, data=None, **kwargs)
- requests.options(url, **kwargs)
- # 以上方法均是在此方法的基础上构建
- requests.request(method, url, **kwargs)
其他请求
更多requests模块相关的文档见:http://cn.python-requests.org/zh_CN/latest/
3、Http请求和XML实例
实例:检测QQ账号是否在线
- import urllib
- import requests
- from xml.etree import ElementTree as ET
- # 使用内置模块urllib发送HTTP请求,或者XML格式内容
- """
- f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
- result = f.read().decode('utf-8')
- """
- # 使用第三方模块requests发送HTTP请求,或者XML格式内容
- r = requests.get('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
- result = r.text
- # 解析XML格式内容
- node = ET.XML(result)
- # 获取内容
- if node.text == "Y":
- print("在线")
- else:
- print("离线")
实例:查看火车停靠信息
- import urllib
- import requests
- from xml.etree import ElementTree as ET
- # 使用内置模块urllib发送HTTP请求,或者XML格式内容
- """
- f = urllib.request.urlopen('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=')
- result = f.read().decode('utf-8')
- """
- # 使用第三方模块requests发送HTTP请求,或者XML格式内容
- r = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=')
- result = r.text
- # 解析XML格式内容
- root = ET.XML(result)
- for node in root.iter('TrainDetailInfo'):
- print(node.find('TrainStation').text,node.find('StartTime').text,node.tag,node.attrib)
注:更多接口猛击这里
七、XML
XML是实现不同语言或程序之间进行数据交换的协议,XML文件格式如下:
- <data>
- <country name="Liechtenstein">
- <rank updated="yes">2</rank>
- <year>2023</year>
- <gdppc>141100</gdppc>
- <neighbor direction="E" name="Austria" />
- <neighbor direction="W" name="Switzerland" />
- </country>
- <country name="Singapore">
- <rank updated="yes">5</rank>
- <year>2026</year>
- <gdppc>59900</gdppc>
- <neighbor direction="N" name="Malaysia" />
- </country>
- <country name="Panama">
- <rank updated="yes">69</rank>
- <year>2026</year>
- <gdppc>13600</gdppc>
- <neighbor direction="W" name="Costa Rica" />
- <neighbor direction="E" name="Colombia" />
- </country>
- </data>
1、解析XML
- from xml.etree import ElementTree as ET
- # 打开文件,读取XML内容
- str_xml = open('xo.xml', 'r').read()
- # 将字符串解析成xml特殊对象,root代指xml文件的根节点
- root = ET.XML(str_xml)
ElementTree.XML将字符串解析成xml对象
- from xml.etree import ElementTree as ET
- # 直接解析xml文件
- tree = ET.parse("xo.xml")
- # 获取xml文件的根节点
- root = tree.getroot()
ElementTree.parse将字符串解析成xml对象
2、操作XML
XML格式类型是节点嵌套节点,对于每一个节点均有以下功能,以便对当前节点进行操作:
- class Element:
- """An XML element.
- This class is the reference implementation of the Element interface.
- An element's length is its number of subelements. That means if you
- want to check if an element is truly empty, you should check BOTH
- its length AND its text attribute.
- The element tag, attribute names, and attribute values can be either
- bytes or strings.
- *tag* is the element name. *attrib* is an optional dictionary containing
- element attributes. *extra* are additional element attributes given as
- keyword arguments.
- Example form:
- <tag attrib>text<child/>...</tag>tail
- """
- 当前节点的标签名
- tag = None
- """The element's name."""
- 当前节点的属性
- attrib = None
- """Dictionary of the element's attributes."""
- 当前节点的内容
- text = None
- """
- Text before first subelement. This is either a string or the value None.
- Note that if there is no text, this attribute may be either
- None or the empty string, depending on the parser.
- """
- tail = None
- """
- Text after this element's end tag, but before the next sibling element's
- start tag. This is either a string or the value None. Note that if there
- was no text, this attribute may be either None or an empty string,
- depending on the parser.
- """
- def __init__(self, tag, attrib={}, **extra):
- if not isinstance(attrib, dict):
- raise TypeError("attrib must be dict, not %s" % (
- attrib.__class__.__name__,))
- attrib = attrib.copy()
- attrib.update(extra)
- self.tag = tag
- self.attrib = attrib
- self._children = []
- def __repr__(self):
- return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self))
- def makeelement(self, tag, attrib):
- 创建一个新节点
- """Create a new element with the same type.
- *tag* is a string containing the element name.
- *attrib* is a dictionary containing the element attributes.
- Do not call this method, use the SubElement factory function instead.
- """
- return self.__class__(tag, attrib)
- def copy(self):
- """Return copy of current element.
- This creates a shallow copy. Subelements will be shared with the
- original tree.
- """
- elem = self.makeelement(self.tag, self.attrib)
- elem.text = self.text
- elem.tail = self.tail
- elem[:] = self
- return elem
- def __len__(self):
- return len(self._children)
- def __bool__(self):
- warnings.warn(
- "The behavior of this method will change in future versions. "
- "Use specific 'len(elem)' or 'elem is not None' test instead.",
- FutureWarning, stacklevel=2
- )
- return len(self._children) != 0 # emulate old behaviour, for now
- def __getitem__(self, index):
- return self._children[index]
- def __setitem__(self, index, element):
- # if isinstance(index, slice):
- # for elt in element:
- # assert iselement(elt)
- # else:
- # assert iselement(element)
- self._children[index] = element
- def __delitem__(self, index):
- del self._children[index]
- def append(self, subelement):
- 为当前节点追加一个子节点
- """Add *subelement* to the end of this element.
- The new element will appear in document order after the last existing
- subelement (or directly after the text, if it's the first subelement),
- but before the end tag for this element.
- """
- self._assert_is_element(subelement)
- self._children.append(subelement)
- def extend(self, elements):
- 为当前节点扩展 n 个子节点
- """Append subelements from a sequence.
- *elements* is a sequence with zero or more elements.
- """
- for element in elements:
- self._assert_is_element(element)
- self._children.extend(elements)
- def insert(self, index, subelement):
- 在当前节点的子节点中插入某个节点,即:为当前节点创建子节点,然后插入指定位置
- """Insert *subelement* at position *index*."""
- self._assert_is_element(subelement)
- self._children.insert(index, subelement)
- def _assert_is_element(self, e):
- # Need to refer to the actual Python implementation, not the
- # shadowing C implementation.
- if not isinstance(e, _Element_Py):
- raise TypeError('expected an Element, not %s' % type(e).__name__)
- def remove(self, subelement):
- 在当前节点在子节点中删除某个节点
- """Remove matching subelement.
- Unlike the find methods, this method compares elements based on
- identity, NOT ON tag value or contents. To remove subelements by
- other means, the easiest way is to use a list comprehension to
- select what elements to keep, and then use slice assignment to update
- the parent element.
- ValueError is raised if a matching element could not be found.
- """
- # assert iselement(element)
- self._children.remove(subelement)
- def getchildren(self):
- 获取所有的子节点(废弃)
- """(Deprecated) Return all subelements.
- Elements are returned in document order.
- """
- warnings.warn(
- "This method will be removed in future versions. "
- "Use 'list(elem)' or iteration over elem instead.",
- DeprecationWarning, stacklevel=2
- )
- return self._children
- def find(self, path, namespaces=None):
- 获取第一个寻找到的子节点
- """Find first matching element by tag name or path.
- *path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
- Return the first matching element, or None if no element was found.
- """
- return ElementPath.find(self, path, namespaces)
- def findtext(self, path, default=None, namespaces=None):
- 获取第一个寻找到的子节点的内容
- """Find text for first matching element by tag name or path.
- *path* is a string having either an element tag or an XPath,
- *default* is the value to return if the element was not found,
- *namespaces* is an optional mapping from namespace prefix to full name.
- Return text content of first matching element, or default value if
- none was found. Note that if an element is found having no text
- content, the empty string is returned.
- """
- return ElementPath.findtext(self, path, default, namespaces)
- def findall(self, path, namespaces=None):
- 获取所有的子节点
- """Find all matching subelements by tag name or path.
- *path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
- Returns list containing all matching elements in document order.
- """
- return ElementPath.findall(self, path, namespaces)
- def iterfind(self, path, namespaces=None):
- 获取所有指定的节点,并创建一个迭代器(可以被for循环)
- """Find all matching subelements by tag name or path.
- *path* is a string having either an element tag or an XPath,
- *namespaces* is an optional mapping from namespace prefix to full name.
- Return an iterable yielding all matching elements in document order.
- """
- return ElementPath.iterfind(self, path, namespaces)
- def clear(self):
- 清空节点
- """Reset element.
- This function removes all subelements, clears all attributes, and sets
- the text and tail attributes to None.
- """
- self.attrib.clear()
- self._children = []
- self.text = self.tail = None
- def get(self, key, default=None):
- 获取当前节点的属性值
- """Get element attribute.
- Equivalent to attrib.get, but some implementations may handle this a
- bit more efficiently. *key* is what attribute to look for, and
- *default* is what to return if the attribute was not found.
- Returns a string containing the attribute value, or the default if
- attribute was not found.
- """
- return self.attrib.get(key, default)
- def set(self, key, value):
- 为当前节点设置属性值
- """Set element attribute.
- Equivalent to attrib[key] = value, but some implementations may handle
- this a bit more efficiently. *key* is what attribute to set, and
- *value* is the attribute value to set it to.
- """
- self.attrib[key] = value
- def keys(self):
- 获取当前节点的所有属性的 key
- """Get list of attribute names.
- Names are returned in an arbitrary order, just like an ordinary
- Python dict. Equivalent to attrib.keys()
- """
- return self.attrib.keys()
- def items(self):
- 获取当前节点的所有属性值,每个属性都是一个键值对
- """Get element attributes as a sequence.
- The attributes are returned in arbitrary order. Equivalent to
- attrib.items().
- Return a list of (name, value) tuples.
- """
- return self.attrib.items()
- def iter(self, tag=None):
- 在当前节点的子孙中根据节点名称寻找所有指定的节点,并返回一个迭代器(可以被for循环)。
- """Create tree iterator.
- The iterator loops over the element and all subelements in document
- order, returning all elements with a matching tag.
- If the tree structure is modified during iteration, new or removed
- elements may or may not be included. To get a stable set, use the
- list() function on the iterator, and loop over the resulting list.
- *tag* is what tags to look for (default is to return all elements)
- Return an iterator containing all the matching elements.
- """
- if tag == "*":
- tag = None
- if tag is None or self.tag == tag:
- yield self
- for e in self._children:
- yield from e.iter(tag)
- # compatibility
- def getiterator(self, tag=None):
- # Change for a DeprecationWarning in 1.4
- warnings.warn(
- "This method will be removed in future versions. "
- "Use 'elem.iter()' or 'list(elem.iter())' instead.",
- PendingDeprecationWarning, stacklevel=2
- )
- return list(self.iter(tag))
- def itertext(self):
- 在当前节点的子孙中根据节点名称寻找所有指定的节点的内容,并返回一个迭代器(可以被for循环)。
- """Create text iterator.
- The iterator loops over the element and all subelements in document
- order, returning all inner text.
- """
- tag = self.tag
- if not isinstance(tag, str) and tag is not None:
- return
- if self.text:
- yield self.text
- for e in self:
- yield from e.itertext()
- if e.tail:
- yield e.tail
- 节点功能一览表
功能节点一览
由于 每个节点 都具有以上的方法,并且在上一步骤中解析时均得到了root(xml文件的根节点),so 可以利用以上方法进行操作xml文件。
a. 遍历XML文档的所有内容
- from xml.etree import ElementTree as ET
- ############ 解析方式一 ############
- """
- # 打开文件,读取XML内容
- str_xml = open('xo.xml', 'r').read()
- # 将字符串解析成xml特殊对象,root代指xml文件的根节点
- root = ET.XML(str_xml)
- """
- ############ 解析方式二 ############
- # 直接解析xml文件
- tree = ET.parse("xo.xml")
- # 获取xml文件的根节点
- root = tree.getroot()
- ### 操作
- # 顶层标签
- print(root.tag)
- # 遍历XML文档的第二层
- for child in root:
- # 第二层节点的标签名称和标签属性
- print(child.tag, child.attrib)
- # 遍历XML文档的第三层
- for i in child:
- # 第二层节点的标签名称和内容
- print(i.tag,i.text)
b、遍历XML中指定的节点
- from xml.etree import ElementTree as ET
- ############ 解析方式一 ############
- """
- # 打开文件,读取XML内容
- str_xml = open('xo.xml', 'r').read()
- # 将字符串解析成xml特殊对象,root代指xml文件的根节点
- root = ET.XML(str_xml)
- """
- ############ 解析方式二 ############
- # 直接解析xml文件
- tree = ET.parse("xo.xml")
- # 获取xml文件的根节点
- root = tree.getroot()
- ### 操作
- # 顶层标签
- print(root.tag)
- # 遍历XML中所有的year节点
- for node in root.iter('year'):
- # 节点的标签名称和内容
- print(node.tag, node.text)
c、修改节点内容
由于修改的节点时,均是在内存中进行,其不会影响文件中的内容。所以,如果想要修改,则需要重新将内存中的内容写到文件。
- from xml.etree import ElementTree as ET
- ############ 解析方式一 ############
- # 打开文件,读取XML内容
- str_xml = open('xo.xml', 'r').read()
- # 将字符串解析成xml特殊对象,root代指xml文件的根节点
- root = ET.XML(str_xml)
- ############ 操作 ############
- # 顶层标签
- print(root.tag)
- # 循环所有的year节点
- for node in root.iter('year'):
- # 将year节点中的内容自增一
- new_year = int(node.text) + 1
- node.text = str(new_year)
- # 设置属性
- node.set('name', 'alex')
- node.set('age', '')
- # 删除属性
- del node.attrib['name']
- ############ 保存文件 ############
- tree = ET.ElementTree(root)
- tree.write("newnew.xml", encoding='utf-8')
解析字符串方式,删除,保存
- from xml.etree import ElementTree as ET
- ############ 解析方式二 ############
- # 直接解析xml文件
- tree = ET.parse("xo.xml")
- # 获取xml文件的根节点
- root = tree.getroot()
- ############ 操作 ############
- # 顶层标签
- print(root.tag)
- # 循环所有的year节点
- for node in root.iter('year'):
- # 将year节点中的内容自增一
- new_year = int(node.text) + 1
- node.text = str(new_year)
- # 设置属性
- node.set('name', 'alex')
- node.set('age', '')
- # 删除属性
- del node.attrib['name']
- ############ 保存文件 ############
- tree.write("newnew.xml", encoding='utf-8')
解析文件方式,删除,保存
3、创建XML文档
- from xml.etree import ElementTree as ET
- # 创建根节点
- root = ET.Element("famliy")
- # 创建节点大儿子
- son1 = ET.SubElement(root, "son", attrib={'name': '儿1'})
- # 创建小儿子
- son2 = ET.SubElement(root, "son", attrib={"name": "儿2"})
- # 在大儿子中创建一个孙子
- grandson1 = ET.SubElement(son1, "age", attrib={'name': '儿11'})
- grandson1.text = '孙子'
- et = ET.ElementTree(root) #生成文档对象
- et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)
创建方式一
- from xml.etree import ElementTree as ET
- # 创建根节点
- root = ET.Element("famliy")
- # 创建节点大儿子
- son1 = ET.Element('son', {'name': '儿1'})
- # 创建小儿子
- son2 = ET.Element('son', {"name": '儿2'})
- # 在大儿子中创建两个孙子
- grandson1 = ET.Element('grandson', {'name': '儿11'})
- grandson2 = ET.Element('grandson', {'name': '儿12'})
- son1.append(grandson1)
- son1.append(grandson2)
- # 把儿子添加到根节点中
- root.append(son1)
- root.append(son1)
- tree = ET.ElementTree(root)
- tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
创建方式二
- from xml.etree import ElementTree as ET
- # 创建根节点
- root = ET.Element("famliy")
- # 创建大儿子
- # son1 = ET.Element('son', {'name': '儿1'})
- son1 = root.makeelement('son', {'name': '儿1'})
- # 创建小儿子
- # son2 = ET.Element('son', {"name": '儿2'})
- son2 = root.makeelement('son', {"name": '儿2'})
- # 在大儿子中创建两个孙子
- # grandson1 = ET.Element('grandson', {'name': '儿11'})
- grandson1 = son1.makeelement('grandson', {'name': '儿11'})
- # grandson2 = ET.Element('grandson', {'name': '儿12'})
- grandson2 = son1.makeelement('grandson', {'name': '儿12'})
- son1.append(grandson1)
- son1.append(grandson2)
- # 把儿子添加到根节点中
- root.append(son1)
- root.append(son1)
- tree = ET.ElementTree(root)
- tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
创建方式三
注:
- shorrt_empty_element = False 没有内容不自闭合
- xml_declaration = True xml开头注释
由于原生保存的XML时默认无缩进,如果想要设置缩进的话, 需要修改保存方式:
- from xml.etree import ElementTree as ET
- from xml.dom import minidom
- def prettify(elem):
- """将节点转换成字符串,并添加缩进。
- """
- rough_string = ET.tostring(elem, 'utf-8')
- reparsed = minidom.parseString(rough_string)
- return reparsed.toprettyxml(indent="\t")
- # 创建根节点
- root = ET.Element("famliy")
- # 创建大儿子
- # son1 = ET.Element('son', {'name': '儿1'})
- son1 = root.makeelement('son', {'name': '儿1'})
- # 创建小儿子
- # son2 = ET.Element('son', {"name": '儿2'})
- son2 = root.makeelement('son', {"name": '儿2'})
- # 在大儿子中创建两个孙子
- # grandson1 = ET.Element('grandson', {'name': '儿11'})
- grandson1 = son1.makeelement('grandson', {'name': '儿11'})
- # grandson2 = ET.Element('grandson', {'name': '儿12'})
- grandson2 = son1.makeelement('grandson', {'name': '儿12'})
- son1.append(grandson1)
- son1.append(grandson2)
- # 把儿子添加到根节点中
- root.append(son1)
- root.append(son1)
- raw_str = prettify(root)
- f = open("xxxoo.xml",'w',encoding='utf-8')
- f.write(raw_str)
- f.close()
4、命名空间
详细介绍,猛击这里
- from xml.etree import ElementTree as ET
- ET.register_namespace('com',"http://www.company.com") #some name
- # build a tree structure
- root = ET.Element("{http://www.company.com}STUFF")
- body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF", attrib={"{http://www.company.com}hhh": ""})
- body.text = "STUFF EVERYWHERE!"
- # wrap it in an ElementTree instance, and save as XML
- tree = ET.ElementTree(root)
- tree.write("page.xml",
- xml_declaration=True,
- encoding='utf-8',
- method="xml")
命名空间
八、configparser
configparser用于处理特定格式的文件,其本质上是利用open来操作文件。
- [DEFAULT]
- ServerAliveInterval = 45
- Compression = yes
- CompressionLevel = 9
- ForwardX11 = yes
- [bitbucket.org]
- User = hg
- [topsecret.server.com]
- Port = 50022
- ForwardX11 = no
config文件格式
读取时,文件内容均为字符串类型,不需要加""
- # 注释1
- ; 注释2
- [section1] # 节点
- k1 = v1 # 值
- k2:v2 # 值
- [section2] # 节点
- k1 = v1 # 值
1、获取所有节点
- import configparser
- config = configparser.ConfigParser()
- config.read('xxxooo', encoding='utf-8')
- ret = config.sections()
- print(ret)
2、获取指定节点下所有的键值对
- import configparser
- config = configparser.ConfigParser()
- config.read('xxxooo', encoding='utf-8')
- ret = config.items('section1')
- print(ret)
3、获取指定节点下所有的建
- import configparser
- config = configparser.ConfigParser()
- config.read('xxxooo', encoding='utf-8')
- ret = config.options('section1')
- print(ret)
4、获取指定节点下指定key的值
- import configparser
- config = configparser.ConfigParser()
- config.read('xxxooo', encoding='utf-8')
- v = config.get('section1', 'k1')
- # v = config.getint('section1', 'k1')
- # v = config.getfloat('section1', 'k1')
- # v = config.getboolean('section1', 'k1')
- print(v)
5、检查、删除、添加节点
- import configparser
- config = configparser.ConfigParser()
- config.read('xxxooo', encoding='utf-8')
- # 检查
- has_sec = config.has_section('section1')
- print(has_sec)
- # 添加节点
- config.add_section("SEC_1")
- config.write(open('xxxooo', 'w'))
- # 删除节点
- config.remove_section("SEC_1")
- config.write(open('xxxooo', 'w'))
6、检查、删除、设置指定组内的键值对
- import configparser
- config = configparser.ConfigParser()
- config.read('xxxooo', encoding='utf-8')
- # 检查
- has_opt = config.has_option('section1', 'k1')
- print(has_opt)
- # 删除
- config.remove_option('section1', 'k1')
- config.write(open('xxxooo', 'w'))
- # 设置
- config.set('section1', 'k10', "123")
- config.write(open('xxxooo', 'w'))
九、logging
用于便捷记录日志且线程安全的模块
1、单文件日志 (只记录到文件中,屏幕不显示信息)
- import logging
- logging.basicConfig(filename='log.log',
- format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
- datefmt='%Y-%m-%d %H:%M:%S %p',
- level=10) # level=logging.DEBUG
- logging.debug('debug')
- logging.info('info')
- logging.warning('warning')
- logging.error('error')
- logging.critical('critical')
- logging.log(10,'log')
日志等级:
- CRITICAL = 50
- FATAL = CRITICAL
- ERROR = 40
- WARNING = 30
- WARN = WARNING
- INFO = 20
- DEBUG = 10
- NOTSET = 0
注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。
日志记录格式:
- format参数中可能用到的格式化串:
- %(name)s Logger的名字
- %(levelno)s 数字形式的日志级别
- %(levelname)s 文本形式的日志级别
- %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
- %(filename)s 调用日志输出函数的模块的文件名
- %(module)s 调用日志输出函数的模块名
- %(funcName)s 调用日志输出函数的函数名
- %(lineno)d 调用日志输出函数的语句所在的代码行
- %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
- %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
- %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
- %(thread)d 线程ID。可能没有
- %(threadName)s 线程名。可能没有
- %(process)d 进程ID。可能没有
- %(message)s用户输出的消息
format参数
2、多文件日志
对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象。
- # 定义文件
- file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
- fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")
- file_1_1.setFormatter(fmt)
- file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
- fmt = logging.Formatter()
- file_1_2.setFormatter(fmt)
- # 定义日志
- logger1 = logging.Logger('s1', level=logging.ERROR)
- logger1.addHandler(file_1_1)
- logger1.addHandler(file_1_2)
- # 写日志
- logger1.critical('')
日志(一)
- # 定义文件
- file_2_1 = logging.FileHandler('l2_1.log', 'a')
- fmt = logging.Formatter()
- file_2_1.setFormatter(fmt)
- # 定义日志
- logger2 = logging.Logger('s2', level=logging.INFO)
- logger2.addHandler(file_2_1)
日志(二)
如上述创建的两个日志对象
当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中
3、Logger对象
模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)
- import logging
- logger = logging.getLogger()
- # 创建一个handler,用于写入日志文件
- fh = logging.FileHandler('test.log')
- # 再创建一个handler,用于输出到控制台
- ch = logging.StreamHandler()
- formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- fh.setFormatter(formatter)
- ch.setFormatter(formatter)
- logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
- logger.addHandler(ch)
- logger.debug('logger debug message')
- logger.info('logger info message')
- logger.warning('logger warning message')
- logger.error('logger error message')
- logger.critical('logger critical message')
logging库提供了多个组件:Logger、Handler、Filter、Formatter。
Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。
可以通过Logger.setLevel(lel)指定最低的日志级别,可用的日志级别有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。
十、Random
- import random
- print(random.random()) #(0,1)----float
- print(random.randint(1,3)) #[1,3]
- print(random.randrange(1,3)) #[1,3)
- print(random.choice([1,'23',[4,5]])) #23
- print(random.sample([1,'23',[4,5]],2)) #[[4, 5], '23']
- print(random.uniform(1,3)) #1.927109612082716
【Python之路】第六篇--Python基础之模块的更多相关文章
- Python之路(第六篇)Python全局变量与局部变量、函数多层嵌套、函数递归
一.局部变量与全局变量 1.在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量.全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序. 全局变量没有任何缩进,在任何位置都可 ...
- 【Python之路】第九篇--Python基础之线程、进程和协程
进程与线程之间的关系 线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除.线程可与属于同一进程的其它线程共享进程所拥有的全 ...
- python之路第四篇(基础篇)
一.冒泡算法实现: 方法一: li = [13,33,12,80,66,1] print li for m in range(4): num1 = li[m] num2 = li[m+1] if nu ...
- 【Python之路】第一篇--Linux基础命令
pwd 命令 查看”当前工作目录“的完整路径 pwd -P # 显示出实际路径,而非使用连接(link)路径:pwd显示的是连接路径 . 表示当前目录 .. 表示上级目录 / 表示根目录 ls ...
- Python之路(第八篇)Python内置函数、zip()、max()、min()
一.python内置函数 abs() 求绝对值 例子 print(abs(-2)) all() 把序列中每一个元素做布尔运算,如果全部都是true,就返回true, 但是如果是空字符串.空列表也返回t ...
- Python之路(第五篇) Python基本数据类型集合、格式化、函数
一.变量总结 1.1 变量定义 记录某种状态或者数值,并用某个名称代表这个数值或状态. 1.2 变量在内存中的表现形式 Python 中一切皆为对象,数字是对象,列表是对象,函数也是对象,任何东西都是 ...
- 【Python之路】特别篇--Python正则表达式
正则表达式的基础 正则表达式并不是Python的一部分. 正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大. 得益于这一点 ...
- 【Python之路】特别篇--Python面向对象(进阶篇)
上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- Python之路第五天,基础(6)-模块
模块 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个 ...
- Python之路(第七篇)Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数
一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") ret ...
随机推荐
- S2SH整合
Struts2.Spring.Hibernate三大框架在一个项目中的具体职责分配如下: 三大框架整合,导入各个框架和整合所需的包(本项目采用的是Struts2.3+spring3.0+hiberna ...
- 《.NET 编程结构》专题汇总
<.NET 编程结构>专题汇总 前言 掌握一门技术,首要的是掌握其基础. 笔者从事.NET相关开发多年,也非常喜欢.NET,多年来也积累了很多相关的资料,在此将一些基础性的 ...
- Django入门实践(一)
Django入门实践(一) Django编程思路+入门 认识Django有一个多月了,我觉得学习Django应该先理清它的编程思路.它是典型的MVC框架(在Django里也称MTV),我觉得Djang ...
- C#基础之方法和参数
C#基础之方法和参数 接上一篇<C#基础之类型和成员基础以及常量.字段.属性> 实例方法.静态方法 C#中的方法分为两类,一种是属于对象(类型的实例)的,称之为实例方法,另一种是属于类型的 ...
- 命令版本git 分支篇-----不断更新中
最近应用开发的过程中出现了一个小问题,顺便记录一下原因和方法--命令版本 开发中想看看过去某个版本的代码,我们先查看log git log commit f224a720b8192165a4e70f2 ...
- 用indexOf获取字符窜某个字符的所有位置
indexOf方法可以传两个参数,第二个参数是传位置的参数,利用这点获取所有的位置.例如: var str = "hello world,welcome!"; var arr = ...
- [APUE]进程控制(中)
一.wait和waitpid函数 当一个进程正常或异常终止时会向父进程发送SIGCHLD信号.对于这种信号系统默认会忽略.调用wait/waidpid的进程可能会: 阻塞(如果其子进程都还在运行); ...
- Dubbo源码学习--服务是如何发布的
相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 ServiceBean ServiceBean 实现ApplicationListener接口监听Conte ...
- jQuery+HTML5声音提示
WEB应用中,有时需要播放特定的声音,比如有新消息或者在线聊天消息声音提示,以前我们通过flash实现,今天我们将使用jQuery和HTML5结合示例来实现如何把声音提示带入WEB应用中. 在本例中, ...
- java转发和重定向
1,请求重定向:客户端行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保持,地址栏的URL地址会改变.2,请求转发:服务器行为,request.ge ...