国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

編寫兼容 Python 2 和 Python 3 的代碼

wangtdgoodluck / 565人閱讀

摘要:注本文的作者是。原文的地址為該筆記向你展示了編寫不會過時的兼容和的代碼風格。它是在的演講,。基本語法差異為了打印出多個。方方和工具沒有提供一個選項自動完成這個。如果你為了個項目編寫新的代碼庫,你可以用一個字符模塊標記所有的字符字面量。

  

注:本文的作者是 Ed Schofield。原文的地址為: Cheat Sheet: Writing Python 2-3 compatible code

該筆記向你展示了編寫不會過時的兼容 Python 2 和 Python 3 的代碼風格。

它是 Ed Schofield 在 PyCon AU 2014 的演講,“ Writing 2/3 compatible code ”。

最低版本:

Python 2: 2.6+

Python 3: 3.3+

安裝

一些下面的 imports 適用于使用 pip 安裝在 PyPI 上安裝:

import future        # pip install future
import past          # pip install past
import six           # pip install six

以下的腳本也適用于 pip 安裝:

futurize             # pip install futurize
pasteurize           # pip install pasteurize

查看 http://python-future.org 和 https://pythonhosted.org/six/ 獲取更多消息。

基本語法差異

print

# Python 2 only:
print "Hello"
# Python 2 and 3:
print("Hello")

為了打印出多個 strings。 import print_function 來防止 Py2 把它解釋成一個元組。

# Python 2 only:
print "Hello", "Guido"
# Python 2 and 3:
from __future__ import print_function    # (at top of module)

print("Hello", "Guido")
# Python 2 only:
print >> sys.stderr, "Hello"
# Python 2 and 3:
from __future__ import print_function

print("Hello", file=sys.stderr)
# Python 2 only:
print "Hello",
# Python 2 and 3:
from __future__ import print_function

print("Hello", end="")

拋出異常

# Python 2 only:
raise ValueError, "dodgy value"
# Python 2 and 3:
raise ValueError("dodgy value")

使用 traceback 拋出異常:

# Python 2 only:
traceback = sys.exc_info()[2]
raise ValueError, "dodgy value", traceback
# Python 3 only:
raise ValueError("dodgy value").with_traceback()
# Python 2 and 3: option 1
from six import reraise as raise_
# or
from future.utils import raise_

traceback = sys.exc_info()[2]
raise_(ValueError, "dodgy value", traceback)
# Python 2 and 3: option 2
from future.utils import raise_with_traceback

raise_with_traceback(ValueError("dodgy value"))

異常鏈 (PEP 3134):

# Setup:
class DatabaseError(Exception):
    pass
# Python 3 only
class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise DatabaseError("failed to open") from exc
# Python 2 and 3:
from future.utils import raise_from

class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise_from(DatabaseError("failed to open"), exc)
# Testing the above:
try:
    fd = FileDatabase("non_existent_file.txt")
except Exception as e:
    assert isinstance(e.__cause__, IOError)    # FileNotFoundError on Py3.3+ inherits from IOError

捕獲異常

# Python 2 only:
try:
    ...
except ValueError, e:
    ...
# Python 2 and 3:
try:
    ...
except ValueError as e:
    ...

除法

整除(rounding down):

# Python 2 only:
assert 2 / 3 == 0
# Python 2 and 3:
assert 2 // 3 == 0

“True division” (float division):

# Python 3 only:
assert 3 / 2 == 1.5
# Python 2 and 3:
from __future__ import division    # (at top of module)

assert 3 / 2 == 1.5

“Old division” (i.e. compatible with Py2 behaviour):

# Python 2 only:
a = b / c            # with any types
# Python 2 and 3:
from past.utils import old_div

a = old_div(b, c)    # always same as / on Py2

長整數

短整數在 Python 3 中已經去除了,并且 long 已經變成了 int(沒有 Lrepr 后面)

# Python 2 only
k = 9223372036854775808L

# Python 2 and 3:
k = 9223372036854775808
# Python 2 only
bigint = 1L

# Python 2 and 3
from future.builtins import int
bigint = int(1)

為了測試一個值是否是整數(任何類型):

# Python 2 only:
if isinstance(x, (int, long)):
    ...

# Python 3 only:
if isinstance(x, int):
    ...

# Python 2 and 3: option 1
from future.builtins import int    # subclass of long on Py2

if isinstance(x, int):             # matches both int and long on Py2
    ...

# Python 2 and 3: option 2
from past.builtins import long

if isinstance(x, (int, long)):
    ...

八進制常量

0644     # Python 2 only
0o644    # Python 2 and 3

Backtick repr

`x`      # Python 2 only
repr(x)  # Python 2 and 3

元類

class BaseForm(object):
    pass

class FormType(type):
    pass
# Python 2 only:
class Form(BaseForm):
    __metaclass__ = FormType
    pass
# Python 3 only:
class Form(BaseForm, metaclass=FormType):
    pass
# Python 2 and 3:
from six import with_metaclass
# or
from future.utils import with_metaclass

class Form(with_metaclass(FormType, BaseForm)):
    pass
Strings 和 bytes

Unicode(text) 字符字面量

如果你更新一個已經存在的 Python 2 的代碼庫,為所有的字符字面量使用 u 做前綴作為 unicode 的標記可能會更好。

# Python 2 only
s1 = "The Zen of Python"
s2 = u"きたないのよりきれいな方がいい
"

# Python 2 and 3
s1 = u"The Zen of Python"
s2 = u"きたないのよりきれいな方がいい
"

futurizepython-modernize 工具沒有提供一個選項自動完成這個。

如果你為了個項目編寫新的代碼庫,你可以用一個 unicode 字符模塊標記所有的字符字面量。

# Python 2 and 3
from __future__ import unicode_literals    # at top of module

s1 = "The Zen of Python"
s2 = "きたないのよりきれいな方がいい
"

查看 http://python-future.org/unicode_literals.html 這里獲取更多的關于討論使用哪種風格的討論。

字節-字符 字面量

# Python 2 only
s = "This must be a byte-string"

# Python 2 and 3
s = b"This must be a byte-string"

To loop over a byte-string with possible high-bit characters, obtaining each character as a byte-string of length 1:

# Python 2 only:
for bytechar in "byte-string with high-bit chars like xf9":
    ...

# Python 3 only:
for myint in b"byte-string with high-bit chars like xf9":
    bytechar = bytes([myint])

# Python 2 and 3:
from future.builtins import bytes
for myint in bytes(b"byte-string with high-bit chars like xf9"):
    bytechar = bytes([myint])

chr().encode("latin-1") 其中的任何一個都可以用于把一個 int 轉換成一個 1-char byte string

# Python 3 only:
for myint in b"byte-string with high-bit chars like xf9":
    char = chr(myint)    # returns a unicode string
    bytechar = char.encode("latin-1")

# Python 2 and 3:
from future.builtins import bytes, chr
for myint in bytes(b"byte-string with high-bit chars like xf9"):
    char = chr(myint)    # returns a unicode string
    bytechar = char.encode("latin-1")    # forces returning a byte str

basestring

# Python 2 only:
a = u"abc"
b = "def"
assert (isinstance(a, basestring) and isinstance(b, basestring))

# Python 2 and 3: alternative 1
from past.builtins import basestring    # pip install future

a = u"abc"
b = b"def"
assert (isinstance(a, basestring) and isinstance(b, basestring))
# Python 2 and 3: alternative 2: refactor the code to avoid considering
# byte-strings as strings.

from future.builtins import str
a = u"abc"
b = b"def"
c = b.decode()
assert isinstance(a, str) and isinstance(c, str)
# ...

unicode

# Python 2 only:
templates = [u"blog/blog_post_detail_%s.html" % unicode(slug)]
# Python 2 and 3: alternative 1
from future.builtins import str
templates = [u"blog/blog_post_detail_%s.html" % str(slug)]
# Python 2 and 3: alternative 2
from future.builtins import str as text
templates = [u"blog/blog_post_detail_%s.html" % text(slug)]

StringIO

# Python 2 only:
from StringIO import StringIO
# or:
from cStringIO import StringIO

# Python 2 and 3:
from io import BytesIO     # for handling byte strings
from io import StringIO    # for handling unicode strings
Imports relative to a package

假設包的結構是這樣的:

mypackage/
    __init__.py
    submodule1.py
    submodule2.py

submodule1.py 的代碼如下:

# Python 2 only:
import submodule2
# Python 2 and 3:
from . import submodule2
# Python 2 and 3:
# To make Py2 code safer (more like Py3) by preventing
# implicit relative imports, you can also add this to the top:
from __future__ import absolute_import
字典
heights = {"Fred": 175, "Anne": 166, "Joe": 192}

Iterating through dict keys/values/items

迭代字典的鍵:

# Python 2 only:
for key in heights.iterkeys():
    ...
# Python 2 and 3:
for key in heights:
    ...

迭代字典的值:

# Python 2 only:
for value in heights.itervalues():
    ...
# Idiomatic Python 3
for value in heights.values():    # extra memory overhead on Py2
    ...
# Python 2 and 3: option 1
from future.builtins import dict

heights = dict(Fred=175, Anne=166, Joe=192)
for key in heights.values():    # efficient on Py2 and Py3
    ...
# Python 2 and 3: option 2
from future.builtins import itervalues
# or
from six import itervalues

for key in itervalues(heights):
    ...

迭代字典元素:

# Python 2 only:
for (key, value) in heights.iteritems():
    ...
# Python 2 and 3: option 1
for (key, value) in heights.items():    # inefficient on Py2
    ...
# Python 2 and 3: option 2
from future.builtins import iteritems
# or
from six import iteritems

for (key, value) in iteritems(heights):
    ...

字典的鍵/值/元素 作為一個列表

字典的鍵作為一個列表:

# Python 2 only:
keylist = heights.keys()
assert isinstance(keylist, list)
# Python 2 and 3:
keylist = list(heights)
assert isinstance(keylist, list)

字典的值作為一個列表:

# Python 2 only:
heights = {"Fred": 175, "Anne": 166, "Joe": 192}
valuelist = heights.values()
assert isinstance(valuelist, list)
# Python 2 and 3: option 1
valuelist = list(heights.values())    # inefficient on Py2
# Python 2 and 3: option 2
from future.builtins import dict

heights = dict(Fred=175, Anne=166, Joe=192)
valuelist = list(heights.values())
# Python 2 and 3: option 3
from future.utils import listvalues

valuelist = listvalues(heights)
# Python 2 and 3: option 4
from future.utils import itervalues
# or
from six import itervalues

valuelist = list(itervalues(heights))

字典元素作為一個列表:

# Python 2 and 3: option 1
itemlist = list(heights.items())    # inefficient on Py2
# Python 2 and 3: option 2
from future.utils import listitems

itemlist = listitems(heights)
# Python 2 and 3: option 3
from future.utils import iteritems
# or
from six import iteritems

itemlist = list(iteritems(heights))
自定義類的行為

自定義迭代器

# Python 2 only
class Upper(object):
    def __init__(self, iterable):
        self._iter = iter(iterable)
    def next(self):          # Py2-style
        return self._iter.next().upper()
    def __iter__(self):
        return self

itr = Upper("hello")
assert itr.next() == "H"     # Py2-style
assert list(itr) == list("ELLO")
# Python 2 and 3: option 1
from future.builtins import object

class Upper(object):
    def __init__(self, iterable):
        self._iter = iter(iterable)
    def __next__(self):      # Py3-style iterator interface
        return next(self._iter).upper()  # builtin next() function calls
    def __iter__(self):
        return self

itr = Upper("hello")
assert next(itr) == "H"      # compatible style
assert list(itr) == list("ELLO")
# Python 2 and 3: option 2
from future.utils import implements_iterator

@implements_iterator
class Upper(object):
    def __init__(self, iterable):
        self._iter = iter(iterable)
    def __next__(self):                  # Py3-style iterator interface
        return next(self._iter).upper()  # builtin next() function calls
    def __iter__(self):
        return self

itr = Upper("hello")
assert next(itr) == "H"
assert list(itr) == list("ELLO")

自定義 __str__ 方法

# Python 2 only:
class MyClass(object):
    def __unicode__(self):
        return "Unicode string: u5b54u5b50"
    def __str__(self):
        return unicode(self).encode("utf-8")

a = MyClass()
print(a)    # prints encoded string
# Python 2 and 3:
from future.utils import python_2_unicode_compatible

@python_2_unicode_compatible
class MyClass(object):
    def __str__(self):
        return u"Unicode string: u5b54u5b50"

a = MyClass()
print(a)    # prints string encoded as utf-8 on Py2
Unicode string: 孔子

自定義 __nonzero__ 對比 __bool__ 方法

# Python 2 only:
class AllOrNothing(object):
    def __init__(self, l):
        self.l = l
    def __nonzero__(self):
        return all(self.l)

container = AllOrNothing([0, 100, 200])
assert not bool(container)
# Python 2 and 3:
from future.builtins import object

class AllOrNothing(object):
    def __init__(self, l):
        self.l = l
    def __bool__(self):
        return all(self.l)

container = AllOrNothing([0, 100, 200])
assert not bool(container)
列表對迭代器

xrange

# Python 2 only:
for i in xrange(10**8):
    ...
# Python 2 and 3: forward-compatible
from future.builtins import range
for i in range(10**8):
    ...
# Python 2 and 3: backward-compatible
from past.builtins import xrange
for i in xrange(10**8):
    ...

range

# Python 2 only
mylist = range(5)
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: forward-compatible: option 1
mylist = list(range(5))            # copies memory on Py2
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: forward-compatible: option 2
from future.builtins import range

mylist = list(range(5))
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: option 3
from future.utils import lrange

mylist = lrange(5)
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: backward compatible
from past.builtins import range

mylist = range(5)
assert mylist == [0, 1, 2, 3, 4]

map

# Python 2 only:
mynewlist = map(f, myoldlist)
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 1
# Idiomatic Py3, but inefficient on Py2
mynewlist = list(map(f, myoldlist))
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 2
from future.builtins import map

mynewlist = list(map(f, myoldlist))
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 3
try:
    import itertools.imap as map
except ImportError:
    pass

mynewlist = list(map(f, myoldlist))    # inefficient on Py2
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 4
from future.utils import lmap

mynewlist = lmap(f, myoldlist)
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 5
from past.builtins import map

mynewlist = map(f, myoldlist)
assert mynewlist == [f(x) for x in myoldlist]

imap

# Python 2 only:
from itertools import imap

myiter = imap(func, myoldlist)
assert isinstance(myiter, iter)
# Python 3 only:
myiter = map(func, myoldlist)
assert isinstance(myiter, iter)
# Python 2 and 3: option 1
from future.builtins import map

myiter = map(func, myoldlist)
assert isinstance(myiter, iter)
# Python 2 and 3: option 2
try:
    import itertools.imap as map
except ImportError:
    pass

myiter = map(func, myoldlist)
assert isinstance(myiter, iter)

zip, izip

As above with zip and itertools.izip.

filter, ifilter

As above with filter and itertools.ifilter too

其他內建函數

File IO with open()

# Python 2 only
f = open("myfile.txt")
data = f.read()              # as a byte string
text = data.decode("utf-8")

# Python 2 and 3: alternative 1
from io import open
f = open("myfile.txt", "rb")
data = f.read()              # as bytes
text = data.decode("utf-8")  # unicode, not bytes

# Python 2 and 3: alternative 2
from io import open
f = open("myfile.txt", encoding="utf-8")
text = f.read()    # unicode, not bytes

reduce()

# Python 2 only:
assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5
# Python 2 and 3:
from functools import reduce

assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5

raw_input()

# Python 2 only:
name = raw_input("What is your name? ")
assert isinstance(name, str)    # native str
# Python 2 and 3:
from future.builtins import input

name = input("What is your name? ")
assert isinstance(name, str)    # native str on Py2 and Py3

input()

# Python 2 only:
input("Type something safe please: ")
# Python 2 and 3
from future.builtins import input
eval(input("Type something safe please: "))

警告:使用上面任何一個都是不安全的

file()

# Python 2 only:
f = file(pathname)
# Python 2 and 3:
f = open(pathname)

# But preferably, use this:
from io import open
f = open(pathname, "rb")   # if f.read() should return bytes
# or
f = open(pathname, "rt")   # if f.read() should return unicode text

execfile()

# Python 2 only:
execfile("myfile.py")
# Python 2 and 3: alternative 1
from past.builtins import execfile

execfile("myfile.py")
# Python 2 and 3: alternative 2
exec(compile(open("myfile.py").read()))

# This can sometimes cause this:
#     SyntaxError: function ... uses import * and bare exec ...
# See https://github.com/PythonCharmers/python-future/issues/37

unichr()

# Python 2 only:
assert unichr(8364) == "€"
# Python 3 only:
assert chr(8364) == "€"
# Python 2 and 3:
from future.builtins import chr
assert chr(8364) == "€"

intern()

# Python 2 only:
intern("mystring")
# Python 3 only:
from sys import intern
intern("mystring")
# Python 2 and 3: alternative 1
from past.builtins import intern
intern("mystring")
# Python 2 and 3: alternative 2
try:
    from sys import intern
except ImportError:
    pass
intern("mystring")

apply()

args = ("a", "b")
kwargs = {"kwarg1": True}
# Python 2 only:
apply(f, args, kwargs)
# Python 2 and 3: alternative 1
f(*args, **kwargs)
# Python 2 and 3: alternative 2
from past.builtins import apply
apply(f, args, kwargs)

chr()

# Python 2 only:
assert chr(64) == b"@"
assert chr(200) == b"xc8"
# Python 3 only: option 1
assert chr(64).encode("latin-1") == b"@"
assert chr(0xc8).encode("latin-1") == b"xc8"
# Python 2 and 3: option 1
from future.builtins import chr

assert chr(64).encode("latin-1") == b"@"
assert chr(0xc8).encode("latin-1") == b"xc8"
# Python 3 only: option 2
assert bytes([64]) == b"@"
assert bytes([0xc8]) == b"xc8"
# Python 2 and 3: option 2
from future.builtins import bytes

assert bytes([64]) == b"@"
assert bytes([0xc8]) == b"xc8"

cmp()

# Python 2 only:
assert cmp("a", "b") < 0 and cmp("b", "a") > 0 and cmp("c", "c") == 0
# Python 2 and 3: alternative 1
from past.builtins import cmp
assert cmp("a", "b") < 0 and cmp("b", "a") > 0 and cmp("c", "c") == 0
# Python 2 and 3: alternative 2
cmp = lambda(x, y): (x > y) - (x < y)
assert cmp("a", "b") < 0 and cmp("b", "a") > 0 and cmp("c", "c") == 0

reload()

# Python 2 only:
reload(mymodule)
# Python 2 and 3
from imp import reload
reload(mymodule)
標準庫

StringIO 模塊

# Python 2 only
from StringIO import StringIO
from cStringIO import StringIO
# Python 2 and 3
from io import BytesIO
# and refactor StringIO() calls to BytesIO() if passing byte-strings

http 模塊

# Python 2 only:
import httplib
import Cookie
import cookielib
import BaseHTTPServer
import SimpleHTTPServer
import CGIHttpServer

# Python 2 and 3:
from future.standard_library import hooks
with hooks():
    import http.client
    import http.cookies
    import http.cookiejar
    import http.server

urllib 模塊

這個使用 urllib 的示例,相同的模式也適用于其他的已經移除的模塊(一個完整的列表 http://python-future.org/standard_library_imports.html#list-of-standard-library-modules )

# Python 2 only:
from urlparse import urlparse
from urllib import urlencode
# Python 3 only:
from urllib.parse import urlparse, urlencode
# Python 2 and 3: alternative 1
from future.standard_library import hooks

with hooks():
    from urllib.parse import urlparse, urlencode
# Python 2 and 3: alternative 2
from future.moves.urllib.parse import urlparse, urlencode
# or
from six.moves.urllib.parse import urlparse, urlencode
# Python 2 and 3: alternative 3
try:
    from urllib.parse import urlparse, urlencode
except ImportError:
    from urlparse import urlparse
    from urllib import urlencode

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/37336.html

相關文章

  • Python入門-Python簡介

    摘要:年月宣布支持時間延長到年。更詳細的發布列表參閱官網的版本號分為三段,形如。其中表示大版本號,一般當整體重寫,或出現不向后兼容的改變時,增加表示功能更新,出現新功能時增加表示小的改動如修復了某個,只要有修改就增加。年公司正式發布。 < 返回索引頁 Python語言簡介 Python介紹及發展 介紹 Python 官方網站:https://www.python.org/, 大家可以到此處下...

    Java_oldboy 評論0 收藏0
  • 如何用PEP 8編寫優雅Python代碼

    摘要:如果需要在二元運算符周圍做換行操作,例如和,那么需要將換行操作放在前面,這條規則源于數學,數學家同意在二元運算符之前換行以可提高可讀性,比較以下兩個例子。在二元運算符之前換行可以讓代碼更加具有可讀性,所鼓勵這種方式。 原文地址:How to Write Beautiful Python Code With PEP 8 作者:Jasmine Finer 翻譯:howie6879 ...

    seanHai 評論0 收藏0
  • 細數Python三十年技術演變史——萌發于小眾,崛起于AI

    摘要:作者宋天龍來源科技大本營導語一切都始于年的那個圣誕節,的誕生并不算恰逢其時,它崛起充滿了機遇巧合,也有其必然性。年的圣誕節,開始編寫語言的編譯器。年發布的標志著的框架基本確定。年月發布了系列的最后一個版本,主版本號為。 showImg(https://segmentfault.com/img/remote/1460000019862276); 作者 | 宋天龍來源 | AI科技大本營 ...

    tuniutech 評論0 收藏0
  • 如何用Python進行數據分析?

    摘要:編程基礎要學習如何用進行數據分析,數據分析師建議第一步是要了解一些的編程基礎,知道的數據結構,什么是向量列表數組字典等等了解的各種函數及模塊。數據分析師認為數據分析有的工作都在處理數據。 showImg(https://segmentfault.com/img/bVbnbZo?w=1024&h=653); 本文為CDA數據分析研究院原創作品,轉載需授權 1.為什么選擇Python進行數...

    lifefriend_007 評論0 收藏0
  • Python - 收藏集 - 掘金

    摘要:首發于我的博客線程池進程池網絡編程之同步異步阻塞非阻塞后端掘金本文為作者原創,轉載請先與作者聯系。在了解的數據結構時,容器可迭代對象迭代器使用進行并發編程篇二掘金我們今天繼續深入學習。 Python 算法實戰系列之棧 - 后端 - 掘金原文出處: 安生??? 棧(stack)又稱之為堆棧是一個特殊的有序表,其插入和刪除操作都在棧頂進行操作,并且按照先進后出,后進先出的規則進行運作。 如...

    546669204 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<