快速导航
首先使用工具 2to3 转换
12to3 目录名 -w -n
-
问题: 如果在python2项目里使用了python3的写法,比如在 python2 里的
print("test"), 使用 2to3 就会转换成1print(("test"))所以需要找到
print((并修复该转换(其实不转也没什么问题)1ag -Gpy 'print((' -
修复:
1- print(("test")) 2+ print("test")
string
-
问题1:
1module 'string' has no attribute 'letters -
修复:
1- string.letters 2+ string.ascii_letters -
问题2:
1'str' object has no attribute 'decode' -
修复:
1- str.decode(xxx) 2+ str.encode(xxx).decode('unicode_escape')
比值问题
1slice indices must be integers or None or have an __index__ method
-
问题: python2里
3/2返回的是整型1python3里3/2返回的是浮点型1.5 -
修复:
1print(3//2) 2# 或者 3print(int(3/2))
编码问题
sys.setdefaultencoding('utf-8')
python2里的 sys.setdefaultencoding('utf-8') 需要删除
encode、decode
-
问题:
1LookupError: 'base64' is not a text encoding; use codecs.encode() to handle arbitrary codecs -
语法:
-
python2
1Python 2.7.16 (default, Dec 21 2020, 23:00:36) 2[GCC Apple LLVM 12.0.0 (clang-1200.0.30.4) [+internal-os, ptrauth-isa=sign+stri on darwin 3Type "help", "copyright", "credits" or "license" for more information. 4>>> a = "a" 5>>> a.encode("base64") 6'YQ==\n' 7>>> b = a.encode("base64") 8>>> b.decode("base64") 9'a' -
python3
1Python 3.7.4 (default, Sep 7 2020, 15:30:33) 2[Clang 11.0.3 (clang-1103.0.32.29)] on darwin 3Type "help", "copyright", "credits" or "license" for more information. 4>>> a = "a" 5>>> a.encode("base64") 6Traceback (most recent call last): 7 File "<stdin>", line 1, in <module> 8LookupError: 'base64' is not a text encoding; use codecs.encode() to handle arbitrary codecs
-
-
修复:
1import base64 2 3def b64encode(s): 4 if isinstance(s, bytes): 5 return base64.b64encode(s) 6 return base64.b64encode(s.encode('utf-8')).decode('utf-8') 7 8def b64decode(s): 9 return base64.b64decode(s).decode('utf-8')1- x.encode('base64') 2- x.decode('base64') 3+ b64encode(x) 4+ b64decode(x)
编码转换
utf-8转换为gbk
-
python2
1'hello世界'.decode('utf-8').encode('gbk') -
python3
1''.join([chr(i) for i in 'hello世界'.encode('gbk')]) 2# 或者 3'hello世界'.encode('gbk').decode('unicode_escape')
cmp
python3里cmp内置函数不再存在,需要自定义函数
1def cmp(a, b):
2 return (a > b) - (a < b)
sorted
python2里sorted有一个cmp参数,python3里统一为key参数
-
python2
1sorted(keys, lambda x, y: cmp(len(x), len(y)), reverse=True) -
python3
1from functools import cmp_to_key 2 3sorted(keys, key=cmp_to_key(lambda x, y: cmp(len(x), len(y))), reverse=True)注意:
must use keyword argument for key function
Exception
-
python3里没有
.message, 所以需要修改e.message为str(e) -
python3无法使用
as直接对变量赋值1def main(): 2 err = None 3 try: 4 raise ValueError("sss") 5 - except Exception as err: 6 - pass 7 + except Exception as e: 8 + err = e 9 return err 10 11print(main())1UnboundLocalError: local variable 'err' referenced before assignment
SSL
-
问题:
1File "/usr/local/lib/python3.6/dist-packages/OpenSSL/SSL.py", line 1591, in set_tlsext_host_name 2raise TypeError("name must be a byte string") -
解决
1- s.set_tlsext_host_name(hostname) 2+ s.set_tlsext_host_name(hostname.encode('utf-8'))
file.read
1with open("test.txt", "rb") as f:
2 for i in f.read(10):
3 print(i, type(i))
-
python2
1('\x7f', <type 'str'>) 2('E', <type 'str'>) 3('\x00', <type 'str'>) -
python3
1127 <class 'int'> 269 <class 'int'> 30 <class 'int'> -
两者之间的转换
1ord('\x7f') == 127 2chr(127) == '\x7f'
redis
python3里默认取出的值是 bytes 类型, 需要客户端添加 decode_responses=True 参数, 取出的值才是 str 类型
requests
自定义编码请求
https://github.com/psf/requests/issues/4133
post json
-
python2
1data = {'test': 'hello世界'.decode('utf-8').encode('gbk')} 2headers = {'Content-Type': 'application/json;charset=gbk'} 3data=json.dumps(data,ensure_ascii=False) 4rsp = requests.post("/dynamic/test", data=data,headers=headers) -
python3
1data = {'test': 'hello世界'} 2headers = {'Content-Type': 'application/json;charset=gbk'} 3data=json.dumps(data, ensure_ascii=False) 4resp = requests.post("/dynamic/test", data=data.encode('gbk'), headers=headers)
post form
-
python2
1data = {'test': 'hello世界'.decode('utf-8').encode('gbk')} 2headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=gbk'} 3resp = requests.post("/dynamic/test", data=data,headers=headers) -
python3
1data = {'test': 'hello世界'.encode('gbk')} 2headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=gbk'} 3resp = requests.post("/dynamic/test", data=data,headers=headers)
响应编码
1resp = requests.get("...")
2print(type(resp.content))
3print(type(resp.text))
-
python2
resp.content是str类型,resp.text是unicode类型 -
python3
resp.content是bytes类型,resp.text是str类型
请求headers顺序
根源主要在 requests.structures 的 CaseInsensitiveDict 类
1from requests.structures import CaseInsensitiveDict
2from collections import OrderedDict
3
4headers = {
5 'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4',
6 'Accept-Encoding': 'gzip, deflate, sdch',
7 'cache': 0,
8 'host': 'Host1.com',
9 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
10 'User-Agent': 'curl/7.29.0',
11 'Host': 'Host2.com'
12}
13print(headers)
14
15r = CaseInsensitiveDict()
16r.update(headers)
17print(r)
不同的python版本结果会输出
-
python2
1OrderedDict([('Accept-Language', 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4'), ('Accept-Encoding', 'gzip, deflate, sdch'), ('cache', 0), ('Host', 'Host2.com'), ('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'), ('User-Agent', 'curl/7.29.0'), ('host', 'Host1.com')]) 2CaseInsensitiveDict({'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4', 'Accept-Encoding': 'gzip, deflate, sdch', 'cache': 0, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'curl/7.29.0', 'host': 'Host1.com'}) -
python3
1OrderedDict([('Accept-Language', 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4'), ('Accept-Encoding', 'gzip, deflate, sdch'), ('cache', 0), ('host', 'Host1.com'), ('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'), ('User-Agent', 'curl/7.29.0'), ('Host', 'Host2.com')]) 2{'Accept-Language': 'en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4', 'Accept-Encoding': 'gzip, deflate, sdch', 'cache': 0, 'Host': 'Host2.com', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'curl/7.29.0'}
所以如果要兼容两个版本,需要显示的传入
1headers = OrderedDict(sorted(headers.items(), key=lambda x: x[0]))
django
1- for k, v in request.GET.iterlists():
2+ for k, v in request.GET.lists():
并且k和v的类型在python3里默认为 str , 不需要使用 k.encode("utf-8") 进行转换
知识共享署名-非商业性使用-相同方式共享4.0国际许可协议