之前使用过python2.x版本,其中的编码问题颇为头疼,本篇主要描述python3中的编码,如果称Python2的编码为殇,那么Python3的编码就应该为美了。
想要解决python2中的编码问题,最直接有效的方法就是将所有外部的字符串转变为unicode格式,再在python内部了流转。python3正是在这方面做了很大的优化。
python3中也有2种编码格式,分别为str与byte,这里的str相当于2中的unicode,byte相当于2中的str。再者python3将python源代码编码从ascii改成了utf-8,从外部接收的编码自动转化成了str(2中的unicode),大大减少产生编码异常的点。与2一样,3中的编码原则就是将外部接收的字符编码成str(unicode字符),输出时再编码成bytes编码。光说没用,我用实验证明。
bytes/str/unicode区别
python3的bytes与str
bytes表示字符的原始8位值,str表示Unicode字符。将unicode字符表示为二进制数据(原始8位值),最常见的编码方式就是UTF-8。python2与3中的unicode字符没有和特定的二进制编码相关联,因此需要使用encode方法。
在python3中bytes与str是绝对不会等价的,即使字符内容为””,因此在传入字符序列时必须注意其类型。
python2的str与unicode
str表示字符的原始8位值,unicode表示Unicode字符。
在python2中,如果str只包含7位ASCII字符(英文字符),那么unicode与str实例类似于同一种类型(等价的),那么在这种情况下,以下几种操作是正常的:
- 可以用+号连接str与unicode
- 可以用=与!=来判断str与unicode
- 可以用’%s’来表示Unicode实例
系统以及源代码编码
3.x已经把源代码编码以及系统编码从ascii都变成了utf-8,避免了中文报错。
>>> import sys
>>> print(sys.getdefaultencoding())
utf-8
>>> print(sys.getfilesystemencoding())
utf-8
>>>
其次,我们可以看到我们定义的a为str(相当于2.x中unicode),而它在windows控制台输出时也没有因为编码问题而报错。
>>> a="你好"
>>>print(a)
你好
字符串编码
>>> a="你好"
>>> print(type(a))
<class 'str'>
>>> b=a.encode("utf-8")
>>> print(type(b))
<class 'bytes'>
>>>
我们可以看到,3.x中的str格式类似于2.x中的unicode,而2.x中的str相当于3.x中的bytes.
import urllib.request
f = urllib.request.urlopen("http://www.xxx.com").readlines()
print(type(f[10]))
print(f[10])
print(f[10].decode('utf-8'))
返回的是bytes格式的,只要decode转化为str就ok了。
文件编码
f = open('1.txt').read()
print(type(f))
print(f)
print(type(f.decode('utf-8')))
print(f.decode('utf-8'))
结果:从文件中读取出来的是str(2.x中的unicode),因此不用转码。
open函数
注意python2中open句柄是str(原始二进制)的,而python3中是str(unicode字符),因此一下代码在python2中正常,在python3中会报错:
with open("test","w") as w:
w.write("123")
因为python3中,要求传入的值为str类型,而不是bytes类型,open函数自带encoding方法。
解决方法:
with open("test","wb") as w:
w.write("123")
同理,read函数也是一样,写成rb,就可以兼容2与3了。
奇技
文件操作
输出一个目录下所有文件名称
def search(paths):
if os.path.isdir(paths): #如果是目录
files=os.listdir(paths) #列出目录中所有的文件
for i in files:
i=os.path.join(paths,i) #构造文件路径
search(i) #递归
elif os.path.isfile(paths): #如果是文件
print paths #输出文件名
文件查找
import glob
print glob.glob(r"E:/*.txt") #返回的是一个列表
查找文件只用到三个匹配符:”*”, “?”, “[]“
”*”匹配0个或多个字符;
”?”匹配单个字符;
”[]“匹配指定范围内的字符,如:[0-9]匹配数字
查找指定名称的文件夹的路径
def search(paths,file_name,tag,lists):
if os.path.isdir(paths): #如果是目录
if file_name==tag: #如果目录名称为tag
lists.append(paths) #将该路径添加到列表中
else: #如果目录名称不为tag
try:
files_list=os.listdir(paths) #列出目录中所有的文件
for file_name in files_list:
path_new=os.path.join(paths,file_name) #构造文件路径
search(path_new,file_name,tag,lists) #递归
except: #遇到特殊目录名时会报错
pass
elif os.path.isfile(paths): #如果是文件
pass
return lists
数据操作
判断数据类型
isinstance("123",(int,long,float,complex)
字符串(string)
字符串推导
a="True"
b=a if a=="True" else "False"
>>>print b
True
format方法拼接字符串与变量
a="{test} abc {test2}".format(test="123",test2="456")
>>>>print a
123 abc 456
或者:
a="{},{}".format(1,2)
>>>>>print a
1,2
去掉小数点后面的数字
a=1.21311
b=Int(math.floor(a))
字符串倒置
>>> a = "codementor"
>>> a[::-1]
字符串首字母变大写
info = 'ssfef'
print info.capitalize()
print info.title()
返回一个字符串居中,并使用空格填充至长度width的新字符串。
"center string".center(width) #width设置为控制台宽度,可控制输出的字符串居中。
列举所有字母
print string.ascii_uppercase 所有大写字母
print string. ascii_lowercase 所有小写字母
print string.ascii_letters 所有字母(包括大小写)
列表(list)
列表去重
ids = [1,4,3,3,4,2,3,4,5,6,1]
ids = list(set(ids))
列表运算
a=[1,2,3]
b=[3,4,5]
set(a)&set(b) 与
set(a)|set(b) 或
set(a)-set(b) 非
单列表元素相加
a = ["Code", "mentor", "Python", "Developer"]
>>> print " ".join(a)
Code mentor Python Developer
多列表元素分别相加
list1 = ['a', 'b', 'c', 'd']
list2 = ['p', 'q', 'r', 's']
>>> for x, y in zip(list1,list2):
print x, y
ap
bq
cr
ds
将嵌套列表转换成单一列表
a = [[1, 2], [3, 4], [5, 6]]
>>> import itertools
>>> list(itertools.chain.from_iterable(a))
[1, 2, 3, 4, 5, 6]
列表内元素相加
a=[1,2,3](数字)
sum(a)
产生a-z的字符串列表
map(chr,range(97,123))
列表推导
if+else配合列表解析
[i if i >5 else -i for i in range(10)]
多层嵌套列表
a=[[1,2],[3,4]]
b=[for j in i for i in a]
print b
[1,2,3,4]
字典操作(dict)
筛选出值重复的key
list1=self.dict_ip.items()
ddict=defaultdict(list)
for k,v in list1:
ddict[v].append(k)
list2=[(i,ddict[i]) for i in ddict if len(ddict[i])>1]
dict_ns=dict(list2)
字典排序(py2)
file_dict={"a":1,"b":2,"c":3}
file_dict_new=sorted(file_dict.iteritems(), key=operator.itemgetter(1),reverse=True) ##字典排序,reverse=True由高到低,itemgetter(1)表示按值排序,为0表示按key排序。
然后当我们导入a这个模块的时候,可以输出dir(a)看看
>>> import p
>>> print dir(p)
['__author__', '__builtins__', '__doc__', '__file__', '__name__', '__package__']
>>> print p.__author__
nmask