Diferencias y cambios en la gramática de python2 y python3
Casi todos los programas de Python 2 requieren algunas modificaciones para funcionar correctamente en un entorno de Python 3. Para simplificar este proceso de conversión, Python 3 incluye un script práctico llamado 2to3 (Utility Script), que toma el archivo de origen de tu programa de Python 2 como una entrada y lo convierte automáticamente en Python 3. El estudio de caso: Porting chardet to Python 3 describe cómo se ejecuta este script, y luego muestra algunas situaciones en las que no se puede reparar automáticamente.
En Python 2, print es un enunciado. Cualquier cosa que quieras emitir, solo tienes que ponerlo después de la palabra clave print. En Python 3, print () es una función. Al igual que otras funciones, print () requiere que le des lo que quieres emitir como un parámetro.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | print() | |
| ② | print 1 | print(1) |
| ③ | print 1,2 | print(1,2) |
| ④ | print 1,2, | print(1,2,end=' ') |
| ⑤ | print >>sys.stderr,1,2,3 | print(1,2,3, file=sys.stderr) |
- Para obtener una línea en blanco, se requiere la llamada de print sin parámetros ((()。
- Para obtener un valor separado, se necesita que este valor sea un parámetro como print ().
- Para la salida de los dos valores separados por un espacio, se puede usar el parámetro print ((()
En Python 2, si usas una coma ((() como final de la frase print, se separará el resultado de la salida con un espacio, y luego en la salida de un espacio de seguimiento (((trailing space), sin carriage return (((). En Python 3, se puede lograr el mismo efecto al pasar end=' ' como un parámetro de palabra clave a print ((). El valor predeterminado de la parámetro de extremo es '\n', por lo que se puede cancelar el carriage return al final de la salida mediante la reasignación del valor del parámetro de extremo. - En Python 2, se puede redirigir la salida a un pipeline usando la sintaxis>>pipe_name, por ejemplo, sys.stderr. En Python 3, se puede hacer lo mismo al pasar el valor del pipeline a print (() como un parámetro de palabras clave. El valor predeterminado del parámetro de archivo es std.stdout, por lo que volver a especificar su valor hará que print (() se extienda a otro pipeline.
Python 2 tiene dos tipos de cadenas:Las cadenas de UnicodeyCadenas no en UnicodePython 3 sólo tiene un tipo:Las cadenas de Unicode。
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | u'PapayaWhip' | 'PapayaWhip' |
| ② | ur'PapayaWhip\foo' | r'PapayaWhip\foo' |
Las cadenas de Unicode en Python 2 son cadenas normales en Python 3, ya que en Python 3 las cadenas son siempre en Unicode.
Las cadenas originales de Unicode ((raw string) (() son las que Python no traduce automáticamente hacia atrás"") también se sustituye por una cadena ordinaria, ya que en Python 3, todas las cadenas originales están codificadas en Unicode。
Python 2 tiene dos funciones globales que pueden forzar la conversión de objetos en cadenas: unicode ((() que convierte objetos en cadenas de Unicode, y str ((() que convierte objetos en cadenas no Unicode. Python 3 tiene un solo tipo de cadena, la cadena de Unicode, por lo que la función str ((() puede hacer todo.La función unicode() ya no existe en Python 3.)
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | unicode(anything) | str(anything) |
Python 2 tiene los tipos int y long preparados para números no flotantes. El valor máximo del tipo int no puede exceder de sys.maxint, y este valor máximo es relevante para la plataforma. Se puede definir el tipo entero largo añadiendo una L al final del número, que es, evidentemente, más amplio que el rango de números representado por el tipo int. En Python 3, solo hay un tipo entero int, que en la mayoría de los casos es muy parecido al tipo entero largo de Python 2. Como ya no existen dos tipos de enteros, no es necesario usar una gramática especial para distinguirlos.
Leer más: PEP 237: Unificar la longitud y la longitud.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | x = 1000000000000L | x = 1000000000000 |
| ② | x = 0xFFFFFFFFFFFFL | x = 0xFFFFFFFFFFFF |
| ③ | long(x) | int(x) |
| ④ | type(x) is long | type(x) is int |
| ⑤ | isinstance(x,long) | isinstance(x,int) |
En Python 2, el entero decimal largo se sustituye por el entero decimal común en Python 3.
En Python 2, el integer de decimoseis dígitos largo se sustituye por el integer ordinario de decimoseis dígitos en Python 3.
En Python 3, los tipos de extensión ya no existen, por lo que es mejor que los tipos de extensión se utilicen.No existe la función natural long (). Para forzar la conversión de una variable a un entero, se puede usar la función int ().。
Compruebe si una variable es entera, obtenga su tipo de datos y compare con una int del tipo ((no es larga)).
También puedes usar la función insinstance (()) para comprobar el tipo de datos; enfatizando una vez más, use int, en lugar de long, para comprobar el tipo de entero ▽.
Python 2 soporta <> como sinónimo de !=. Python 3 sólo soporta!=, ya no soporta <> <unk>
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | if x <> y: | if x != y: |
| ② | if x <> y<> z: | if x != y!= z: |
- Simplemente comparar.
- Comparación entre tres valores relativamente complejos.
En Python 2, los objetos del diccionario tienen_key() método utilizado para probar si el diccionario contiene una clave específica (((key) ❚ El Python 3 ya no soporta este método ❚ Necesitas usarinEl operador.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_dictionary.has_key('PapayaWhip') | 'PapayaWhip' in a_dictionary |
| ② | a_dictionary.has_key(x) or a_dictionary.has_key(y) | x in a_dictionary or y in a_dictionary |
| ③ | a_dictionary.has_key(x or y) | (x or y) in a_dictionary |
| ④ | a_dictionary.has_key(x + y) | (x + y) in a_dictionary |
| ⑤ | x + a_dictionary.has_key(y) | x + (y in a_dictionary) |
- La forma más simple.
- El operador or tiene menor prioridad que el operador in, por lo que no es necesario agregar paréntesis.
- Por otro lado, por la misma razón, la prioridad de or es menor que la prioridad de in, por lo que se añade un paréntesis. Nota: el código aquí es completamente diferente al de la línea anterior._Una tecla de un diccionario.
- El operador in tiene menor prioridad que el operador +, por lo que esta forma en el código técnicamente no requiere de paréntesis, pero se añade 2 a 3.
- Esta forma requiere de paréntesis, ya que in tiene menos prioridad que +。
En Python 2, muchos métodos de clase diccionario devuelven una lista. Los métodos más usados tienen claves, elementos y valores. En Python 3, todos los métodos anteriores devuelven valores a una vista dinámica. En algunos contextos, este cambio no tiene efecto. Si los valores devueltos de estos métodos se transmiten de inmediato a otra función, y esa función recorre toda la secuencia, el valor devuelto de los métodos anteriores es la vista de la lista o la vista y no produce ninguna diferencia.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_dictionary.keys() | list(a_dictionary.keys()) |
| ② | a_dictionary.items() | list(a_dictionary.items()) |
| ③ | a_dictionary.iterkeys() | iter(a_dictionary.keys()) |
| ④ | [i for iin a_dictionary.iterkeys()] | [i for iin a_dictionary.keys()] |
| ⑤ | min(a_dictionary.keys()) | no change |
- el uso de la función list () para convertir el valor de retorno de keys () en una lista estática, por consideraciones de seguridad, 2to3 puede reportar errores. Este tipo de código es efectivo, pero es menos eficiente para usar vistas. Deberías revisar el código después de la conversión para ver si necesitas una lista, tal vez las vistas también puedan hacer el mismo trabajo.
2 , que es otra vista de la conversión de los métodos de () para () a la lista. 2to3 para valores () también es la misma conversión de los métodos que devuelven valores. - Python 3 ya no admite las teclas iter (((). Si es necesario, use iter ((() para convertir el valor de retorno de las teclas ((() en un iterador.
4, 2to3 es capaz de identificar que el método iterkeys () se utiliza en el análisis de la lista, y luego convertirlo en el método keys () de Python 3 sin necesidad de usar un iter adicional () para empaquetar su valor de retorno. Esto es posible porque la vista es iterable.
5 2to3 también reconoce que los retornos de los métodos keys (() se transmiten inmediatamente a otra función que recorre toda la secuencia, por lo que no hay necesidad de convertir los retornos de keys (() a una lista. Por el contrario, las funciones min (() recorren con gusto la vista. Este proceso es igualmente efectivo para min ((), max ((), sum ((), list ((), tuple ((), set ((), sorted ((), any (() y all (().
Desde Python 2 hasta Python 3, algunos módulos de la biblioteca estándar han sido renombrados. Algunos módulos relacionados entre sí también se han combinado o reorganizado para que la asociación sea más lógica.
- http
En Python 3, varios módulos HTTP relacionados se combinan en un paquete separado llamado http.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import httplib | import http.client |
| ② | import Cookie | import http.cookies |
| ③ | import cookielib | import http.cookiejar |
| ④ | import BaseHTTPServer <br> import SimpleHTTPServer <br> import CGIHttpServer | import http.server |
El módulo http.client implementa una biblioteca subyacente que se puede usar para solicitar recursos HTTP y analizar las respuestas HTTP.
El módulo http.cookies proporciona una interfaz Python para obtener las cookies enviadas a través de la cabecera HTTP Set-Cookie
Los navegadores populares almacenan las cookies en forma de archivos en el disco, que pueden ser manipulados por el módulo http.cookiejar.
El módulo http.server implementa un servidor HTTP básico
- urllib
Python 2 tiene algunos módulos para analizar, codificar y obtener URLs, pero estos módulos se superponen entre sí como si fueran un colchón de ratón. En Python 3, estos módulos se reconstruyen y se agrupan en un paquete separado, urllib.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import urllib | import urllib.request <br> urllib.parse,urllib.error |
| ② | import urllib2 | import urllib.request <br> urllib.error |
| ③ | import urlparse | import urllib.parse |
| ④ | import robotparser | import urllib.robotparser |
| ⑤ | from urllib import FancyURLopener <br> from urllib import urlencode | from urllib.request import FancyURLopener <br> from urllib.parse import urlencode |
| ⑥ | from urllib2 import Request <br> from urllib2 import HTTPError | from urllib.request import Request <br> from urllib.error import HTTPError |
Anteriormente, el módulo urllib de Python 2 tenía una variedad de funciones, incluyendo urlopen () para obtener datos, y también era útil para dividir la URL en sus componentes, las funciones splitype () y splituser (). En el nuevo paquete urllib, estas funciones están organizadas de manera más lógica. 2to3 modificará la invocación de estas funciones para adaptarlas al nuevo esquema de denominación.
En Python 3, los módulos anteriores de urllib2 se incorporaron al paquete urllib. Al mismo tiempo, las cosas que más te gustan en urllib2 aparecerán en Python 3 como build_El método opener, el objeto de solicitud, el HTTPBasicAuthHandler y los amigos.
El módulo urllib.parse de Python 3 contiene todas las funciones de análisis del módulo urlparse original de Python 2.
El módulo urllib.robotparse analiza el archivo robots.txt.
La clase FancyURLopener, que maneja el redireccionamiento HTTP y otros códigos de estado, sigue siendo válida en el módulo urllib.request de Python 3. La función .urlencode () se ha trasladado a urllib.parse.
El objeto Request sigue siendo válido en urllib.request, pero las constantes como HTTPError se han trasladado a urllib.error.
¿He mencionado que 2to3 también reescribiría tus llamadas a funciones? Por ejemplo, si tu código de Python 2 importa el módulo urllib, y llama a la función urllib.urlopen (()) para obtener datos, 2to3 modificará la frase de importación y las llamadas a funciones al mismo tiempo.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import urllib print urllib.urlopen('http://diveintopython3.org/').read() | import urllib.request, urllib.parse, urllib.error <br> print(urllib.request.urlopen('http://diveintopython3.org/').read()) |
- dbm
Todos los clones de DBM ahora están en un paquete separado, el dbm. Si necesitas una variante específica de uno de ellos, como GNUDBM, puedes importar el módulo adecuado en el paquete dbm.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import dbm | import dbm.ndbm |
| ② | import gdbm | import dbm.gnu |
| ③ | import dbhash | import dbm.bsd |
| ④ | import dumbdbm | import dbm.dumb |
| ⑤ | import anydbm <br> import whichdb | import dbm |
- xmlrpc
XML-RPC es un método de nivel ligero para realizar llamadas remotas de RPC a través del protocolo HTTP. Algunas de las bibliotecas de implementación de los clientes y servidores XML-RPC de XML-RPC ahora se combinan en paquetes independientes, xmlrpc.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import xmlrpclib | import xmlrpc.client |
| ② | import DocXMLRPCServer <br> import SimpleXMLRPCServer | import xmlrpc.server |
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | try:<br> import cStringIO as StringIO <br>except ImportError: <br> import StringIO | import io |
| ② | try:<br> import cPickle as pickle <br>except ImportError: <br> import pickle | import pickle |
| ③ | import _builtin_ | import builtins |
| ④ | import copy_reg | import copyreg |
| ⑤ | import Queue | import queue |
| ⑥ | import SocketServer | import socketserver |
| ⑦ | import ConfigParser | import configparser |
| ⑧ | import repr | import reprlib |
| ⑨ | import commands | import subprocess |
- En Python 2, lo que normalmente haces es intentar importar cStringIO primero como una alternativa a StringIO, y si eso falla, importar StringIO. No lo hagas en Python 3; el módulo io te ayudará con esto. Encontrará la implementación más rápida disponible y la usará automáticamente.
- En Python 2, importar la implementación más rápida de Pickle también es una forma útil de hacer lo mismo. En Python 3, el módulo de Pickle se encargará de ello automáticamente por ti, así que no lo hagas más.
3, el módulo de construcciones contiene las funciones globales, clases y constantes que se usan en todo el lenguaje Python. Redefinir una función en el módulo de construcciones significa redefinir esta función global en todas partes. Esto suena muy poderoso, pero también es aterrador. - El módulo copyreg añade soporte para el módulo pickle para los tipos personalizados de usuario definidos en el lenguaje C.
- El módulo de cola permite una cola de productores y consumidores (queue multi-producer, multi-consumer).
El módulo socketserver proporciona una clase básica general para la implementación de varios servidores de sockets.
7 El módulo configparser es utilizado para analizar el archivo de configuración de estilo INI.
8, el módulo reprlib reimplementa la función repr () y añade un control sobre la longitud de la cadena antes de que se interrumpa.
El módulo de subproceso le permite crear subprocesos, conectarse a sus pipelines y obtener su valor de retorno.
- Importación relativa en el paquete
Un paquete es una entidad individual compuesta por un grupo de módulos relacionados entre sí. En Python 2, para hacer referencia mutua a módulos dentro del mismo paquete, se usa import foo o from foo import Bar. El intérprete de Python 2 busca foo.py en el directorio actual y luego busca en la ruta de búsqueda de Python ((sys.path). En Python 3 el proceso es un poco diferente. Python 3 no busca primero en la ruta actual, sino que busca directamente en la ruta de búsqueda de Python.
Supongamos que tienes varios archivos en el mismo directorio:
chardet/
|
+--init.py
|
+--constants.py
|
+--mbcharsetprober.py
|
+--universaldetector.py
Ahora supongamos que universaldetector.py necesita importar toda la clase constants.py, además de una clase de mbcharsetprober.py. ¿Qué harías?
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | import constants | from .import constants |
| ② | from mbcharsetprober import MultiByteCharSetProber | from .mbcharsetprober import MultiByteCharsetProber |
- Cuando necesites importar un módulo entero desde otra parte del paquete, usa la nueva sintaxis de importar desde. El parámetro . . aquí representa el camino relativo entre el archivo actual (universaldetector.py) y el archivo que quieres importar (constants.py). En este ejemplo, ambos archivos están en la misma carpeta, por lo que se usa una sola frase. También puedes importar desde el directorio padre (import anothermodule) o desde el subdirectorio.
- Para importar una clase o función específica de otro módulo directamente al espacio de nombres de tu módulo, agrega el camino relativo al nombre del módulo que necesita ser importado y quita la última línea diagonal (slash). En este ejemplo, mbcharsetprober.py está en el mismo directorio que universaldetector.py, por lo que el nombre del camino relativo es un punto. También puedes importar desde el directorio padre (from .. import anothermodule) o desde el subdirectorio.
En Python 2, el iterador tiene una forma de next (), que se utiliza para devolver el siguiente elemento de la secuencia. En Python 3 esto también funciona, pero ahora hay una nueva función global next (), que usa un iterador como parámetro.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | anIterator.next() | next(anIterator) |
| ② | a_function_that_returns_an_iterator().next() | next(a_function_that_returns_an_iterator()) |
| ③ | class A:<br> def next(self):<br> pass | class A:<br> def next(self):<br> pass| |
| ④ | class A:<br> def next(self, x, y):<br> pass | no change |
| ⑤ | next = 42<br>for an_iterator in a_sequence_of_iterators:<br> an_iterator.next() | next = 42<br>for an_iterator in a_sequence_of_iterators:<br> an_iterator.next() |
En el ejemplo más simple, ya no llamas el método next (() de un iterador, sino que ahora pasas el iterador mismo como un parámetro a la función global next (() <unk>.
2. Si tienes una función que devuelve el valor de un iterador, llama a esta función y pasa el resultado como un parámetro a la siguiente () función.
3 Si defines tu propia clase y luego la usas como un iterador, en Python 3 puedes definir métodos especiales para la clase y usarlos como un iterador._next¿Qué es lo que está sucediendo?
4. Si una clase definida tiene un next () que usa uno o más parámetros, no se mueve cuando se ejecuta 2to3. Esta clase no se puede usar como iterador porque su método next () tiene parámetros.
5, esto es un poco complicado. Si se da la casualidad de que hay una variable local llamada next, en Python 3 tiene una prioridad superior a la función global next ((() }}. En este caso, se necesita un método especial para llamar al iterador.next() para obtener el siguiente elemento de la secuencia。(O, también puedes reorganizar el código para que el nombre de la variable local no se llame next, pero 2to3 no lo hará por ti。)
En Python 2, el método filter() devuelve una lista que se obtiene mediante una función que devuelve un valor de verdadero o falso para detectar cada elemento de la secuencia. En Python 3, la función filter() devuelve un iterador, que ya no es una lista.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | filter(a_function, a_sequence) | list(filter(a_function, a_sequence)) |
| ② | list(filter(a_function, a_sequence)) | no change |
| ③ | filter(None, a_sequence) | [i for iin a_sequence if i] |
| ④ | for i in filter(None, a_sequence): | no change |
| ⑤ | [i for iin filter(a_function, a_sequence)] | no change |
1, en el caso más simple, 2to3 envuelve el filter () con una función list () que recorre sus parámetros y devuelve una lista.
2 , sin embargo, si la invocación de filter (() ya está en el paquete list ((), 2to3 ya no lo procesará, ya que en este caso es irrelevante si el valor devuelto de filter (()) es un iterador.
3. para tratar con la gramática particular de filter ((None, ...) 2to3 convierte esta invocación de manera gramaticalmente equivalente a la de la lista.
4. Como el ciclo for recorre toda la secuencia, no hay necesidad de hacer más modificaciones.
5. Como en el caso anterior, no es necesario hacer modificaciones, ya que el análisis de la lista recorre toda la secuencia, incluso si el filtro () devuelve un iterador, puede funcionar como el filtro () anterior que devuelve la lista.
Al igual que con el cambio de filter, la función map ahora devuelve un iterador. En Python 2, devuelve una lista.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | map(a_function,'PapayaWhip') | list(map(a_function,'PapayaWhip')) |
| ② | map(None,'PapayaWhip') | list('PapayaWhip') |
| ③ | map(lambda x: x+1,range(42)) | [x+1for x in range(42)] |
| ④ | for i in map(a_function, a_sequence): | no change |
| ⑤ | [i for iin map(a_function,a_sequence)] | no change |
En el caso más sencillo, 2to3 utiliza una función list () para envasar la llamada map () [2].
2. para una gramática especial de map ((None, ...) similar a la de filter ((None, ...) 2to3 la convertirá en una llamada de valor equivalente que utiliza list (()
3, si el primer parámetro de map () es una función lambda, 2to3 lo convertirá equivalentemente en una resolución de lista.
4. No es necesario hacer cambios en el ciclo for que recorre toda la secuencia.
5. Una vez más, no hay necesidad de hacer modificaciones aquí, ya que el análisis de la lista recorre toda la secuencia, aunque el valor de retorno de map () sea un iterador y no una lista, puede funcionar correctamente.
En Python 3, la función reduce (()) ha sido eliminada del espacio de nombres global y ahora se coloca en el módulo fucntools。
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | reduce(a, b, c) | from functools import reduce reduce(a, b, c) |
Python 2 tiene una función global llamada apply (), que usa una función f y una lista[a, b, c] como argumentos, y devuelve el valor f ((a, b, c) <unk>. También puedes llamar directamente a esta función y añadir un asterisco (((*En Python 3, la función apply ((() ya no existe; se debe usar el sistema de marcado con estrellas.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | apply(a_function, a_list_of_args) | a_function(*a_list_of_args) |
| ② | apply(a_function, a_list_of_args, a_dictionary_of_named_args) | a_function(*a_list_of_args,**a_dictionary_of_named_args) |
| ③ | apply(a_function, a_list_of_args+ z) | a_function(*a_list_of_args+ z) |
| ④ | apply(aModule.a_function, a_list_of_args) | aModule.a_function(*a_list_of_args) |
1, la forma más simple, se puede hacer a través de una lista de parámetros como[a, b, c]) antes de añadir un asterisco para llamar a la función。 esto es equivalente a la función apply ((() de Python 2。
En Python 2, la función apply() en realidad puede llevar 3 argumentos: una función, una lista de argumentos y un diccionario de nombres de argumentos. En Python 3, puedes añadir un asterisco antes de la lista de argumentos:), añadir dos asteriscos antes de los parámetros de nombre del diccionario**En la actualidad, la mayoría de los bloggers no tienen acceso a los medios de comunicación.
3. El operador + se usa aquí como función de la lista de conexiones, y tiene más prioridad que el operador, por lo que no es necesario añadir paréntesis adicionales alrededor de a_list_of_args + z.
4, el script 2to3 es lo suficientemente inteligente como para convertir las llamadas complejas de apply (), incluyendo las llamadas de funciones en el módulo de importación <unk>.
En Python 2, se puede usar la función intern () para limitar su función en una cadena para lograr una optimización de rendimiento. En Python 3, la función intern () se transfiere al módulo sys.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | intern(aString) | sys.intern(aString) |
-
Declaraciones de exec
Al igual que la sentencia print se convierte en una función en Python 3, la sentencia exec también lo hace. La función .exec () utiliza una cadena que contiene código Python arbitrario como parámetro y luego la ejecuta como si se ejecutara una sentencia o expresión.
| Notes | Python 2 | Python 3 |
|---|
|①|exec codeString|exec(codeString)
|②|exec codeString in a_global_namespace|exec(codeString, a_global_namespace)|
|③|exec codeString in a_global_namespace, a_local_namespace|exec(codeString, a_global_namespace,a_local_namespace)|
1, en su forma más simple, porque exec (() es ahora una función y no una sentencia, 2to3 rodearía este código en forma de cadena con paréntesis。
2. La instrucción exec de Python 2 puede especificar un espacio de nombres, y el código se ejecutará en este espacio privado de objetos globales. Python 3 también tiene esta función; solo tiene que pasar este espacio de nombres como segundo parámetro a la función exec ().
3, lo que es aún más sorprendente es que la frase exec en Python 2 también puede especificar un espacio de nombres local (como por ejemplo, una variable declarada en una función). En Python 3, la función exec () también tiene esta función.
Al igual que las anteriores declaraciones de exec, las declaraciones de execfile en Python 2 también pueden usar cadenas como ejecutar código de Python. En Python 3, las declaraciones de execfile se han eliminado. Si realmente desea ejecutar el código de Python en un archivo (pero no desea importarlo), puede hacerlo abriendo el archivo, leyendo su contenido y luego llamando la función compile (global) para forzar el compilador de Python Interpreter y luego llamar a la nueva función exec (global).
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | execfile('a_filename') | exec(compile(open('a_filename').read(),'a_filename','exec')) |
En Python 2, para obtener una representación de una cadena de un objeto arbitrario, hay una forma de envasar el objeto en un contrapunto ((por ejemplo:xEn Python 3, esta habilidad sigue existiendo, pero ya no se puede usar el recuento para obtener esta cadena. Se necesita usar la función global repr ().
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | `x` | repr(x) |
| ② | `'PapayaWhip' + `2`` | repr('PapayaWhip'+ repr(2)) |
- Recuerde que x puede ser cualquier cosa: una clase, una función, un módulo, un tipo de datos básico, etc.
- En Python 2, los recuerdos de comillas pueden ser embebidos, lo que da lugar a la confusa (pero efectiva) expresión △ 2to3 que es lo suficientemente inteligente como para convertir esta invocación embebida en la función repr ().
Desde Python 2 a Python 3, la sintaxis para capturar anomalías ha cambiado un poco.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | try:<br> import mymodule<br>except ImportError, e<br> pass | try:<br> import mymodule<br>except ImportError as e:<br> pass |
| ② | try:<br> import mymodule<br>except (RuntimeError, ImportError), e<br> pass | try:<br> import mymodule<br>except (RuntimeError, ImportError) as e:<br> pass |
| ③ | try:<br> import mymodule<br>except ImportError:<br> pass | no change |
| ④ | try:<br> import mymodule<br>except:<br> pass | no change |
1 , Python 3 usa una nueva palabra clave, as。, que se añade una coma después del tipo de excepción en Python 2.
2. La palabra clave as también puede usarse para capturar varios tipos de anomalías a la vez.
3. Si captas una excepción, pero no te preocupas por acceder al objeto de excepción en sí mismo, la sintaxis de Python 2 y Python 3 es la misma.
4 Similarmente, si usas un método de seguridad para capturar todas las excepciones, la sintaxis de Python 2 y Python 3 es la misma.
5. Cuando se importa un módulo (o la mayoría de las otras situaciones), no se debe usar este método (refiriéndose al fallback anterior). De lo contrario, el programa puede capturar excepciones como KeyboardInterrupt (interrumpir el programa si el usuario presiona Ctrl-C), lo que hace que el desbloqueo sea más difícil.
En Python 3, hay un pequeño cambio en la sintaxis para lanzar excepciones personalizadas.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | raise MyException | unchanged |
| ② | raise MyException,'error message' | raise MyException('error message') |
| ③ | raise MyException,'error message', a_traceback | raise MyException('errormessage').with_traceback(a_traceback) |
| ④ | raise 'error message' | unsupported |
- Ejecutar excepciones sin el mensaje de error personalizado por el usuario, que en su forma más simple no cambia la gramática.
- Cuando se quiere lanzar una excepción con un mensaje de error personalizado por el usuario, el cambio es evidente. Python 2 usa una coma para separar las excepciones de los mensajes de error; Python 3 pasa los mensajes de error a las excepciones como parámetros.
- Python 2 soporta una gramática más compleja para lanzar una excepción con un rastreo de pila personalizado por el usuario. En Python 3 también se puede hacer esto, pero la gramática es completamente diferente.
- En Python 2, puedes arrojar una excepción sin clase de excepción, con solo un mensaje de excepción. En Python 3, esta forma ya no es soportada. 2to3 te advertirá que no puede corregir automáticamente esta sintaxis.
En Python 2, el generador tiene una técnica de throw (). La invocación a_generator.throw () lanza una excepción cuando el generador se detiene, y luego devuelve el siguiente valor obtenido por la función de generador. En Python 3, esta función sigue siendo disponible, pero con una gramática un poco diferente.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_generator.throw(MyException) | no change |
| ② | a_generator.throw(MyException,'error message') | a_generator.throw(MyException('error message')) |
| ③ | a_generator.throw('error message') | unsupported |
En su forma más simple, el generador arroja excepciones sin el mensaje de error personalizado por el usuario. En este caso, no hay cambios en la sintaxis de Python 2 a Python 3.
2. Si el generador lanza una excepción con un mensaje de error personalizado por el usuario, se necesita transmitir este mensaje de error a la clase de excepciones para instanciarla.
3. Python 2 también admite excepciones que solo arrojan información de excepciones. Python 3 no admite esta sintaxis, y 2to3 muestra un mensaje de advertencia que le dice que necesita corregir el código manualmente.
En Python 2, hay dos formas de obtener números dentro de un rango: range (), que devuelve una lista, y range (), que devuelve un iterador. En Python 3, range (), que devuelve el iterador, y xrange (), ya no existen.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | xrange(10) | range(10) |
| ② | a_list = range(10) | a_list = list(range(10)) |
| ③ | [i for iin xrange(10)] | [i for iin range(10)] |
| ④ | for i in range(10): | no change |
| ⑤ | sum(range(10)) | no change |
1, en el caso más simple, 2to3 simplemente convertiría xrange (..) en range (..)
2. Si tu código de Python 2 usa range (), 2to3 no sabe si necesitas una lista, o si un iterador también funciona. Por precaución, 2to3 puede cometer errores y luego usar list () para forzar la conversión de los valores devueltos de range () al tipo de lista.
3. Si la función xrange () se encuentra en la resolución de la lista, no es necesario convertir su valor de retorno en una lista, ya que la resolución de la lista es igual para el iterador.
4 Similarmente, el ciclo for también actúa en el iterador, por lo que no cambia nada aquí.
La función sum ((() funciona en el iterador, por lo que 2to3 no hace ninguna modificación aquí. Al igual que el método de clase de diccionario que devuelve el valor como vista (((view) y no como lista, esto también se aplica a min (((), max (((), sum (((), list (((), tuple (((), set (((), sorted (((), any (((), all (())
Python 2 tiene dos funciones globales para solicitar la entrada del usuario en la línea de comandos. La primera, llamada input (), espera a que el usuario introduzca una expresión de Python (y luego devuelve el resultado). La segunda, llamada raw_input (), lo que el usuario introduce es lo que devuelve.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | raw_input() | input() |
| ② | raw_input('prompt') | input('prompt') |
| ③ | input() | eval(input()) |
1, en su forma más simple, raw_input (() se sustituye por input (() }}.
En Python 2, la función raw_input (()) puede especificar un indicador como un parámetro. En Python 3 se conserva esta función.
3. Si realmente quieres pedirle a un usuario que introduzca una expresión en Python y calcular el resultado, puedes llamar a la función input ((() y enviar el valor devuelto a eval ((() <unk>.
En Python 2, el código de la función puede acceder a las propiedades especiales de la función misma. En Python 3, estas propiedades especiales fueron renombradas por consistencia.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | a_function.func_name | a_function._name_ |
| ② | a_function.func_doc | a_function._doc_ |
| ③ | a_function.func_defaults | a_function._defaults_ |
| ④ | a_function.func_dict | a_function._dict_ |
| ⑤ | a_function.func_closure | a_function._closure_ |
| ⑥ | a_function.func_globals | a_function._globals_ |
| ⑦ | a_function.func_code | a_function._code_ |
1、name atributo ((originalfunc_name) contiene el nombre de la función。
2、doc atributo ((originalfuncdoc) contiene la cadena de documentos que usted define en el código fuente de la función ((docstring)
3、__defaults__attribute ((originalfunc_defaults) es un subgrupo que guarda los valores predeterminados de los parámetros.
4、__dict_El atributo _[[func_dict]] es un espacio de nombres que admite atributos de funciones arbitrarias.
5、__closure__attribute (func_closure) es un subconjunto de objetos de celda que contiene la vinculación de una función a una variable libre.
6、__globals__attribute ((originalfunc_globals) es una referencia al espacio de nombres global de módulos, en el que la función misma está definida.
7、__code__attribute (originalfunc_code) es un objeto de código que representa un cuerpo de funciones compilado.
En Python 2, los objetos de archivo tienen un método xreadlines () que devuelve un iterador que lee una línea de archivo a la vez. Esto es especialmente útil en el ciclo for. De hecho, las versiones posteriores de Python 2 agregaron esta función a los objetos de archivo mismos.
En Python 3, el método xreadlines ((() ya no está disponible. 2to3 puede resolver situaciones sencillas, pero algunos casos de borde requieren intervención manual.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | for line in a_file.xreadlines(): | for line in a_file: |
| ② | for line in a_file.xreadlines(5): | no change (broken) |
1, si antes se llamaban xreadlines sin parámetros (), 2to3 lo convertiría en el objeto del archivo en sí mismo. En Python 3, el código después de esta conversión puede hacer lo mismo que antes: leer una línea del archivo una vez y luego ejecutar el cuerpo del ciclo for.
2. Si antes usaste un argumento ((número de líneas leídas por vez) para llamar a xreadlines ((), 2to3 no puede hacer la conversión de Python 2 a Python 3 para ti, tu código fallará de esta manera: AttributeError: '_io.TextIOWrapper' object has no attribute 'xreadlines'. Puedes cambiar manualmente los xreadlines a readlines para que el código funcione en Python 3. El método readline en Python 3 devuelve el iterador, por lo que no es tan eficiente como los xreadlines en Python 2.
En Python 2 se puede definir una función lambda anónima, que permite a esta función recibir varios parámetros al especificar el número de elementos de un subgrupo como argumento. De hecho, el intérprete de Python 2 desempaqueta este subgrupo en argumentos denominados, y luego se puede citarlos en la función lambda. En Python 3 todavía se puede transmitir un subgrupo como argumento de la función lambda, pero el intérprete de Python no lo analiza como un parámetro denominado.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | lambda (x,): x+ f(x) | lambda x1: x1[0]+f(x1[0]) |
| ② | lambda (x, y): x+f(y) | lambda x_y: x_y[0]+f(x_y[1]) |
| ③ | lambda (x,(y,z)): x+ y+ z | lambda x_y_z: x_y_z[0]+x_y_z[1][0]+ x_y_z[1][1] |
| ④ | lambda x, y, z: x+y + z | unchanged |
1, si se ha definido una función lambda, que utiliza un grupo de elementos que contiene un elemento como un parámetro, en Python 3, se convertirá en un grupo de elementos que contiene hasta x1[La función lambda que se cita en 0]。x1 es la que se genera automáticamente en el guión 2to3 basado en los parámetros de denominación del subgrupo original。
2 La función lambda que utiliza un grupo de dos elementos (x, y) como parámetros se convierte en x_y, que tiene dos parámetros de posición, es decir, x_y[0] y x_y[1]。
Los scripts de 3 y 2 a 3 pueden incluso manejar una función lambda con el parámetro de nombre de la matriz como parámetro. El código resultante es un poco difícil de leer, pero funciona de la misma manera en Python 3 que el código original en Python 2.
4. Puedes definir una función lambda que use varios parámetros. Si no hay paréntesis alrededor de los parámetros, Python 2 lo tomará como una función lambda que contenga varios parámetros; en este cuerpo de funciones lambda, se refieren a estos parámetros por su nombre, como se hace en otros tipos de funciones. Esta sintaxis sigue siendo válida en Python 3.
En Python 2, los métodos de clase pueden acceder a los objetos de clase que definen su clase, y también pueden acceder a los objetos de método mismos. Im_self es el objeto de instancia de la clase; im_func es el objeto de la función y im_class es la clase misma. En Python 3, estas propiedades son renombradas para seguir las convenciones de denominación de otras propiedades.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | aClassInstance.aClassMethod.im_func | aClassInstance.aClassMethod._func_ |
| ② | aClassInstance.aClassMethod.im_self | aClassInstance.aClassMethod._self_ |
| ③ | aClassInstance.aClassMethod.im_class | aClassInstance.aClassMethod._self_._class_ |
En Python 2, puedes crear tus propias clases y hacerlas usadas en un contexto booleano. Por ejemplo, puedes instanciar la clase y usar el objeto de la instancia en una sentencia if. Para ello, defines un__nonzero__() método, que devuelve un valor de True o False, cuando el objeto de la instancia está en el contexto de Boolean. En Python 3, todavía se puede hacer lo mismo, pero el nombre de este método especial se convierte__bool__()。
| Notes | Python 2 | Python 3 |
|---|
|①|class A:<br> def nonzero(self):<br> pass|class A:<br> def bool(self):<br> pass
|②|class A:<br> def nonzero(self, x, y):<br> pass|no change|
- Python 3 llama cuando se usa un objeto de clase en un contexto en BULL__bool_En lugar de eso.nonzero()。
2 sin embargo, si usted tiene una definición que utiliza dos parámetros__nonzero__() Método: El script 2 a 3 asume que el método que usted define tiene otros usos, por lo que no modifica el código.
Entre Python 2 y Python 3 hay un ligero cambio en la sintaxis para definir números octal.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | x = 0755 | x = 0o755 |
Debido a la integración de los integrados largos y los integrados, la constante de sys.maxint ya no es precisa. Pero debido a que este valor es útil para detectar la capacidad de una plataforma específica, se conservó en Python 3 y se renombró sys.maxsize.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | from sys importmaxint | from sys importmaxsize |
| ② | a_function(sys.maxint) | a_function(sys.maxsize) |
1, maxint se ha convertido en maxsize.
2. Todos los sys.maxint se han convertido en sys.maxsize.
En Python 2 se puede usar la función global callable ((() para comprobar si un objeto es callable (((callable, por ejemplo función) }}. En Python 3, esta función global se ha eliminado }}. Para comprobar si un objeto es callable, se puede comprobar un método especial__call_La existencia de ______
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | callable(anything) | hasattr(anything,'_call_') |
En Python 2, la función global zip() puede usar una serie arbitraria como parámetros, y devuelve una lista compuesta por subgrupos. El primer subgrupo contiene el primer elemento de cada serie; el segundo subgrupo contiene el segundo elemento de cada serie; y se desprende sucesivamente. En Python 3, zip() devuelve un iterador, no una lista.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | zip(a, b, c) | list(zip(a, b, c)) |
| ② | d.join(zip(a, b, c)) | no change |
En su forma más sencilla, puedes restablecer la función anterior de la función de envasado de list (zip) llamando a la función de envasado de list (zip) y recorriendo el iterador de la función de envasado de list (zip) y devolviendo la lista de resultados.
En un contexto en el que ya se han recorrido todos los elementos de la secuencia (por ejemplo, aquí se llama a la metodología join), el iterador que devuelve zip () puede funcionar correctamente. El script 2to3 detecta estas situaciones y no cambia su código.
En Python 2, StandardError es la clase base de todas las excepciones incorporadas, excepto StopIteration, GeneratorExit, KeyboardInterrupt y SystemExit. En Python 3, StandardError ha sido eliminado y sustituido por Exception.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | x =StandardError() | x =Exception() |
| ② | x =StandardError(a, b, c) | x =Exception(a, b, c) |
En el módulo types hay una variedad de constantes que te ayudan a decidir el tipo de un objeto. En Python 2, contiene constantes que representan todos los tipos de datos básicos, como dict e int. En Python 3, estas constantes han sido eliminadas. Sólo se necesita usar el nombre del tipo básico para reemplazarlas.
| Notes | Python 2 | Python 3 |
|---|---|---|
| types.UnicodeType | str | |
| types.StringType | bytes | |
| types.DictType | dict | |
| types.IntType | int | |
| types.LongType | int | |
| types.ListType | list | |
| types.NoneType | type(None) | |
| types.BooleanType | bool | |
| types.BufferType | memoryview | |
| types.ClassType | type | |
| types.ComplexType | complex | |
| types.EllipsisType | type(Ellipsis) | |
| types.FloatType | float | |
| types.ObjectType | object | |
| types.NotImplementedType | type(NotImplemented) | |
| types.SliceType | slice | |
| types.TupleType | tuple | |
| types.TypeType | type | |
| types.XRangeType | range |
types.StringType se mapea en bytes, no en str, ya que en Python 2 <unk>string<unk> es en realidad una secuencia de bytes codificados con algún tipo de caracteres.
isinstance() es una función que comprueba si un objeto es una instancia de una clase o un tipo específicos. En Python 2 se puede pasar una instancia de un subgrupo de tipos a isinstance(), y si el objeto es de cualquier tipo del subgrupo, la función devuelve True. En Python 3 se puede hacer esto, pero no se recomienda usar un tipo como parámetro para pasarlo dos veces.
| Notes | Python 2 | Python 3 |
|---|---|---|
| isinstance(x,(int,float,int)) | isinstance(x,(int,float)) |
Python 2 tiene dos tipos de cadenas: cadenas codificadas en Unicode y cadenas no codificadas en Unicode. Pero en realidad hay otro tipo, el basestring. Es un tipo de datos abstracto, una superclase de str y unicode. No puede ser invocado o instanciado directamente, pero puede usarse como un parámetro de instancia para detectar si un objeto es una cadena Unicode o una cadena no Unicode.
| Notes | Python 2 | Python 3 |
|---|---|---|
| isinstance(x, basestring) | isinstance(x, str) |
Python 2.3 introdujo el módulo itertools, que define las variantes de las funciones globales zip (), map (), filter (), cuyo tipo de retorno es el iterador, no la lista. En Python 3, estas funciones de variación en estas itertools se eliminaron debido a que el tipo de retorno de estas funciones globales es el iterador.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | itertools.izip(a, b) | zip(a, b) |
| ② | itertools.imap(a, b) | map(a, b) |
| ③ | itertools.ifilter(a, b) | filter(a, b) |
| ④ | from itertools import imap, izip, foo | from itertools import foo |
- Utiliza la función global zip (), en lugar de itertools.izip ().
2o, el uso de map () en lugar de itertools.imap ()
3 ,itertools.ifilter() se ha convertido en filter() 。 - El módulo itertools permanece en Python 3, sólo que ya no contiene funciones que se han trasladado al espacio de nombres global. Los scripts 2to3 son lo suficientemente inteligentes como para eliminar las instrucciones de importación que ya no son útiles, mientras que mantienen la integridad de otras instrucciones de importación.
En el módulo sys, hay tres variables a las que puedes acceder cuando se trata de excepciones: sys.exc_type, sys.exc_value, sys.exc_traceback. En realidad, estas ya existían en la era de Python 1. Desde Python 1.5, ya no se recomienda usar estas tres variables debido a la nueva versión de sys.exc_info, que es un subconjunto que contiene todos los tres elementos anteriores. En Python 3, estas tres variables finalmente ya no existen; esto significa que debes usar sys.exc_info.
| Notes | Python 2 | Python 3 |
|---|---|---|
| sys.exc_type | sys.exc_info()[0] | |
| sys.exc_value | sys.exc_info()[1] | |
| sys.exc_traceback | sys.exc_info()[2] |
En Python 2, si necesitas escribir una lista de parámetros que recorre un grupo, no necesitas poner paréntesis alrededor de los valores del grupo. En Python 3, estos paréntesis son necesarios.
| Notes | Python 2 | Python 3 |
|---|---|---|
| [i for iin 1,2] | [i for iin(1,2)] |
Python 2 tiene una función llamada os.getcwd() que devuelve el directorio de trabajo actual como una cadena de caracteres (que no está codificada en Unicode). Debido a que los sistemas de archivos modernos pueden procesar nombres de directorio que pueden codificarse en hexadecimal, Python 2.3 introdujo la función os.getcwdu ((() que devuelve las cadenas codificadas en Unicode del directorio de trabajo actual. En Python 3, ya que solo hay un tipo de cadena de caracteres (tipo Unicode), solo necesitas os.getcwd (().
| Notes | Python 2 | Python 3 |
|---|---|---|
| os.getcwdu() | os.getcwd() |
En Python 2, puedes definir los parámetros de metaclass en la declaración de clase, o definir un nivel de clase especial (class-level)__metaclass_En Python 3, el atributo _ se usa para crear subcategorías.__metaclass_El atributo _ ha sido eliminado.
| Notes | Python 2 | Python 3 |
|---|---|---|
| ① | class C(metaclass=PapayaMeta):<br> pass | unchanged |
| ② | class Whip:<br> _metaclass_ = PapayaMeta | class Whip(metaclass=PapayaMeta):<br> pass |
| ③ | class C(Whipper, Beater):<br> _metaclass_ = PapayaMeta | class C(Whipper,Beater,metaclass=PapayaMeta):<br> pass |
- Declarar los parámetros de metaclass al declarar una clase, esto es válido en Python 2 y Python 3, son los mismos.
- Declarar en la definición de la clase que el atributo metaclass es válido en Python 2, pero ya no lo es en Python 3.
3, 2to3 es capaz de construir una declaración de clase válida, incluso si la clase hereda de varias clases paternas.
Los siguientes parches de corrección no son verdaderos parches. Es decir, son solo aspectos del estilo del código, no tienen nada que ver con la esencia del mismo. Pero los desarrolladores de Python tienen un gran interés en hacer que el estilo del código sea lo más consistente posible. Para ello, hay un manual oficial que describe el estilo del código de Python.
-
set (valor literal) y set (valor literal) y set (valor literal) y set (valor literal)
En Python 2, la única manera de definir un conjunto de valores literales es llamando set{a_sequence}. En Python 3 esto sigue siendo válido, pero el uso de la nueva notación literal: paréntesis grandes {}) es una forma más clara. Esta forma de definir un conjunto de valores literales es válida además de los conjuntos en blanco, ya que los diccionarios también lo marcan con paréntesis grandes, por lo que {} representa un diccionario en blanco, no un conjunto en blanco.
Los scripts 2to3 no corregirán de forma predeterminada los valores literales de set[...]. Para activar esta función, especifique el parámetro -f set_literal cuando se llame 2to3 en la línea de comandos.
| Notes | Before | After |
|---|---|---|
| set([1,2,3]) | {1,2,3} | |
| set((1,2,3)) | {1,2,3} | |
| set([i for iin a_sequence]) | {i for iin a_sequence} |
-
Buffer de funciones globales (expreso)
Los objetos de Python implementados en C pueden exportar una barra de interfaz de buffer que permite que el resto del código de Python lea y escriba directamente en un trozo de memoria. Esto suena muy poderoso, pero también es aterrador. En Python 3, el buffer fue renombrado como memoryview.
Los scripts 2to3 de forma predeterminada no corrigen la función buffer (). Para activar esta función, especifique el parámetro -f buffer cuando se llame 2to3 en la línea de comandos.
| Notes | Before | After |
|---|---|---|
| x =buffer(y) | x =memoryview(y) |
-
Espacio alrededor de la coma (explicado)
A pesar de los estrictos requisitos de Python para espacios para indenting y outdenting, Python es muy libre para el uso de espacios en otros aspectos. En listas, subgrupos, conjuntos y diccionarios, los espacios pueden aparecer delante o detrás de las comillas, lo que no tiene ningún efecto negativo. Sin embargo, el manual de estilo de código de Python indica que no se puede tener un espacio antes de las comillas y debe incluir un espacio después de las comillas.
Los scripts 2to3 no corregirán los espacios alrededor de las commas por defecto. Para activar esta función, especifique el parámetro -f wscomma cuando se llame 2to3 en la línea de comandos.
| Notes | Before | After |
|---|---|---|
| a ,b | a, b | |
| {a :b} | {a: b} |
-
Idiomas comunes (expresivos)
Hay muchas prácticas que se han establecido en la comunidad de Python. Algunas son como el while 1: loop, que se remonta a Python 1. Python no tenía un tipo de boolea en el sentido real hasta Python 2.3, por lo que los desarrolladores usaban antes el 1 y el 0 como sustitutos.
Los scripts 2to3 no hacen correcciones por defecto para estas prácticas. Para activar esta función, especifique el parámetro -f idioms cuando se llame 2to3 en la línea de comandos.
| Notes | Before | After |
|---|---|---|
| while 1:<br> do_stuff() | while True:<br> do_stuff() | |
| type(x) == T | isinstance(x, T) | |
| type(x) is T | isinstance(x, T) | |
| a_list = list(a_sequence) | a_list = sorted(a_sequence) | |
| a_list.sort() | do_stuff(a_list) | |
| do_stuff(a_list) |
Traducido de:El blog de CSDN
Cómo convertir el código de Python 2 en el código de Python 3
En cuanto a cómo convertir el código de Python 2.x en el código de Python 3.x.
Cómo convertir código de Python 2.x en código de Python 3.x
No hace falta decir mucho si se trata solo de unas pocas funciones, como print, etc.
Entonces, si quieres cambiar el código, puedes hacerlo.
Las versiones de Python 2.x, como la que instale yo, Python 2.7.2, llevan consigo algunas herramientas útiles cuando se descargan y se instalan en Windows.
Uno de ellos, llamado 2to3.py, es una aplicación que te ayuda a convertir el código de Python 2.x al código de Python 3.x.
Se encuentra en el directorio raíz de las instalaciones de Python\Python27\Tools\Scripts\2to3.py
Cómo utilizar 2to3.py para convertir el código de Python 2.x en Python 3.x
Por ejemplo, tengo un script de Python 2.x:
D:\tmp\tmp_dev_root\python\python2_to_python3\34563264_data_from_site.py
Ahora, el código para convertirlo a Python 3.x.
Se puede abrir el cmd de windows, ubicarlo debajo del script a convertir y ejecutarlo
D:\tmp\WordPress\DevRoot\Python27\Tools\Scripts\2to3.py -w 34563264_data_from_site.py
La conversión es exitosa, y el resultado de la ejecución es:
D:\tmp\tmp_dev_root\python\python2_to_python3>D:\tmp\WordPress\DevRoot\Python27\Tools\Scripts\2to3.py -w 34563264_data_from_site.py
RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: set_literal
RefactoringTool: Skipping implicit fixer: ws_comma
RefactoringTool: Refactored 34563264_data_from_site.py
--- 34563264_data_from_site.py (original)
+++ 34563264_data_from_site.py (refactored)
@@ -18,7 +18,7 @@
import time;
import codecs;
import logging;
-import urllib;
+import urllib.request, urllib.parse, urllib.error;
from datetime import datetime,timedelta;
from optparse import OptionParser;
from string import Template,replace;
@@ -90,7 +90,7 @@
foundPhone = eachItemSoup.find(attrs={"class":"phone"});
logging.debug("foundPhone=%s", foundPhone);
if(foundPhone):
- foundPhoneUni = unicode(foundPhone);
+ foundPhoneUni = str(foundPhone);
logging.debug("foundPhoneUni=%s", foundPhoneUni);
# case 1:
#<p class="phone"><strong>phone:</strong> 800.206.7886<br />
@@ -122,7 +122,7 @@
foundWeb = eachItemSoup.find(attrs={"class":"web"});
logging.debug("foundWeb=%s", foundWeb);
if(foundWeb):
- foundWebUni = unicode(foundWeb);
+ foundWebUni = str(foundWeb);
logging.debug("foundWebUni=%s", foundWebUni);
# <p class="web"><strong>e-mail:</strong> <a href="#">[email protected]</a><br />
@@ -151,7 +151,7 @@
foundAddr = eachItemSoup.find(attrs={"class":"addr"});
logging.debug("foundAddr=%s", foundAddr);
if(foundAddr):
- foundAddrUni = unicode(foundAddr);
+ foundAddrUni = str(foundAddr);
# <p class="addr">
# <strong>address:</strong> 740 SW 21st Ave, Suite #310<br />
RefactoringTool: Files that were modified:
RefactoringTool: 34563264_data_from_site.py
En este momento, se puede ver que el código original 34563264_data_from_site.py se ha convertido en el código de Python 3.x.
Para ello, también hay un archivo bak::34563264_data_from_site.py.bak, comparando los dos se puede ver la diferencia:
En la actualidad, para 2to3.py en sí, también se pueden ver más usos en la consulta de ayuda:
D:\tmp\tmp_dev_root\python\python2_to_python3>D:\tmp\WordPress\DevRoot\Python27\Tools\Scripts\2to3.py -h
Usage: 2to3 [options] file|dir ...
Options:
-h, --help show this help message and exit
-d, --doctests_only Fix up doctests only
-f FIX, --fix=FIX Each FIX specifies a transformation; default: all
-j PROCESSES, --processes=PROCESSES
Run 2to3 concurrently
-x NOFIX, --nofix=NOFIX
Prevent a transformation from being run
-l, --list-fixes List available transformations
-p, --print-function Modify the grammar so that print() is a function
-v, --verbose More verbose logging
--no-diffs Don't show diffs of the refactoring
-w, --write Write back modified files
-n, --nobackups Don't write backups for modified files
Aquí hay algunas explicaciones:
(1) Si no se añade el parámetro -w, por defecto sólo se imprime el contenido de la diferencia correspondiente al proceso de conversión en la ventana actual.
(2) Agrega -w, es decir, cambia el contenido y vuelve a escribirlo en el documento original.
(3) Si no quieres generar un archivo bak, añade -n.
(4) Si no quieres ver ese montón de resultados, añade los no-diffs.
El resto, no mucho más. Los interesados pueden ir y seguir con el despliegue.
El uso de 2 a 3 arriba es copiado deEn el camino
¡Si hay errores, por favor, apúntanos! ^_^

