{"id":20976433,"url":"https://github.com/dasydong/python3diff2","last_synced_at":"2025-03-13T09:19:58.417Z","repository":{"id":120127503,"uuid":"234116310","full_name":"DasyDong/python3diff2","owner":"DasyDong","description":"Python2和3的区别","archived":false,"fork":false,"pushed_at":"2020-04-12T03:48:39.000Z","size":20,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-20T05:51:26.433Z","etag":null,"topics":["diff","difference","python2","python3"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DasyDong.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-15T15:54:43.000Z","updated_at":"2024-06-06T13:40:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"862847d7-c570-49fc-9371-3af164c3b5e8","html_url":"https://github.com/DasyDong/python3diff2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DasyDong%2Fpython3diff2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DasyDong%2Fpython3diff2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DasyDong%2Fpython3diff2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DasyDong%2Fpython3diff2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DasyDong","download_url":"https://codeload.github.com/DasyDong/python3diff2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243374734,"owners_count":20280729,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["diff","difference","python2","python3"],"created_at":"2024-11-19T04:53:54.140Z","updated_at":"2025-03-13T09:19:58.391Z","avatar_url":"https://github.com/DasyDong.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"- [此文是实践中的Python3与Python2的不同，快乐并痛苦](#此文是实践中的python3与python2的不同快乐并痛苦)\n- [升级python2到python3](#升级python2到python3)\n    - [Mac版](#mac版)\n        - [安装homebrew](#安装homebrew)\n        - [安装python3](#安装python3)\n        - [升级pip](#升级pip)\n        - [虚机环境virtualenv](#虚机环境virtualenv)\n    - [2to3转换](#2to3转换)\n    - [代码](#代码)\n        - [print](#print)\n        - [UNICODE字符串](#unicode字符串)\n        - [全局函数UNICODE](#全局函数unicode)\n        - [比较运算符](#比较运算符)\n        - [返回列表的字典类方法](#返回列表的字典类方法)\n        - [map-filter-reduce](#mapfilterreduce)\n        - [TRY-EXCEPT](#tryexcept)\n        - [XRANGE](#xrange)\n        - [INPUT](#input)\n        - [函数属性FUNC](#函数属性func)\n        - [IO方法XREADLINES()](#io方法xreadlines)\n        - [lambda函数](#lambda函数)\n        - [全局函数ZIP](#全局函数zip)\n        - [TYPES模块中的常量](#types模块中的常量)\n        - [对元组的列表解析](#对元组的列表解析)\n        - [元类](#元类)\n        - [在python2中使用__future__模块](#在python2中使用__future__模块)\n        - [整除divide](#整除divide)\n        - [next()](#next)\n        - [For循环变量和全局命名空间泄漏](#for循环变量和全局命名空间泄漏)\n        - [INPUT](#input)\n- [包差异](#包差异)\n    - [pylint](#pylint)\n# 此文是实践中的Python3与Python2的不同，快乐并痛苦\n\n\n# 升级python2到python3\n\n## Mac版\n\n查看下当前python版本， 如果已经是Python 3，则跳过\n```\npython --version\n```\n\n### 安装homebrew\n```\n/usr/bin/ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"\n```\n\n### 安装python3\n```\nbrew install python\n```\n\n安装完成后查看下新python版本和位置 ，发现python3会成本默认版本。我的是/usr/local/opt/python/libexec/bin/python\n```\nwhich python\n```\n\n\n### 升级pip\n```\n pip3 install --upgrade pip setuptools wheel\n```\n\n\n```\nIf you need Homebrew's Python 2.7 run\n  brew install python@2\n\nPip, setuptools, and wheel have been installed. To update them run\n  pip3 install --upgrade pip setuptools wheel\n\nYou can install Python packages with\n  pip3 install \u003cpackage\u003e\nThey will install into the site-package directory\n  /usr/local/lib/python3.6/site-packages\n```\n### 虚机环境virtualenv\n之后python的2/3使用都可以自由切换\n```\nvirtualenv venv  //python3\nvirtualenv venv -p python2.7 //python2\n```\n\n***\n\n## 2to3转换\npython3内置2to3命令， 简单的代码可以直接转3\n```\n2to3  -w gmc.py 生成转换的bake文件\n2to3  -w gmc.py 直接覆盖原文件\n2to3  --help\n```\n```\nOptions:\n  -h, --help            show this help message and exit\n  -d, --doctests_only   Fix up doctests only\n  -f FIX, --fix=FIX     Each FIX specifies a transformation; default: all\n  -j PROCESSES, --processes=PROCESSES\n                        Run 2to3 concurrently\n  -x NOFIX, --nofix=NOFIX\n                        Prevent a transformation from being run\n  -l, --list-fixes      List available transformations\n  -p, --print-function  Modify the grammar so that print() is a function\n  -v, --verbose         More verbose logging\n  --no-diffs            Don't show diffs of the refactoring\n  -w, --write           Write back modified files\n  -n, --nobackups       Don't write backups for modified files\n  -o OUTPUT_DIR, --output-dir=OUTPUT_DIR\n                        Put output files in this directory instead of\n                        overwriting the input files.  Requires -n.\n  -W, --write-unchanged-files\n                        Also write files even if no changes were required\n                        (useful with --output-dir); implies -w.\n  --add-suffix=ADD_SUFFIX\n                        Append this string to all output filenames. Requires\n                        -n if non-empty.  ex: --add-suffix='3' will generate\n                        .py3 files.\n\n```\n\n## 代码\n### print\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nprint | print() | 输出一个空白行，python3需要调用不带参数的print() |\nprint 1, 2, |\tprint(1,2, end=' ') |\tpython2中如果使用一个,作为print结尾，将会用空格分割输出的结果，然后在输出一个尾随的空格，而不输回车。python3里，把end=' ' 作为一个关键字传给print()可以实现同样的效果，end默认值为'\\n',所以通过重新指定end参数的值，可以取消在末尾输出回车符号\nprint \u003e\u003e sys.stderr, 1, 2, 3 |\tprint(1, 2, 3, file=sys.stderr\t |python2中，可以通过\u003e\u003epipe_name语法，把输出重定向到一个管道，比如sys.stderr.在python3里，可以通过将管道作为关键字参数file的值传递给print()完成同样的功能。\n\n### UNICODE字符串\npython2中有两种字符串类型：Unicode字符串和非Unicode字符串\nPython3中只有一种类型：Unicode字符串\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nu'PapayaWhip' |\t'PapayaWhip' |\tpython2中的Unicode字符串在python3即为普通字符串\nur'PapayaWhip\\foo' |\tr'PapayWhip\\foo'|\tUnicode原始字符串(使用这种字符串，python不会自动转义反斜线\"\\\")也被替换为普通的字符串，因为在python3里，所有原始字符串都是以unicode编码的。\n\n### 全局函数UNICODE\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nunicode()把对象转换成unicode字符串 \u003cbr\u003e str()把对象转换为非Unicode字符串 |  unicode字符串，所以str()函数即可完成所有的功能\n\n\n### 比较运算符\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\n\u003c\u003e or != |   != |\n[1, 2] \u003e ‘foo’ = False \u003cbr/\u003e (1, 2) \u003e ‘foo’ = True \u003cbr/\u003e [1, 2] \u003e (1, 2) = False | TypeError: unorderable types: list() \u003e str() |Python 3 中当对不可排序类型做比较的时候，会抛出一个类型错误\n\n\n### 返回列表的字典类方法\npython2里，许多字典类方法的返回值是列表。最常用方法有keys, items和values\npython3，所有以上方法的返回值改为动态试图。在一些上下文环境里，这种改变不会产生影响。如果这些方法的返回值被立即传递给另外一个函数，而且那个函数会遍历整个序列，那么以上方法的返回值是列表或视图并不会产生什么不同。如果你期望获得一个被独立寻址元素的列表，那么python3的这些改变将会使你的代码卡住，因为视图不支持索引\n\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\na_dictionary.keys()\t| list(a_dictionary.keys())\t| 使用list()将keys 返回值转换为一个静态列表\na_dictionary.items()  | list(a_dictionary.items()) | 将items返回值转为列表\na_dictionary.iterkeys()\t| \titer(a_dictionary.keys()) | python3不再支持iterkeys,使用iter()将keys()的返回值转换为一个迭代器\n[i for i in a_dictionary.iterkeys()]\t| \t[ i for i in a_dictonary.keys()]\t| \t不需要使用额外的iter()，keys()方法返回的是可迭代的\nmin(a_dictionary.keys())\t| \tno change\t| \t对min(),max(),sum(),list(),tuple(),set(),sorted(),any()和all()同样有效\n重命名或重新组织的模块:\n\n\n### map-filter-reduce\npython2里，filter()方法返回一个列表，这个列表是通过一个返回值为True或False的函数来检测序列里的每一项的值\n\npython3中，filter()函数返回一个迭代器，不再是列表\n\n跟filter()的改变一样，map()函数现在返回一个迭代器,python2中返回一个列表\n\n在python3里，reduce()函数已经从全局名字空间移除，现在被放置在fucntools模块里\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nfilter(a_function, a_sequence) |\tlist(filter(a_function, a_sequence))\nmap(a_function,'PapayaWhip'\t| list(map(a_function, 'PapayaWhip'))\nreduce(a,b,c)\t| from functools import reduce reduce(a, b, c)\n\n### TRY-EXCEPT\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nexcept (RuntimeError, ImportError), e pass|   except(RuntimeError, ImportError) as e\nex.message | 没有message属性\n支持raise MyException, 'error message' | 只支持 raise MyException('error message') |\n\n\n### XRANGE\npython２里，有两种方法获得一定范围内的数字：range(),返回一个列表，还有xrange(),返回一个迭代器\n\npython3　里，range()返回迭代器，xrange()不再存在\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\na_list = range(10)\t| a_list= list(ange(10))\n\n\n### INPUT\npython2有两个全局函数，用在命令行请求用户输入。\n第一个叫input()，它等待用户输入一个python表达式(然后返回结果)。用户输入什么他就返回什么,\n第二个叫做raw_input()，输入结果为字符串形式\npython3 通过input替代了他们，输入结果为字符串形式\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nraw_input()\t| input\t|\n\n### 函数属性FUNC\npython2,函数的代码可用访问到函数本身的特殊属性\n\npython3为了一致性，这些特殊属性被重命名了\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\na_function.func_name    |\ta_function.__name__  |\t__name__属性包含了函数的名字\na_function.func_doc\t  |a_function.__doc__\t  | __doc__包含了函数源代码定义的文档字符串\na_function.func_defaults  |\ta_function.__defaults__\t  |是一个保存参数默认值的元组\na_function.func_dict  |\ta_function.__dict__\t  |__dict__属性是一个支持任意函数属性的名字空间\na_function.func_closure\t  |a_function.__closure__\t  |__closure__属性是由cell对象组成的元组，包含了函数对自由变量的绑定\na_function.func_globals\t  |a_function.__globals__\t  |是对模块全局名字空间的引用\na_function.func_code\t  |a_function.__code__\t  |是一个代码对象，表示编译后的函数体\n\n\n### IO方法XREADLINES()\npython2中，文件对象有一个xreadlines()方法，返回一个迭代器，一次读取文件的一行。这在for循环中尤其实用\n\npython3中，xreadlines()方法不再可用\n\n\n### lambda函数\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nlambda (x,): x + f(x)|\tlambda x1 : x1[0] + f(x1[0])\t|注１\nlambda (x,y): x + f(y)\t|lambda x_y : x_y[0] + f(x_y[1])\t|注２\nlambda (x,(y,z)): x + y + z\t|lambda x_y_z: x_y_z[0] + x_y_z[1][0]+ x_y_z[1][1]\t|注３\nlambda x,y,z: x+y+z |\tunchanged\t|注４\n\n注１：如果定义了一个lambda函数，使用包含一个元素的元组作为参数，python3中，会被转换成一个包含到x1[0]的引用的lambda函数。x1是2to3脚本基于原来元组里的命名参数自动生成的。\n\n注２：使用含有两个元素的元组(x,y)作为参数的lambda函数被转换为x_y,它有两个位置参数，即x_y[0]和x_y[1]\n\n注３：2to3脚本可以处理使用嵌套命名参数的元组作为参数的lambda函数。产生的结果有点晦涩，但python3下和python2的效果是一样的。\n\n注４：可以定义使用多个参数的lambda函数。语法在python3同样有效\n\n\n### 全局函数ZIP\n\npython2，zip()可以使用任意多个序列作为参数，它返回一个由元组构成的列表。第一个元组包含了每个序列的第一个元素，第二个元组包含了每个序列的第二个元素，依次递推\n\npython３中返回一个迭代器，而非列表\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nzip(a,b,c)\t| list(zip(a,b,c)\t| python3中可以通过list函数遍历zip()返回的迭代器，形成列表返回\nd.join(zip(a,b,c))\t| no change\t| 在已经会遍历所有元素的上下文环境里，zip()本身返回的迭代器能够正常工作，2to3脚本检测到后，不再修改\n\n\n### TYPES模块中的常量\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\ntypes.UnicodeType |\tstr\ntypes.StringType\t| bytes\ntypes.DictType |\t\tdict\ntypes.IntType |\t\tint\ntypes.LongType |\t\tint\ntypes.ListType |\t\tlist\ntypes.NoneType |\t\ttype(None)\ntypes.BooleanType |\t\tbool\ntypes.BufferType |\t\tmemoryview\ntypes.ClassType\t |\ttype\ntypes.ComplexType |\t\tcomplex\ntypes.EllipsisType\t |\ttype(Ellipsis)\ntypes.FloatType\t |\tfloat\ntypes.ObjectType |\t\tobject\ntypes.NotImplementedType |\t\ttype(NotImplemented)\ntypes.SliceType\t |\tslice\ntypes.TupleType\t |\ttuple\ntypes.TypeType\t |\ttype\ntypes.XRangeType |\t\trange\n\n\n### 对元组的列表解析\npython2，如果需要编写一个遍历元组的列表解析，不需要在元组值周围加上括号\n\npython3里，这些括号是必需的\n\npython2 | python3 | 备注 |\n:--- | :--- | :---  |\n[ i for i in 1, 2]' | \t'[i for i in (1,2)]\n\n### 元类\npython2里，可以通过在类的声明中定义metaclass参数，或者定义一个特殊的类级别(class-level__metaclass__属性，来创建元类\n\npython3中，__metaclass__属性被取消了\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nclass C(metaclass=PapayaMeta): pass\t |  unchanged\nclass Whip: __metaclass__ = PapayMeta\t | class Whip(metaclass=PapayaMeta): pass\nclass C(Whipper, Beater): __metaclass__ = PapayaMeta | \tclass C(Whipper, Beater, metaclass=PapayMeta): pass\n\n\n### 在python2中使用__future__模块\n```\nall_feature_names = [\n    \"nested_scopes\",\n    \"generators\",\n    \"division\",\n    \"absolute_import\",\n    \"with_statement\",\n    \"print_function\",\n    \"unicode_literals\",\n    \"barry_as_FLUFL\",\n    \"generator_stop\",\n    \"annotations\",\n]\n```\nmodule | python2 | python3 | 备注 |\n:--- | :--- | :--- | :--- |\nfrom future import absolute_import |  import string先当前目录,再系统中查找string | 先在系统中查找， 再在当前查找 |\nfrom future import division | 3 / 4 = 0 | 3 / 4 = 0.75; 3//4 = 0 |\nfrom future import print_function | 不支持print a | print(a)\nfrom __future__ import unicode_literals | print '\\'xxx\\' is unicode?', isinstance('xxx', unicode) \u003e\u003e False | print '\\'xxx\\' is unicode?', isinstance('xxx', unicode) \u003e\u003e True\n\n### 整除divide\n\n**如果你正在移植代码，这个变化是特别危险的。或者你在 Python 2 上执行 Python 3 的代码。因为这个整除的变化表现在它会被忽视（即它不会抛出语法异常）。\n　　因此，我还是倾向于使用一个 float(3)/2 或 3/2.0 代替在我的 Python 3 脚本保存在 Python 2 中的 3/2 的一些麻烦（并且反而过来也一样，我建议在你的 Python 2 脚本中使用 from __future__ import division）**\n\nmodule | python2 | python3 | 备注 |\n:--- |:--- | :--- | :--- |\n3 / 2 | 1 |  1.5\n3 // 2  | 1 | 1\n3 / 2.0 | 1.5 |1.5\n3 // 2.0| 1.0 | 1.0\n\n\n### next()\n\n```\nmy_generator = (letter for letter in 'abcdefg')\n```\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nnext(my_generator) \u003cbr/\u003e my_generator.next()  | next(my_generator) | Python 3 移除了方法.next()\n\n\n### For循环变量和全局命名空间泄漏\n\n好消息：在 Python 3.x 中 for 循环变量不会再导致命名空间泄漏。\n　　在 Python 3.x 中做了一个改变，在 What’s New In Python 3.0 中有如下描述：\n　　“列表推导不再支持 [... for var in item1, item2, ...] 这样的语法。使用 [... for var in (item1, item2, ...)] 代替。也需要提醒的是列表推导有不同的语义： 他们关闭了在 list() 构造器中的生成器表达式的语法糖, 并且特别是循环控制变量不再泄漏进周围的作用范围域.”\n```\ni = 1\nprint 'before: i =', i\nprint 'comprehension: ', [i for i in range(5)]\nprint 'after: i =', i\n```\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\nbefore: i = 1 \u003cbr/\u003e comprehension: [0, 1, 2, 3, 4] \u003cbr/\u003e after: i = 4\u003cbr/\u003e | before: i = 1 \u003cbr/\u003ecomprehension: [0, 1, 2, 3, 4] \u003cbr/\u003eafter: i = 1|\n\n\n### INPUT\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\n\n\n\n***\n\n# 包差异\n\n## pylint\n\n\npython2 | python3 | 备注 |\n:--- | :--- | :--- |\npip install pylint | pip install pylint --upgrade | [pylint]((https://github.com/PyCQA/pylint)) |\n\nPylint can be simply installed by running:\n```\npip install pylint\n```\n\nIf you are using Python 3.6+, upgrade to get full support for your version:\n```\npip install pylint --upgrade\n```\n\n***\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdasydong%2Fpython3diff2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdasydong%2Fpython3diff2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdasydong%2Fpython3diff2/lists"}