python3的编码和奇技

之前使用过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

版权声明:本文为abc_soul原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。