【python】-- json & pickle、xml、requests、hashlib、shelve、shutil、configparser、subprocess
json & pickle
Python中用于序列化的两个模块
- json 用于【字符串】和 【python基本数据类型】 间进行转换
- pickle 用于【python特有的类型】 和 【python基本数据类型】间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
1、dumps序列化和loads反序列化
- dumps()序列化
- import json #导入json模块
- info = {
- 'name':"zhangqigao",
- "age":22
- }
- with open("test.txt","w") as f: #以普通模式写入
- data = json.dumps(info) #把内存对象转为字符串
- f.write(data) #写到文件中
- #text.txt文件中的内容
- {"name": "zhangqigao", "age": 22}
- #########################################
- loads()反序列化
- import json
- with open("test.txt","r") as f: #以普通模式读
- data = json.loads(f.read()) #用loads反序列化
- print(data.get("age"))
- #输出
- 22
2、dump序列化和load反序列化
- dump()序列化
- import json
- info = {
- 'name':"zhangqigao",
- "age":22
- }
- with open("test.txt","w") as f: #文件以写的方式打开
- json.dump(info,f) #第1个参数是内存的数据对象 ,第2个参数是文件句柄
- #text.txt文件中的内容
- {"name": "zhangqigao", "age": 22}
- #########################################
- load()反序列化
- import json
- with open("test.txt","r") as f: #以读的方式打开文件
- data = json.load(f) #输入文件对象
- print(data.get("age"))
- #输出
- 22
小结:
- dumps和loads是成对使用的,dump和load是成对使用的。
- dumps和loads由于序列化的是内容,所以后面要加s,但是dump和load序列化的内容是对象,所以单数。
- json只能处理简单的数据类型,例如:字典、列表、字符串等,不能处理函数等复杂的数据类型。
- json是所有语言通用的,所有语言都支持json,如果我们需要python跟其他语言进行数据交互,那么就用json格式。
pickle模块提供了四个功能:dumps、dump、loads、load
1、dumps序列化和loads反序列化
- dumps()序列化
- import pickle
- info = {
- 'name':"zhangqigao",
- "age":22,
- }
- with open("test.txt","wb") as f: #以二进制的形式写入
- data = pickle.dumps(info) #序列化成字符串
- f.write(data) #写入test.txt 文件中
- #输出到test.txt文件中的内容
- �}q (X ageqKX nameqX
- zhangqigaoqu.
- #########################################
- loads()反序列化
- import pickle
- with open("test.txt","rb") as f: #以二进制的模式读
- data = pickle.loads(f.read()) #反序列化操作
- print(data.get("age"))
- #输出
- 22
2、dump序列化和load反序列化
- dump()序列化
- import pickle
- info = {
- 'name':"zhangqigao",
- "age":22,
- }
- with open("test.txt","wb") as f:
- pickle.dump(info,f) #序列化
- #输出
- �}q (X ageqKX nameqX
- zhangqigaoqu.
- #########################################
- load()反序列化
- import pickle
- with open("test.txt","rb") as f:
- data = pickle.load(f) #反序列化成内存对象
- print(data.get("age"))
- #输出
- 22
小结:
- json值支持简单的数据类型,pickle支持所有的数据类型。
- pickle只能支持python本身的序列化和反序列化,不能用作和其他语言做数据交互,而json可以。
- pickle序列化的是字节,而json序列化的是字符
- pickle序列化的是整个的数据对象,所以反序列化函数时,函数体中的逻辑变了,是跟着心的函数体走的。
- pickle和json在3.0中只能dump一次和load一次,在2.7里面可以dump多次,load多次,以后只记住,只需要dump一次,load一次就可以了。
XML
XML是实现不同语言或者程序之间进行数据交换的协议,跟json差不多,但是json使用起来更简单,不过现在仍然有很多传统的公司,像金融行业的很多系统的接口还是XML
1、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>
2、查询xml文档内容
- import xml.etree.ElementTree as et
- tree = et.parse("xmltest.xml")
- root = tree.getroot() #获取根节点
- print(root.tag) #打印节点名称
- #遍历xml文档
- for child in root:
- print(child.tag,child.attrib) #分别打印子节点名称和子节点属性
- #遍历子节点下的所有节点
- for i in child:
- print(i.tag,i.text) #打印子节点下节点的节点名和节点值
- #只遍历year节点
- for i in child.iter("year"):
- print("\t",i.tag,i.attrib,i.text)
- #只遍历year节点
- for node in root.iter("year"):
- print(node.tag,node.text) #打印year的节点名和节点值
注:
- tag是返回节点名,attrib返回节点属性,text返回节点值
- 返回根节点用getroot()方法
- 只遍历某个节点,只需要用iter(节点名)方法
3、修改xml文档内容
- import xml.etree.ElementTree as et
- tree = et.parse("xmltest.xml")
- root = tree.getroot()
- #修改year节点的值
- for node in root.iter("year"):
- new_year = int(node.text) + 1 #修改节点值
- node.text = str(new_year) #修改后强制转换成字符串类型
- node.tag = "myyear" #修改节点名
- node.set("zhangqigao",'handsome') #修改节点属性
- tree.write("xmltest1.xml") #修改完成后,重新写入xml文件(可以是任何文件,包括原来的)
注:可以修改xml文件中的任何内容,包括本身的节点名,修改后一定要有写入xml文件的操作。
4、删除node节点
- import xml.etree.ElementTree as et
- tree = et.parse("xmltest.xml")
- root = tree.getroot()
- #删除
- for country in root.findall("country"): #找到第一层子节点
- rank = int(country.find("rank").text) #找到子节点下的'rank'节点的节点值
- if rank > 50:
- root.remove(country) #删除子节点
- tree.write("xmltest1.xml") #重新写入xml文件
注:
- findall()从根节点只能根据第一层的子节点名查找,并且返回第一层子节点的内存地址
- find从根节点查找第一层子节点名,返回第一层子节点下的所有节点的内存地址
- 删除子节点用remove()方法
- 删除以后,一定要做重新写入新的xml文件操作
5、手动创建xml文件
- import xml.etree.ElementTree as et
- new_xml = et.Element("namelist") #创建根节点
- #创建第一层子节点,后面参数依次是:父节点,子节点,子节点属性
- name = et.SubElement(new_xml,"name",attrib={"zhangqigao":"handsome"})
- #创建第二层子节点
- age = et.SubElement(name,"age",attrib={"check":"yes"})
- #设置第二层节点值
- age.text = ''
- sex = et.SubElement(name,"sex")
- sex.text = "man"
- #创建另外一个第一层子节点
- name2 = et.SubElement(new_xml,"name",attrib={"zhangqigao":"haoshuai"})
- #创建其第二层子节点
- age = et.SubElement(name2,"age")
- age.text = ''
- ET = et.ElementTree(new_xml) #生成新的xml文档
- ET.write("test.xml",encoding="utf-8",xml_declaration=True) #在新xml文件的开头自动添加:<?xml version='1.0' encoding='utf-8'?>
- et.dump(new_xml) #在屏幕上打印生成的格式
注:et.dump(new_xml)这个有什么作用呢?当你需要直接把字符串传过去,不需要传文件时,用这个就ok了。
requests
Python标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了。它是为另一个时代、另一个互联网所创建的。它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务。
发送get请求:
- 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')
Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作。
安装模块:
- pip3 install requests
使用模块:
get请求:
- # 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)
post请求:
- # 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)
其他请求:
- 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)
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)
hashlib
写程序中,经常需要对字符串进行MD5加密,python中也支持这种加密
1、MD5加密
原则:只要你的输入是固定的,你的输出也一定是固定的。MD5是在hash上更改的,主要做文件的一致性
- import hashlib
- m = hashlib.md5() #创建一个MD5对象
- m.update(b"zhang") #在python3中需要是2进制的值,所以字符串前加b
- print(m.hexdigest()) #以16进制打印MD5值
- #输出
- d0cd2693b3506677e4c55e91d6365bff
- m.update(b"qigao")
- print(m.hexdigest())
- #输出
- 0bfca190ecc60e44cbc739ca9c252133
文件MD5加密:
说明:如果我们想得到一个文件所有内容的MD5值,我们所做的方法是循环这个文件,获取每行的MD5值,但是这样生成的MD5值的效率会变慢,因为每一行都需要计算。这样我们还不如直接把文件的所有内容加载出来,直接计算它的MD5值,这样反而快些。
- import hashlib
- m = hashlib.md5() #创建MD5对象m
- m.update(b"zhang")
- print(m.hexdigest())
- #输出
- d0cd2693b3506677e4c55e91d6365bff
- m.update(b"qigao")
- print(m.hexdigest())
- #输出
- 0bfca190ecc60e44cbc739ca9c252133
- m2 = hashlib.md5() #创建MD5对象m2
- m2.update(b"zhangqigao")
- print(m2.hexdigest())
- #输出
- 0bfca190ecc60e44cbc739ca9c252133
注:由上面的代码可以看出,你读到最后一行的字符串的MD5值跟一下子读取所有内容的MD5值是一样的,这是为什么呢?其实这边update做了一个拼接功能,m.update(b"zhang")是返回的字符串"zhang"的MD5值,但是到了第二个m.update("qigao")的值并不是"qigao"的字符串的MD5值,它需要拼接前面的字符串,应该是m.update(b"zhangqigao")的MD5值,所以相当于m.update(b"zhang"),m.update(b"qigao") = m.update(b"zhang"+b"qigao")。
2、sha1加密
- import hashlib
- hash = hashlib.sha1()
- hash.update(b"zhangqigao")
- print(hash.hexdigest())
- #输出
- c8b2a6571067f92133b5b43a085f1ddd36e8c3fb
3、sha256加密
说明:sha256用的比较多,相比MD5要更加的安全
- import hashlib
- hash = hashlib.sha256()
- hash.update(b"zhangqigao")
- print(hash.hexdigest())
- #输出
- 0634de5fe3d009fd0ec76ab3d97ab0fe37969b696e8d6550797cf3b446dd78ba
4、sha384加密
- import hashlib
- hash = hashlib.sha384()
- hash.update(b"zhangqigao")
- print(hash.hexdigest())
- #输出
- 3489c64e31671094ca1afde35fd31ee9b09cdb90c3728f31696829e8a56be311e1405d537179e62d236e6d70a4f13ff4
5、sha512加密
- import hashlib
- hash = hashlib.sha512()
- hash.update(b"zhangqigao")
- print(hash.hexdigest())
- #输出
- cb09fd5a519b2b075f4aa5965a39657df900fff832b73d161a426512b6023ab8c1c0872a7b2d50055cbd75c4b6f374cda0615be9530f7f4b7dc08ab3f266325d
注意:
- 以上这几种,其实都是对MD5加密的不同算法
- 其中sha256用的最多,比MD5要安全的多
- 有些公司会用加密方式加密,比如:把字符串"zhangqigao",通过一定的算法变成"zhang.qi.gao",当然这种算法自己肯定要知道,然后MD5加密,当然每个公司的加密方式是不一样的。
6、hmac加密
其实以上还不是最牛的,最牛的是下面这种,叫hmac加密,它内部是对我们创建key和内容进行处理再进行加密。
散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;
一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。
- import hmac #导入hmac模块
- hash = hmac.new(b"zhang",b"qigao") #zhang是key,qigao是内容
- print(hash.hexdigest())
- #输出
- 2f124c86aeb5142246198f77a142e855
更多加密:点击
shelve
json也好,还是pickle也好,在python3中只能dump一次和load一次,不能dump多次,和load多次,真想要dump多次和load多次就需要将数据持久化。
1、持久化
- import shelve #导入shelve模块
- def stu_data(name,age): #定义一个函数
- print("register stu:",name,age)
- name = ["test","zhang","qi","gao"] #定义一个列表
- info = { "name":"zhangqigao","age":18} #定义一个字典
- with shelve.open("shelve_test") as d:
- d["test"] = name #持久化列表
- d["info"] = info #持久化字典
- d["func"] = stu_data #持久化函数
代码执行结果:
- 生成三个文件夹,分别是:shelve_test.dir、shelve_test.dat、shelve_test.bak
- #########################################
- ①shelve_test.dir内容
- 'test', (0, 50)
- 'func', (1024, 24)
- 'info', (512, 48)
- #########################################
- ②shelve_test.dat内容
- �]q (X testqX zhangqX qiqX gaoqe.
- �}q (X nameqX
- zhangqigaoqX ageqKu.
- �c__main__
- stu_data
- q .
- #########################################
- ③shelve_test.bak内容
- 'test', (0, 50)
- 'func', (1024, 24)
- 'info', (512, 48)
2、解析文件内容
- import shelve
- def stu_data(name,age): #这边一定要定义相同名字的函数,不然执行报错
- print("stu:",name,age)
- with shelve.open("shelve_test") as f:
- print(f['test']) #解析列表
- print(f['info']) #解析字典
- print(f["func"]("zhangqsan",22)) #解析函数
- #输出
- ['test', 'zhang', 'qi', 'gao']
- {'age': 18, 'name': 'zhangqigao'}
- stu: zhangqsan 22
- None
3、shelve常用方法
- update
- 说明:update方法是如果序列化的值存在,则更新,如果不存在,则新增,用法:update({key:序列化对象})
- #dumps到文件中
- import shelve
- info = {
- "name":"zhangqigao",
- "age":18
- }
- with shelve.open("shelve_test") as d:
- d['qigaotest'] = info #变量存在
- d.update({'qigaotest':"shuaigaogao"}) #更新已经key为"qigaotest"的值
- #loads到内存中
- import shelve
- with shelve.open("shelve_test") as f:
- print(f.get("qigaotest"))
- #输出
- shuaigaogao
- #########################################
- get
- 说明:把文件中的值load到内存中时,通过get它的key值获取
- import shelve
- with shelve.open("shelve_test") as f:
- print(f.get("qigaotest")) #或者是f["qigaotest"]
- #输出
- shuaigaogao
小结:
- shelve模块是一个简单的key,value将内存数据通过文件持久化的模块。
- shelve模块可以持久化任何pickle可支持的python数据格式。
- shelve就是pickle模块的一个封装。
- shelve模块是可以多次dump和load。
shutil
文件的拷贝、删除、打包、压缩等文件操作
模块常用函数:
- 1、shutil.copyfileobj(fsrc, fdst)
- 功能:把一个文件的内容拷贝到另外一个文件中,可以是部分文件内容。
- with open("f_old",'r',encoding="utf-8") as f1,\
- open("f_new","w",encoding="utf-8") as f2:
- shutil.copyfileobj(f1,f2) #拷贝文件的内容
- 注:经过试验,目前试验不出可以拷贝部分文件内容,先忘记可以拷贝部分内容把。
- #########################################
- 2、shutil.copyfile(src, dst)
- 功能:拷贝文件,但是不拷贝所有权限
- shutil.copyfile("f_old","f_new") #同一目录下拷贝文件
- shutil.copyfile(r'D:\PycharmProjects\pyhomework\day5\shutil_mode\shutil_mod\f_old',r'd:\f_new') #通过绝对路径拷贝文件
- #########################################
- 3、shutil.copymode(src, dst)
- 功能:拷贝文件的文件权限
- [root@whtest137 ~]# ll
- total 8
- -rwxr-xr-x 1 root root 0 Apr 1 16:05 zhangqigao #有执行权限
- -rw-r--r-- 1 whtest whtest 0 Apr 1 16:06 zhangqigao_old #没有执行权限
- >>> import os,shutil
- >>> os.chdir("/root")
- #拷贝"zhangqigao_old"权限给"zhangqigao"
- >>> shutil.copymode("zhangqigao_old","zhangqigao")
- [root@whtest137 ~]# ll
- total 8
- -rw-r--r-- 1 root root 0 Apr 1 16:05 zhangqigao # 获得跟"zhangqigao_old"一样的文件权限
- -rw-r--r-- 1 whtest whtest 0 Apr 1 16:06 zhangqigao_old
- #########################################
- 4、shutil.copystat(src, dst)
- 功能:拷贝文件的状态信息,如:mode bits, atime, mtime, flags
- #两个文件的创建时间和用户权限都不同
- [root@jenkins_sh temp]# ll
- total 0
- -rw-r--r-- 1 root root 0 Apr 1 17:31 zhangqigao
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #python操作
- >>> import os,shutil
- >>> os.chdir("/temp")
- #zhangqigao 这个文件状态
- >>> os.stat("zhangqigao")
- posix.stat_result(st_mode=33188, st_ino=76808194, st_dev=2053L, st_nlink=1,
- st_uid=0, st_gid=0, st_size=0, st_atime=1491039109, st_mtime=1491039109,
- st_ctime=1491039109)
- #zhangqigao_old的文件状态
- >>> os.stat("zhangqigao_old")
- posix.stat_result(st_mode=33261, st_ino=76808195, st_dev=2053L, st_nlink=1,
- st_uid=101, st_gid=103, st_size=0, st_atime=1491035188, st_mtime=1491035188,
- st_ctime=1491035242)
- #拷贝zhangqigao_old 文件状态给zhangqigao 文件
- >>> shutil.copystat("zhangqigao_old","zhangqigao")
- # 拷贝后,zhangqigao文件的文件状态
- >>> os.stat("zhangqigao")
- posix.stat_result(st_mode=33261, st_ino=76808194, st_dev=2053L, st_nlink=1,
- st_uid=0, st_gid=0, st_size=0, st_atime=1491035188, st_mtime=1491035188,
- st_ctime=1491039237)
- #操作后两个文件比较
- [root@jenkins_sh temp]# ll
- total 0
- -rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao #状态包括文件权限,文件创建的时间等,不包括文件所属用户和用户组
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #########################################
- 5、shutil.copy(src, dst)
- 功能:拷贝文件和文件的权限
- #拷贝前
- [root@jenkins_sh temp]# ll
- total 0
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #拷贝中
- >>> import os,shutil
- >>> os.chdir("/temp")
- >>> shutil.copy("zhangqigao_old","zhangqigao")
- #拷贝结果输出
- [root@jenkins_sh temp]# ll
- total 0
- -rwxr-xr-x 1 root root 0 Apr 1 17:42 zhangqigao #拷贝了zhangqigao_old文件和文件权限
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #########################################6、shutil.copy2(src, dst)
- 功能:拷贝文件和文件的状态
- #拷贝前
- [root@jenkins_sh temp]# ll
- total 0
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #拷贝中
- >>> import os,shutil
- >>> os.chdir("/temp")
- >>> shutil.copy2("zhangqigao_old","zhangqigao")
- #拷贝后
- [root@jenkins_sh temp]# ll
- total 0
- -rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao #拷贝了zhangqigao_old的文件和状态
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #########################################
- 7、shutil.copytree(src, dst)
- 功能:递归的去拷贝文件,相当于cp -r
- #操作前
- [root@jenkins_sh temp]# ll
- total 4
- drwxr-xr-x 2 root root 4096 Apr 1 17:53 xiaogao
- [root@jenkins_sh temp]# cd xiaogao/;ll
- total 0
- -rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #操作中
- >>> import os,shutil
- >>> os.chdir("/temp")
- >>> shutil.copytree("xiaogao","gaogao") #递归拷贝
- #操作结果
- [root@jenkins_sh temp]# ll
- total 8
- drwxr-xr-x 2 root root 4096 Apr 1 17:53 gaogao #拷贝成功
- drwxr-xr-x 2 root root 4096 Apr 1 17:53 xiaogao
- [root@jenkins_sh temp]# cd gaogao/;ll
- total 0
- -rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao
- -rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao_old
- #########################################
- 9、shutil.rmtree(path[, ignore_errors[, onerror]])
- 功能:递归的去删除文件,相当于:rm -fr
- #操作前
- [root@jenkins_sh temp]# ll
- total 4
- drwxr-xr-x 2 root root 4096 Apr 1 17:53 xiaogao
- [root@jenkins_sh temp]# cd xiaogao/;ll
- total 0
- -rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao
- -rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old
- #操作中
- >>> import os,shutil
- >>> os.chdir("/temp")
- >>> shutil.rmtree("xiaogao")
- #操作结果
- [root@jenkins_sh temp]# ll
- total 0 #成功删除xiaogao目录
- #########################################
- 10、shutil.move(src, dst)
- 功能:递归的去移动文件 相当于:mv
- #操作前
- [root@jenkins_sh temp]# ll
- total 4
- drwxr-xr-x 2 root root 4096 Apr 1 18:07 xiaogao
- -rw-r--r-- 1 root root 0 Apr 1 18:07 zhangqigao
- #操作中
- >>> import shutil
- >>> shutil.move("/temp/zhangqigao","/temp/xiaogao") #把文件移到目录中
- #操作结果
- [root@jenkins_sh xiaogao]# ll
- total 4
- drwxr-xr-x 2 root root 4096 Apr 1 18:08 xiaogao
- [root@jenkins_sh temp]# cd xiaogao/;ll
- total 0
- -rw-r--r-- 1 root root 0 Apr 1 18:07 zhangqigao
压缩/解压缩:
- 1、shutil.make_archive((base_name, format, root_dir=None,base_dir=None,verbose=0,dry=0,owner=None,group=None,logger=None)
- 功能:创建压缩包并且返回文件路径,例如:zip,tar
- base_name : 压缩包的文件名,也可以是压缩包的路径。只是文件名,则保存当前目录,否则保存到指定路径。
- format:压缩包种类,'zip','tar','bztar','gztar'
- root_dir:需要压缩的文件夹路径(默认当前路径)
- owner:用户,默认当前用户
- group:组,默认当前组
- logger:用于记录日志,通常是logging.Logger对象
- #指定路径
- >>> import shutil
- #把/temp下的xiaogao文件以zip压缩格式压缩,并且存放在/temp/zhangqigao目录下,"/temp/zhangqigao/xiaogao" 中的xiaogao是压缩名
- >>> shutil.make_archive("/temp/zhangqigao/xiaogao",'zip',"/temp/xiaogao")
- '/temp/zhangqigao/xiaogao.zip' #压缩结果
- #默认当前路径
- >>> shutil.make_archive("xiaogao",'zip',"/temp/xiaogao")
- '/temp/xiaogao.zip'
- #########################################
- 2、zipfile
- 功能:以zip的形式压缩文件,注意了这个只能压缩文件,不能压缩目录,如果压缩,也只能显示空目录。
- import zipfile
- # 压缩
- z = zipfile.ZipFile('laxi.zip', 'w')
- z.write('a.log') #写入
- z.write('data.data')
- z.close() #关闭
- # 解压
- z = zipfile.ZipFile('laxi.zip', 'r')
- z.extractall() #解压
- z.close()
- #########################################
- 3、tarfile
- 功能:以tar的形式打包文件,这边能打包所以文件,包括目录
- import tarfile
- # 打包
- tar = tarfile.open('your.tar','w')
- #不加arcname打的是绝对路径,也就是/Users/wupeiqi/PycharmProjects/bbs2.zip,加这个表示你在your.tar中加什么文件就写什么文件名,也就是bbs2.zip
- tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip')
- tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip')
- tar.close()
- # 解压
- tar = tarfile.open('your.tar','r')
- tar.extractall() # 可设置解压地址
- tar.close()
小结:
- tar打包不会压缩文件,所以文件的大小没有变
- zip才会压缩,所以压缩后的文件大小会变小
- 一般情况下是先打包再压缩
configparser
用于生产和修改常见配置文件的模块
1、配置文件格式
- [DEFALUT]
- compressionlevel = 9
- serveraliveinterval = 45
- compression = yes
- forwardx11 = yes
- [bitbucket.org]
- user = hg
- [topsecret.server.com]
- host port = 50022
- forwardx11 = no
2、创建配置文件
- import configparser #导入configparser模块
- #创建一个对象
- config = configparser.ConfigParser()
- #配置默认全局配置组
- config["DEFALUT"] = {"ServerAliveInterval":"",
- "Compression":"yes",
- "CompressionLevel":""
- }
- #配置第一个其他组
- config["bitbucket.org"] = {}
- #没有没有赋给一个变量,直接赋值
- config["bitbucket.org"]["User"] = 'hg'
- #配置第二个其他组
- config["topsecret.server.com"] = {}
- #这边就赋给一个变量
- topsecret = config["topsecret.server.com"]
- #通过变量赋值
- topsecret["Host Port"] = ''
- topsecret["ForwardX11"] = 'no'
- #给全局配置组赋值
- config["DEFALUT"]["ForwardX11"] = "yes"
- #操作完毕,把配置的内容写入一个配置文件中
- with open("example.ini","w") as configfile:
- config.write(configfile)
注:其实有的时候我们很少创建,除非是用系统管理,一般直接修改就可以了
3、读取配置文件
- 1、读取配置组
- >>> import configparser
- >>> config = configparser.ConfigParser()
- >>> config.sections() #不读取配置文件,组名列表为空
- []
- >>> config.read("example.ini") #读取配置文件,返回配置文件名
- ['example.ini']
- >>> config.sections() #返回除默认配置组的其他组名
- ['bitbucket.org', 'topsecret.server.com']
- >>> config.defaults() #读取默认配置组,并返回有序字典
- OrderedDict([('compressionlevel', ''), ('serveraliveinterval', ''), ('compression', 'yes'), ('forwardx11', 'yes')])
- #########################################
- 2、组名是否存在
- >>> 'bitbucket.org' in config #组名存在
- True
- >>> 'zhangqigao.org' in config #组名不存在
- False
- #########################################
- 3、读取组内的值
- >>> config["bitbucket.org"]["User"] #读取"bitbucket.org"配置组中的值
- 'hg'
- >>> config["DEFAULT"]["Compression"] #读取默认配置组中的值
- 'yes'
- >>> topsecret = config['topsecret.server.com'] #把配置组赋给一个对象
- >>> topsecret['ForwardX11'] #通过对象获取值
- <strong>'no
- </strong>
- #########################################
- 4、 循环获取组内的key值
- >>> for key in config["bitbucket.org"]: #循环打印bitbucket.org组下的key值
- ... print(key)
- ...
- #输出,只打印默认组和bitbucket.org组的key值
- user
- compressionlevel
- serveraliveinterval
- compression
- forwardx11
- >>> for key in config["topsecret.server.com"]:#循环打印topsecret.server.com组下的key值
- ... print(key)
- ...
- #输出,只打印默认组和topsecret.server.com组的key值
- host port
- forwardx11
- compressionlevel
- serveraliveinterval
- compression
注:默认组是全局的,所以循环遍历key值时,会遍历从默认组和需要遍历的组一起遍历出来
4、增删改查语法
- 1、配置文件名i.cfg
- [DEFAULT]
- k1 = v1
- k2 = v2
- [section1]
- k3 = v3
- k4:v4
- [section2]
- k5 = 5
- #########################################
- 2、读i.cfg
- import configparser
- config = configparser.ConfigParser()
- config.read("i.cfg")
- sec = config.sections()
- print(sec)
- #输出
- ['section1', 'section2']
- options = config.options("section2") #返回默认组和section2组的key值
- print(options)
- #输出
- ['k5', 'k1', 'k2']
- item_list = config.items("section2") #返回默认组和section2组的key-value值
- print(item_list)
- #输出
- [('k1', 'v1'), ('k2', 'v2'), ('k5', '')]
- val1 = config.get("section2","k1") #获取section2组中k1对应的值,是否可取是按照上面返回的列表
- print(val1)
- #输出
- v1
- val2 = config.getint("section2","k5") #返回section2中k5的值,这个值返回的int类型的
- print(val2)
- #输出
- 5
- #########################################
- 3、改写i.cfg
- ①删除section和option
- import configparser
- config = configparser.ConfigParser()
- config.read("i.cfg")
- config.remove_option("section1","k3") #删除section1组下的k3
- config.remove_section("section2") #删除section2组
- with open("i.cfg2","w") as f: #重新写入一个文件
- config.write(f)
- #输出,写入文件的内容
- [DEFAULT]
- k1 = v1
- k2 = v2
- [section1]
- k4 = v4
- ②添加section
- import configparser
- config = configparser.ConfigParser()
- config.read("i.cfg")
- sec = config.has_option("section2","k5") #是否存在section2组内有k5
- print(sec)
- #输出
- True
- sec = config.has_section("zhangqigao") #是否存在zhangqigao组
- print(sec)
- #输出
- False
- config.add_section("zhangqigao") #添加section组zhangqigao
- config.add_section("zhangqigao") #重新写入到一个配置文件中
- with open("i.cfg3","w") as f:
- config.write(f)
- ③添加或者设置option
- import configparser
- config = configparser.ConfigParser()
- config.read("i.cfg")
- config.set("zhangqigao","z","") #设置或者添加zhangqigao中option值
- with open("i.cfg3","w") as f: #重新写入文件中
- config.write(f)
subprocess
操作系统的命令做交互
在没有subprocess这个模块的时候,跟我们的操作系统做交互的主要是这三个模块:os.system()、os.popen()、commands。
- 1、os.system()
- 作用:执行操作系统命令,只返回命令的执行状态(0:成功,非0:失败),不返回命令的执行结果。
- >>> import os
- >>> os.system("ls -l")
- total 16708
- -rw-------. 1 root root 1350 Jan 4 01:51 anaconda-ks.cfg
- -rw-r--r--. 1 root root 8017 Jan 4 01:51 install.log
- 0 #执行返回的状态
- >>> res = os.system("ls -l")
- total 16708
- -rw-------. 1 root root 1350 Jan 4 01:51 anaconda-ks.cfg
- -rw-r--r--. 1 root root 8017 Jan 4 01:51 install.log
- >>> res
- 0 #0: 表示成功
- >>> res = os.system("lm")
- sh: lm: command not found
- >>> res
- 32512 #非0:表示失败
- #########################################
- 2、os.popen()
- 作用:执行操作系统命令,不返回命令的执行状态,只返回命令的执行结果。
- >>> import os
- >>> os.popen("ls -l")
- <open file 'ls -l', mode 'r' at 0x7f5ded070540>
- >>> res = os.popen("ls -l")
- >>> a = res.read()
- >>> print(a) #打印返回结果
- total 16708
- -rw-------. 1 root root 1350 Jan 4 01:51 anaconda-ks.cfg
- -rw-r--r--. 1 root root 8017 Jan 4 01:51 install.log
- 注:执行popen()不是直接返回命令的执行结果的,而是需要read一下,这是因为popen相当于打开了一个文件,它把结果存到文件中,只不过它是相当于存在内存中了,但是你好像打开文件的样子去取一样。
- ####################################
- 3、commands模块
- 作用:既可以获取命令的执行状态,也可以获取命令的执行结果,但是只能在python2.7有这个命令,在python3.5之后就没有,还有就是这个模块功能只支持Linux,Windows不支持,这边知道这个命令就行了,先忘记它吧。
- >>> import commands #导入commands命令
- >>> commands.getstatusoutput("ls -l")
- (0, 'total 16708\n-rw-------. 1 root root 1350 Jan 4 01:51 anaconda-ks.cfg\n
- -rw-r--r--. 1 root root 8017 Jan 4 01:51 install.log') #元组的形式返回
- >>> res = commands.getstatusoutput("ls -l")
- >>> res[0] #执行状态
- 0
- >>> print(res[1]) #执行结果
- total 16708
- -rw-------. 1 root root 1350 Jan 4 01:51 anaconda-ks.cfg
- -rw-r--r--. 1 root root 8017 Jan 4 01:51 install.log
commands模块在python3.5以后的版本就没有了
subprocess:
- 1、subprocess.run()
- 作用:运行命令,返回命令执行的结果(python3.5以后的版本才会有这个命令)
- >>> import subprocess
- # python 解析则传入命令的每个参数的列表
- >>> subprocess.run(["df","-h"])
- Filesystem Size Used Avail Use% Mounted on
- /dev/mapper/VolGroup-LogVol00
- 289G 70G 204G 26% /
- tmpfs 64G 0 64G 0% /dev/shm
- /dev/sda1 283M 27M 241M 11% /boot
- CompletedProcess(args=['df', '-h'], returncode=0)
- # 需要交给Linux shell自己解析,则:传入命令字符串,shell=True
- >>> subprocess.run("df -h|grep /dev/sda1",shell=True)
- /dev/sda1 283M 27M 241M 11% /boot
- CompletedProcess(args='df -h|grep /dev/sda1', returncode=0)
- 注:看到上面run函数的使用,这边有很多小伙伴有点不解,这边我解释一下:第1种情况是:执行的命令需要让python去解释执行这个命令,执行的命令以及参数,需要以列表的形式传入。第二种情况:但是如果需要交给Linux shell环境去解析的还,这传入命令的字符串,并且声明shell=True即可。
- #########################################
- 2、subprocess.call()
- 作用:执行命令,返回命令的状态,0或者非0
- >>> import subprocess
- >>> res = subprocess.call(["ls","-l"])
- total 26976
- -rw-r--r-- 1 1000 1000 10914 Jan 17 15:57 aclocal.m4
- drwxr-xr-x 5 root root 4096 May 12 14:21 build
- -rwxr-xr-x 1 1000 1000 43940 Jan 17 15:57 config.guess
- >>> res #返回命令的状态
- 0
- #########################################
- 3、subprocess.check_call()
- 作用:执行命令,如果执行结果为0,正常返回,否则抛异常
- >>> import subprocess
- >>> res = subprocess.check_call(["ls","-l"])
- total 26976
- -rw-r--r-- 1 1000 1000 10914 Jan 17 15:57 aclocal.m4
- drwxr-xr-x 5 root root 4096 May 12 14:21 build
- >>> res
- 0
- #########################################
- 4、subprocess.getstatusoutput()
- 作用:接收字符串形式的命令,返回元组形式,第1个元素是执行状态,第二个是命令结果
- >>> import subprocess
- >>> subprocess.getstatusoutput('ls /bin/ls')
- (0, '/bin/ls') #0:执行状态,'bin/ls':执行结果
- #########################################
- 5、subprocess.getoutput()
- 作用:接收字符串形式的命令,并且返回命令的结果
- >>> import subprocess
- >>> subprocess.getoutput('ls /bin/ls')
- '/bin/ls' #返回命令的结果
- #########################################
- 6、subprocess.check_output()
- 作用:执行命令,并且返回结果,不是打印
- >>> import subprocess
- >>> res = subprocess.check_output(["ls","-l"])
- >>> res
- b'total 26976\n-rw-r--r-- 1 1000 1000 10914 Jan 17 15:57 aclocal.m4\n
- drwxr-xr-x 5 root root 4096 May 12 14:21 build\n
- -rwxr-xr-x 1 1000 1000 43940 Jan 17 15:57 config.guess\n
- -rw-r--r-- 1 root root 756903 May 12 14:18 config.log\n' #这边是以字节类型返回的
subprocess.Popen():
其实以上subprocess使用的方法,都是对subprocess.Popen的封装
- 1、stdout
- 作用:标准输出
- >>> import subprocess
- >>> res = subprocess.Popen("df -h",shell=True,stdout=subprocess.PIPE) #需要管道标准输出
- >>> res.stdout.read() #标准输出
- b'Filesystem Size Used Avail Use% Mounted on\n/dev/mapper/VolGroup-
- LogVol00\n 289G 70G 204G 26% /\ntmpfs 64G 0 64G
- 0% /dev/shm\n/dev/sda1 283M 27M 241M 11% /boot\n'
- >>> obj.stdout.close() #关闭标准输出
- #########################################
- 2、stdin
- 作用:标准输入
- >>> import subprocess
- >>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- >>> obj.stdin.write("hello world") #标准输入
- >>> obj.stdin.close() #关闭标准输入
- #这里输入完成了是不是的把他的输出读出来?
- >>> cmd_out = obj.stdout.read() #获取启动的进程的标准输出
- >>> obj.stdout.close() #关闭标准输出
- >>> cmd_error = obj.stderr.read() #获取启动的进程的标准错误
- >>> obj.stderr.close() #关闭启动程序的标准错误
- #########################################
- 3、stderr
- 作用:标准错误
- >>> import subprocess
- >>> res = subprocess.Popen("lm -l",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
- >>> res.stderr.read() #标准输出错误
- '/bin/sh: lm: command not found\n'
- >>> obj.stderr.close() #关闭启动程序的标准错误
- 注意:上面的提到的标准输出都为啥都需要等于subprocess.PIPE,这个又是啥呢?原来这个是一个管道,这个需要画一个图来解释一下:
- #########################################
- 4、poll()
- 作用:定时检查命令有没有执行完毕,执行完毕返回0,没有完毕返回None
- >>> import subprocess
- >>> res = subprocess.Popen("sleep 20;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
- >>> print(res.poll())
- None #没有执行完毕
- >>> print(res.poll())
- 0 #执行完毕
- #########################################
- 5、wait()
- 作用:等待命令执行完成,并且返回结果状态
- >>> res = subprocess.Popen("sleep 20;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
- >>> res.wait()
- ############
- 漫长等待中
- ############
- 0 #等待结束,返回执行结果状态
- #########################################
- 6、terminate()
- 作用:杀掉启动进程
- >>> import subprocess
- >>> res = subprocess.Popen("sleep 20;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
- >>> res.terminate() #杀掉启动的进程
- >>> res.stdout.read() #杀掉后,标准输出为空
- b''
- #########################################
- 7、communicate()
- 作用:执行的过程传数据,没什么用,先忘记它吧!以后用到再说
- >>> import subprocess
- >>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- >>> obj.stdin.write("hello world") #标准输入
- >>> out_error_list = obj.communicate(timeout=10)
- >>> print(out_error_list) #输入的结果
- ('', ' File "<stdin>", line 1\n hello world\n ^\nSyntaxError: invalid syntax\n')
- #########################################
- 8、pid
- 作用:获取当前执行子shell的程序的进程号
- >>> import subprocess
- >>> res = subprocess.Popen("sleep 20;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
- >>> res.pid #获取这个Linux shell的环境的进程号
- 30225
1、注意:上面的提到的标准输出都为啥都需要等于subprocess.PIPE,这个又是啥呢?原来这个是一个管道,这个需要画一个图来解释一下:
2、可用参数
- args:shell命令,可以是字符串或者序列类型(如:list,元组)
- bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
- stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
- preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
- close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
- shell:同上
- cwd:用于设置子进程的当前目录
- env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
- universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
- startupinfo与createionflags只在windows下有效将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
【python】-- json & pickle、xml、requests、hashlib、shelve、shutil、configparser、subprocess的更多相关文章
- 【Python】Json序列化和反序列化模块dumps、loads、dump、load函数介绍
1.json.dumps() json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数. 转换案例: ...
- 【python】json中load和loads区别
相同点 dump 和 dumps 都实现了序列化 load 和 loads 都实现反序列化 变量从内存中变成可存储或传输的过程称之为序列化序列化是将对象状态转化为可保存或可传输格式的过程. 变量内容从 ...
- 【Python】利用正则解析xml练习题
{ "date": "18-03-29 06:04:47", "data": { "deviceType": 1, &q ...
- 【python】 json.dumps() json.dump()的区别
以前写的很简单,只有几句话,最近发现本文是本博客阅读量最大的一篇文章,觉得这样有种把人骗进来的感觉,于是又细化了一些.如果还有不好的地方,欢迎指出. 首先说明基本功能: dumps是将dict转化成s ...
- 【python】json中字典key不可为数值型
遇到了一个很诡异的错误.写一个字典,存入json文件.之后读出判断是否存在key.结果惊奇的发现,同一个key居然存在两次. 原因:json会将数值key转换为unicode 结论:使用json时字典 ...
- 【Python】Windows平台下Python、Pydev连接Mysql数据库
Mysql数据库是跨平台的,不是说Python一定就要连接Mongodb. Python连接Mysql数据库是非常easy的. 首先,你要配置好Python的开发环境,详见<[Python]Wi ...
- 【Python】-NO.98.Note.3.Python -【Python3 解释器、运算符】
1.0.0 Summary Tittle:[Python]-NO.98.Note.3.Python -[Python3 解释器] Style:Python Series:Python Since:20 ...
- 【Python】 零碎知识积累 II
[Python] 零碎知识积累 II ■ 函数的参数默认值在函数定义时确定并保存在内存中,调用函数时不会在内存中新开辟一块空间然后用参数默认值重新赋值,而是单纯地引用这个参数原来的地址.这就带来了一个 ...
- 【Python】-NO.97.Note.2.Python -【Python 基本数据类型】
1.0.0 Summary Tittle:[Python]-NO.97.Note.2.Python -[Python 基本数据类型] Style:Python Series:Python Since: ...
随机推荐
- Java程序中的Log文件配置
log4j.properties文件 log4j.rootLogger=info,stdout,logfile #stdout log4j.appender.stdout=org.apache.log ...
- ASP.NET MVC学习---(四)MVC初窥
前面三篇大幅度的介绍了EF框架 这并不是没有道理的 现在使用mvc开发一般都离不开ef 因为它们相结合可以为你带来完美的体验 当然 前面所描述的仅仅是ef框架的冰山一角 它是一门学问很深的功课 如果你 ...
- 解决dubbo问题:forbid consumer(2)
线下环境经常出现类似这种异常: com.alibaba.dubbo.rpc.RpcException: Forbid consumer 10.0.53.69 access service com.ku ...
- 开关按钮(ToggleButton&Switch)
开关按钮,很实用的小东西. 下面上实例: -------------------------------我是邪恶的分割线--------------------------------------- ...
- python调度框架APScheduler使用详解
# coding=utf-8 """ Demonstrates how to use the background scheduler to schedule a job ...
- GMGC记实(上篇)
24日和25日參加了2014年GMGC大会,整体感觉今年的大会比前2届大会办的更符合听众的需求.由于今年的大会开设了开发人员训练营的分会场.在成都这样一个CP占主流的IT圈中非常有意义.另一点就是在会 ...
- java清除所有微博短链接 Java问题通用解决代码
java实现微博短链接清除,利用正则,目前只支持微博短链接格式为"http://域名/字母或数字8位以内"的链接格式,现在基本通用 如果链接有多个,返回结果中会有多出的空格,请注意 ...
- C#中静态方法和非静态方法的区别
静态方法和非静态方法的区别: 1.静态方法不需要类实例化就可以调用,反之非静态方法需要实例化后才能调用: 2.静态方法只能访问静态成员和方法,非静态方法都可以访问: 3.静态方法不能标记为overri ...
- SELECT * INTO xx FROM x0
insert into a select * from b:--向存在表中插入数据,如果不存在表a报错. select * into a from b:--创建新表的同时插入数据,如果表a存在,报错. ...
- Eclipse 经常使用快捷键
一.File 二.Edit Ctrl + 1 有益写错,让编辑器提醒改动 三.Refactor 抽取为全局变量 Refactor - Convert Local Variable to Field ...