Hay una tendencia de desalentar a la configuración de sys.setdefaultencoding('utf-8') en Python 2. ¿Puede alguien de la lista de ejemplos reales de problemas con eso? Argumentos como it is harmful o it hides bugs no suena muy convincente.

ACTUALIZACIÓN: por Favor, tenga en cuenta que esta pregunta es sólo acerca de utf-8, no es sobre el cambio de codificación predeterminada «en el caso general».

Por favor dar algunos ejemplos con código si se puede.

  • ¿cómo se usa? Si usted está hablando acerca de la modificación de sitecustomize.py luego, cuando el código se ejecuta en otros equipos puede tener fallos
  • Si usted tiene una decodificar o codificar error es probablemente por una razón obvia que yo.e s = u'é' str(s) . Usted debe trabajar con un tipo string o unicode y manejar la codificación de forma explícita.
  • stackoverflow.com/questions/28642781/…, no de configuración global – la aplicación sólo.
  • pudiera ser relevante, mail.python.org/pipermail/python-dev/2009-August/091406.html Usted puede obtener un extraño efecto causado por el hecho de que algunos de los objetos string se compare ahora igual mientras que no necesariamente tenían el mismo valor de hash. Unicode objetos y las cadenas tienen el mismo valor de hash, siempre que sean ASCII. Con el ASCII de codificación predeterminada, un no-ASCII cadena no puede ser comparado con un objeto Unicode, por lo que el problema no se produce.
  • UTF-8 cadena no es un objeto Unicode sin embargo, y a pesar de la codificación de los objetos string no compara iguales si tienen diferentes contenidos. A menos que haya un error en Python, la función de hash,
  • Porque usted es un malentendido de cómo funciona Python con codificaciones si usted piensa que usted necesita. Aquí una presentación de cómo utilizar correctamente: farmdev.com/talks/unicode – Como un aparte, si el argumento de «se esconde errores» no suena convincente para usted, que puede ser el problema real. (Y sí, Unicode en Python 2 succiones. Pero sys.setdefaultencoding no es la solución.) Y por último, si quieres ver un error que causa, no busque más: stackoverflow.com/a/28627705/1968
  • es por eso que estoy pidiendo un ejemplo real de que se me pueda entender.
  • aquí la un ejemplo de una pregunta cuando un usuario tiene jodido porque el Autor de PyDev piensa que es una buena idea establecer sys.setdefaultencoding('utf-8'). He aquí un blog de alguien que consiguió follar por el este, con algunos detalles más y más enlaces.
  • Un buen anuncio el día de hoy sobre el tema: anonbadger.wordpress.com/2015/06/16/…

5 Comentarios

  1. 22

    El cartel original pidió el código que demuestra que el cambio es perjudicial—excepto que «esconde» errores no relacionados con el interruptor.

    Resumen de las conclusiones

    Tanto basados en la experiencia y la evidencia que he recogido, aquí son las conclusiones a las que hemos llegado.

    1. Configuración de la defaultencoding a UTF-8 en la actualidad es seguro, excepto para aplicaciones especializadas, manejo de archivos de los que no son unicode sistemas listos.

    2. La «oficial» rechazo del interruptor está basada en razones ya no son relevantes para una gran mayoría de los usuarios finales (no de la biblioteca de proveedores), por lo que debemos dejar de desalentar a los usuarios a establecer.

    3. Trabajando en un modelo que se encarga de Unicode correctamente, por defecto, es mucho más adecuadas para las aplicaciones de inter-sistemas de comunicaciones que manualmente trabajando con la Api de unicode.

    Efectivamente, la modificación de la codificación predeterminada muy frecuentemente evita un número de usuario dolores de cabeza en la gran mayoría de los casos de uso. Sí, hay situaciones en las que los programas relacionados con múltiples codificaciones silenciosamente se portan mal, pero a partir de este interruptor puede ser activado por etapas, esto es no es un problema en el usuario final código.

    Lo que es más importante, la habilitación de esta bandera es un ventaja real de los usuarios de código, tanto por la reducción de la sobrecarga de tener que manejar manualmente conversiones de Unicode, que estorban el código y lo que es menos legible, sino también por evitar posibles errores cuando el programador no lo hace correctamente en todos los casos.


    Ya que estos reclamos son casi el opuesto exacto de la oficial de Python línea de comunicación, creo que la explicación de que estas conclusiones se justifica.

    Ejemplos de éxito en el uso de una versión modificada defaultencoding en la naturaleza

    1. Dave Malcom de Fedora creído que es siempre a la derecha. propuso, después de investigar los riesgos, a cambio de distribución amplia def.enc.=UTF-8 para todos usuarios de Fedora.

      Duro hecho de presentarse a pesar de que por qué Python rompería es sólo el hash comportamiento que listado, que nunca es recogido por cualquier otro oponente dentro del núcleo de la comunidad como una razón para preocuparse o incluso por la misma persona, cuando se trabaja en entradas de usuario.

      Curriculum vitae de Fedora: Es cierto que el cambio en sí mismo que se describió como «tremendamente impopular» con los desarrolladores principales, y fue acusado de ser incompatible con las versiones anteriores.

    2. Hay 3000 proyectos solo en openhub hacerlo. Tienen una búsqueda lenta frontend, pero el escaneo de más de ello, estimo que el 98% son de usar UTF-8. No he encontrado nada acerca de sorpresas desagradables.

    3. Hay 18000(!) github maestro ramas con lo cambió.

      Mientras que el cambio es «impopular» en el núcleo de la comunidad de su bastante popular en la base de usuarios. Aunque esto podría ser tenido en cuenta, ya que los usuarios suelen utilizar hacky soluciones, no creo que este es un argumento que debido a mi siguiente punto.

    4. Sólo hay 150 bugreports total en GitHub debido a esto. A una tasa de eficacia del 100%, el cambio parece ser positiva, no negativa.

      Para resumir los problemas de la gente han chocar, he escaneado a través de todos los antes mencionados entradas.

      • Cambiando def.enc. a UTF-8 es típicamente introducido pero no se quitó en el tema de proceso de cierre, más a menudo como una solución. Algunos de los más grandes de la excusa de que como solución temporal, teniendo en cuenta la «mala prensa» que tiene, pero mucho más error reporteros son sólome alegro sobre la revisión.

      • Un par de (1-5?) proyectos de modificación de su código haciendo las conversiones de tipo manualmente para que no necesitan cambiar el valor predeterminado más.

      • En dos casos veo a alguien que dice que con def.enc. establece UTF-8 conduce a una falta completa de salida totalmente, sin explicar la configuración de prueba. Yo no podía verificar la reclamación, y he probado uno y encontramos que lo contrario es cierto.

      • Uno reclamaciones su «sistema» puede depender de no cambiarla, pero no sabemos por qué.

      • Uno (y sólo uno) había una verdadera razón para evitarlo: ipython usa una 3ra parte del módulo o el test runner modificado su proceso de forma incontrolada (nunca es indiscutible que una de def.enc. el cambio es defendido por su los defensores sólo al intérprete momento de la instalación, es decir, cuando el «propietario» del proceso).

    5. He encontrado cero indicación de que los diferentes hashes de ‘é’ y u é las causas de los problemas en el mundo real código.

    6. Python hace no «break»

      Después de cambiar la configuración a UTF-8, sin función de Python cubiertos por unidad de pruebas es el trabajo de forma diferente que sin el modificador. El interruptor de , sin embargo, no está probado en todo.

    7. Es asesorado en bugs.python.org para usuarios frustrados

      Ejemplos aquí, aquí o aquí
      (a menudo conectado con la línea oficial de advertencia)

      La primera de ellas se muestra cómo se estableció el interruptor está en Asia (comparar también con el github argumento).

    8. Ian Bicicleta publicado su apoyo para siempre la habilitación de este comportamiento.

      Puedo hacer que mis sistemas y comunicaciones constantemente UTF-8, las cosas se vayan a mejor. No veo realmente una desventaja. Pero, ¿por qué Python lo hacen TAN CONDENADAMENTE DIFÍCIL […] me siento como alguien decidió que eran más inteligentes que yo, pero no estoy seguro de creer en ellos.

    9. Martijn Fassen, mientras que la refutación de Ian, admitió que el ASCII podría haber sido mal en el primer lugar.

      Yo creo que si, por ejemplo, Python 2.5, se entregan con un defecto de la codificación de UTF-8, no romper nada. Pero si la hice para mi Python, me gustaría tener problemas pronto como me dieron mi código para alguien más.

    10. En Python3, no «practican lo que predican»

      A la vez oponerse a cualquier def.enc. cambio tan duramente porque de medio ambiente dependiente de código o de implicitación, una discusión aquí gira en torno a Python3‘s problemas con su ‘unicode sandwich’ y el paradigma de la correspondiente requiere de supuestos implícitos.

      También han creado posibilidades para escribir válido Python3 código como:

      >>> from 褐褑褒褓褔褕褖褗褘 import *        
      >>> def 空手(合氣道): あいき(ど(合氣道))
      >>> 空手(う힑힜('👏 ') + 흾)
      💔
    11. DiveIntoPython lo recomienda.

    12. En este hilo, Guido mismo asesora un profesional de usuario final el uso de un proceso específico de environt con el interruptor de «crear un custom ambiente Python para cada proyecto.»

      La razón fundamental de los diseñadores de Python 2.x de la biblioteca estándar, no quiere que usted sea capaz de establecer la codificación predeterminada en tu aplicación, es que la biblioteca estándar está escrito con la suposición de que la codificación predeterminada es fijo, y no garantiza el correcto funcionamiento de la biblioteca estándar puede ser hecho cuando la cambia. No hay pruebas para esta situación. Nadie sabe qué va a fallar cuando. Y usted (o peor aún, los usuarios) va a venir de nuevo a nosotros con quejas si la biblioteca estándar de repente empieza a hacer cosas que no esperaba.

    13. Jython ofrece para cambiar sobre la marcha, incluso en los módulos.

    14. PyPy hizo no soporte de recarga(sys) – pero trajo de vuelta en a petición del usuario dentro de un solo día sin hacer preguntas. Comparar con el «lo estás haciendo mal» actitud de CPython, reclamando sin la prueba es la «raíz del mal».


    Final de esta lista me confirman que uno podría la construcción de un módulo que se bloquea porque de una modificación de la intérprete de configuración, hacer algo como esto:

    def is_clean_ascii(s):
        """ [Stupid] type agnostic checker if only ASCII chars are contained in s"""
        try:
            unicode(str(s))
            # we end here also for NON ascii if the def.enc. was changed
            return True
        except Exception, ex:
            return False    
    
    if is_clean_ascii(mystr):
        <code relying on mystr to be ASCII>

    Creo que eso no es un argumento válido porque la persona que escribió este doble tipo de aceptar módulo obviamente era consciente acerca de ASCII vs no cadenas de caracteres ASCII y sería consciente de codificación y decodificación.

    Creo que esta evidencia es más que suficiente indicación de que la modificación de este ajuste no conduce a ningún tipo de problemas en el mundo real códigos base de la gran mayoría del tiempo.

    • No debería ser esto una entrada de blog que enlace en un comentario en Martijn la respuesta?
    • gracias por los comentarios, me ofrecen ahora un resumen de mis investigaciones en la parte superior.
    • Esta respuesta es demasiado larga, y tan innecesariamente. La mayoría de sus argumentos, los que ocupan la mayor parte de tu post, parecen ser nada más que un argumentum ad populum, y prueba por verbosidad, en el peor. Además, la totalidad de la sección acerca de la normalización y codificación es irrelevante y pertenece en un post en el blog, no en una respuesta en el Desbordamiento de Pila. Su respuesta sería mucho mejor si simplemente destilada de la razones técnicas para que de su opinión, nada más.
    • Gracias, Alexis, para que la gran edición de ejecución.
    • Algunos comentarios específicos: Configuración por defecto es como el uso de goto. Claro, usted puede hacer el trabajo, pero usted tendrá un tiempo más difícil para ella ya que el desarrollo de la aplicación. Llegar a ser incoherente en su manejo de Unicode y que va a morder. La mayoría de las personas que la utilizan do no entender Unicode y creo que este es el camino más fácil.
    • Los argumentos de que una gran cantidad de GitHub el código utiliza no es la prueba de que está bien usar, también puede ser tomada como prueba de la mayoría de los desarrolladores no entienden cómo usar Unicode correctamente. Ve los mismos problemas con cómo los desarrolladores novatos uso super(). Hablando en general, es un de la Carga de Culto, aplicada y mal aplicadas sin la comprensión de ¿cómo funciona o si es necesario en absoluto.
    • Tienes razón, un valor por defecto debe, muy general, nunca se cambió, sólo debido a que los problemas desaparecen por arte de magia y no sabes por qué. Que debe saber lo que u r haciendo. Pero SI usted sabe lo que hace, a continuación, Python2 es mejor trabajar con el. Mejor que Py3 para mí – pero eso es una historia diferente 😉
    • Yo también comienzan a comprender que su problema principal con el que parece ser el (de acuerdo) hecho de que el código podría conseguir inconsistente con respecto a los tipos de cadena que viajan a través de, algunos unicode algunos bytes, mientras que sin el modificador de que se estrellara. También aquí yo estoy con vosotros: Uno debe decidir antes de escribir la primera Py2 l.o.c., si su lib o proceso debe ser trabajar con unicode O con bytes consistentemente. Preferimos bytes – con buenas razones.
    • llegar a ser incoherente en su manejo de Unicode y que va a morder. «Podría elaborar en lo exactamente va a ser el problemas de morder nosotros? Así setdefaultencoding parece ser más bien una manera segura de salir. Si algo se rompería gran momento, no hemos oído hablar de él por ahora, y no se que significa cosa, que se rompe en el uso de otra codificación predeterminada debe ser corregido? Gracias por su comprensión. IMO la forma en Python 2.x sigue a rechazar ASCII > 127 por defecto es bastante arcano (aunque yo estoy totalmente en favor de Python lo contrario)…
    • Python 2.0 fue la primera versión de Python para introducir el soporte Unicode, en octubre de 2000. Se incluyó la decisión y, a continuación, deshabilitar la configuración de la codificación predeterminada. Eso significa que hay ahora 15 años de código heredado por ahí que se basa en ser capaz de atrapar una excepción al intentar concatenar no-ASCII en bytes de los bytes que no son descifrables como ASCII, etc. Usted no puede posiblemente solucionar todo ese código.
    • y lo que ustedes llaman ‘arcanos’ se llama hacia atrás y hacia delante de compatibilidad, un requisito cuando el lenguaje es usado por miles de millones de computadoras en el mundo. Python 3 podría hacer el cambio, porque no hacer promesas acerca de la compatibilidad.
    • > eso significa Que hay ahora es de 15 años de legado código de allí que se basa en ser capaz de atrapar una excepción (…). En realidad, el 15-años de legado de código se basa en el estándar de la lib para trabajar con unicode (es decir,sometext'.decode('whatever'), y no apoyar el cambio de la defaultenconding en mi humilde opinión es similar a decir que no estamos seguros de si el soporte unicode realmente funciona [en el stdlib]. De todos modos tengo tu punto. Esencialmente, esto significa que la conmutación de defaultencoding no está soportado oficialmente, sin embargo, ya que las respuestas se señala que en algunas circunstancias no son las ventajas de hacerlo. Gracias por tu punto de VISTA.
    • Tener este conocimiento anterior tendríamos que nunca se necesita de Python 3, harto de perder una década de Python de la comunidad a la vez que provoca la falta de innovación
    • Que resume bastante bien mi post original en una sola línea.

  2. 16

    Porque no siempre se quiere tener sus cuerdas automáticamente decodificada a Unicode, o para el caso de su Unicode automáticamente objetos codificados con el fin de bytes. Puesto que usted está solicitando para un ejemplo concreto, aquí hay uno:

    Tomar un WSGI de la aplicación web; usted está construyendo una respuesta por parte de agregar el producto de un proceso externo a una lista, en un bucle, y que el proceso externo le da codificado en UTF-8 bytes:

    results = []
    content_length = 0
    
    for somevar in some_iterable:
        output = some_process_that_produces_utf8(somevar)
        content_length += len(output)
        results.append(output)
    
    headers = {
        'Content-Length': str(content_length),
        'Content-Type': 'text/html; charset=utf8',
    }
    start_response(200, headers)
    return results

    Que grandes y muy bien y funciona. Pero, a continuación, su compañero de trabajo viene y se agrega una nueva característica; ahora proporcionar etiquetas demasiado, y estos están localizados:

    results = []
    content_length = 0
    
    for somevar in some_iterable:
        label = translations.get_label(somevar)
        output = some_process_that_produces_utf8(somevar)
    
        content_length += len(label) + len(output) + 1
        results.append(label + '\n')
        results.append(output)
    
    headers = {
        'Content-Length': str(content_length),
        'Content-Type': 'text/html; charset=utf8',
    }
    start_response(200, headers)
    return results

    Usted prueba esta en inglés y todo lo que todavía funciona, genial!

    Sin embargo, la translations.get_label() biblioteca devuelve realmente valores Unicode y cuando cambie la configuración regional, las etiquetas contienen caracteres no-ASCII.

    La WSGI biblioteca escribe los resultados a la toma de corriente, y todos los valores Unicode se auto-codificado para usted, ya que se establece setdefaultencoding() a UTF-8, pero la longitud calculada es del todo errónea. Va a ser muy corta como UTF-8 codifica todo lo que esté fuera del rango ASCII con más de un byte.

    Todo esto es ignorar la posibilidad de que en realidad estás trabajando con datos en un codec diferente; puede ser la escritura de Latin-1 + Unicode, y ahora usted tiene una longitud incorrecta encabezado y una mezcla de datos de codificaciones.

    Usted no había utilizado sys.setdefaultencoding() una excepción se han planteado y que usted sabía que había un error, pero ahora sus clientes se quejan de las respuestas incompletas; hay bytes que faltan al final de la página y que no sé muy bien cómo sucedió.

    Tenga en cuenta que este escenario no implican la 3ª parte de las bibliotecas que puede o no puede depender el valor predeterminado sigue siendo ASCII. El sys.setdefaultencoding() configuración es global, aplicando a todos código que se ejecuta en el intérprete. ¿Qué tan seguro está usted de que no hay problemas en aquellas bibliotecas que implican implícito de codificación o descodificación?

    Que Python 2 codifica y decodifica entre str y unicode tipos implícitamente puede ser útil y seguro cuando se trata de datos ASCII sólo. Pero realmente necesita saber cuando se mezcla con Unicode y cadena de bytes de datos accidentalmente, en lugar de yeso sobre él con un global de pincel y esperar lo mejor.

    • Hay un error en el you don't always want to have your strings automatically decoded to Unicode – las cadenas son decodificados a UTF-8, no Unicode objetos.
    • UTF-8 es un codificación, por lo que tendrías que estar codificado en UTF-8. Ese es el problema te Unicode objetos cuando se mezclan los dos tipos; str + unicode le da unicode, siempre que el str podría ser decodificado.
    • en mi ejemplo de la translations.get_label() devuelve unicode objetos. El WSGI aplicación también podría optar a sólo concatenar todos los resultados, momento en el que te gustaría conseguir uno unicode objeto como de salida, pasa a la toma de corriente, o quizás a otro WSGI envoltura de la etiqueta. No sabemos, porque hemos silenciado todos Python excepciones que normalmente habrían sido arrojados.
    • No lo entiendo. Para mí es como usted está diciendo que con sys.setdefaultencoding("utf-8") Python comenzará a producir unicode objetos en lugares donde se str anteriormente. Es ese derecho? (Todavía estoy leyendo a través del ejemplo)
    • Una tabla de conversión de tipo y contenido de la variable sin duda ayudará a obtener ese derecho.
    • Python se trate y decodificar str objetos cuando se concatenan con unicode objetos, sí, y que normalmente se producirá un error si los bytes no son descifrables como ASCII. Pero tan pronto como cambiar el códec predeterminado, entonces bytes que son decodificables como UTF-8 también será convertido y usted termina con Unicode objetos en los que creía que eran la producción de valores de byte en lugar.
    • Así, el Python no choque con los no-ASCII cadenas más con sys.setdefaultencoding("utf-8"). No puedo ver la forma en que este comportamiento es malo para el ejemplo. En el caso de mi aplicación (Roundup) esto está cerca el choque estoy tratando de arreglar – stackoverflow.com/questions/28642781/…
    • estamos dando vueltas en círculos. Usted no ve esto como algo malo, porque no veo cómo implícitamente la conversión de tipos puede ser malo. En un lenguaje donde las conversiones implícitas son la excepción en lugar de la predeterminada, esto es un gran el tema, y que están cambiando las reglas de la conversión a nivel mundial. Si esto fue configurado por módulo en su lugar, estaría libre para disparar en el pie, sin forzar el problema de la 3ª parte de la biblioteca puede que esté utilizando. Pero ese no es el caso aquí, y si usted no está viendo un problema con este tipo de comportamiento no sé qué decirte.
    • Veo que las cosas puede ser malo, pero no veo que hay un ejemplo del mundo real de la que ha cambiado el comportamiento fue deseado comportamiento. En tu ejemplo, la aplicación se bloqueará sólo en símbolo internacional, que se pasó en stackoverflow.com/questions/28642781/… cuando se añadió Unicode plantillas capa de Roundup, y sys.setdefaultencoding("utf-8") es la única recomendación de forma de arreglar eso de choque. Lo que estoy escuchando de ustedes es que el bloqueo es un comportamiento deseado. No estoy de acuerdo en eso, lo siento.
    • the length you calculated is entirely wrong es un buen argumento, aunque. pastebin.ubuntu.com/10791721 da 3 y 6 de la consola. Pero esto se ve como un error en Python, que es incapaz de manejar mutibyte codificaciones.
    • el comportamiento deseado sería revisión Roundup. Si hay un error en un 3er grupo de producto, y la única manera es hacer un cambio global, entonces hay algo mal con ese producto.
    • ¿Por qué es que un error en la forma en Python maneja una codificación multibyte? La longitud de una cadena Unicode debe ser el número de puntos de codificación, no el número de bytes en un arbitrario codec. La longitud de una cadena de bytes debe ser el número de bytes. La Longitud del Contenido de encabezado debe contener el número de bytes, no el punto de código de recuento. No veo por qué este es un multi-byte frente de byte único problema de codificación.
    • en su pastie están recibiendo la longitud de cadenas de bytes, codificado en UTF-8. Usted obtener el mismo resultado sin el sys.setdefaultencoding() llamada.
    • Ok. Así que si no estamos utilizando len() para el procesamiento de cadenas, que son básicamente guardar para usar sys.setdefaultencoding("utf-8") (que parece ser el caso con Roundup núcleo que parece se limitó a mover cadenas de utf-8 el contenido de la base de datos para la capa de plantilla).
    • El problema que existe con los libs sólo aparecerá si el uso no-inglés caracteres propios (badlib), o alimentados por utf-8 cadena de procesamiento. Lo que lleva a la pregunta stackoverflow.com/questions/29586776/… – ¿cómo rastrear utf-8 cadenas se pasan externos libs.
    • El mencionado problema con Roundup es issues.roundup-tracker.org/issue2550811 – me gustaría saber cómo había que proponer para solucionarlo.
    • el uso de Jinja2 aquí revela que el Roundup no es la práctica de la Unicode sandwich enfoque; hacer todo el texto en la aplicación de unicode en el punto de entrada tan pronto como sea posible, y sólo codifican para los bytes en el punto de salida, tan tarde como sea posible. En este contexto, recomiendo la lectura / ver Ned Batchelder del Pragmática Unicode presentación.
    • Para ser más precisos «, pero el byte de la longitud calculada es del todo malo». Suponiendo que el número de bytes en una cadena es igual al número de caracteres es generalmente una mala idea, pero estaba seguro si str es ascii. Tratando de escribir código en py2 con unicode_literals y unicode en todas partes, parece que el cambio de la codificación predeterminada sería genial-pero supongo que mi verdadero problema se me presentó un str en algún lugar. Gracias por la explicación aclaratoria.

  3. 3

    Primero de todo: Muchos de los opositores de cambio predeterminado enc argumentan que su tonto porque su incluso cambiando ascii comparaciones

    Creo que es justo dejar en claro que, conforme con el original de la pregunta, veo que nadie defendiendo otra cosa que desviarse de Ascii a UTF-8.

    La setdefaultencoding(‘utf-16’) ejemplo parece ser siempre llevado adelante por aquellos que se oponen a la modificación 😉


    Con m = {‘a’: 1, ‘é’: 2} y el archivo ‘out.py’:

    # coding: utf-8
    print u'é' 

    A continuación:

    +---------------+-----------------------+-----------------+
    | DEF.ENC       | OPERATION             | RESULT (printed)|            
    +---------------+-----------------------+-----------------+
    | ANY           | u'abc' == 'abc'       | True            |     
    | (i.e.Ascii    | str(u'abc')           | 'abc'           |
    |  or UTF-8)    | '%s %s' % ('a', u'a') | u'a a'          | 
    |               | python out.py         | é               |
    |               | u'a' in m             | True            |
    |               | len(u'a'), len(a)     | (1, 1)          |
    |               | len(u'é'), len('é')   | (1, 2) [*]      |
    |               | u'é' in m             | False  (!)      |
    +---------------+-----------------------+-----------------+
    | UTF-8         | u'abé' == 'abé'       | True   [*]      |
    |               | str(u'é')             | 'é'             |
    |               | '%s %s' % ('é', u'é') | u'é é'          | 
    |               | python out.py | more  | 'é'             |
    +---------------+-----------------------+-----------------+
    | Ascii         | u'abé' == 'abé'       | False, Warning  |
    |               | str(u'é')             | Encoding Crash  |
    |               | '%s %s' % ('é', u'é') | Decoding Crash  |
    |               | python out.py | more  | Encoding Crash  |
    +---------------+-----------------------+-----------------+

    [*]: Resultado supone la mismo é. Ver a continuación en que.

    Mientras buscaba en esas operaciones, el cambio de la codificación predeterminada en el programa podría no parecer demasiado mal, dando resultados «más cerca» para tener Ascii sólo los datos.

    Sobre el hashing ( en ) y len() el comportamiento de obtener el mismo, a continuación, en Ascii (más en los resultados a continuación). Estas operaciones también muestran que existen diferencias significativas entre unicode y cadenas de bytes, que puede provocar errores lógicos, si se ignora por usted.

    Como se ha señalado ya: es un proceso de amplia opción, así que sólo tienes un disparo a elegir cuál es la razón por la que biblioteca los desarrolladores deben realmente nunca hacerlo, pero conseguir su interior en orden de modo que no es necesario confiar en python conversiones implícitas.
    También deben documentar claramente lo que esperan, y volver y negar de entrada no escribir la lib (como la función de normalización, ver más abajo).

    => Escribir programas con que configuración hace que sea un riesgo para otros el uso de los módulos de su programa en su código, al menos sin filtrado de entrada.

    Nota: Algunos opositores dicen que el def.enc. es aún un amplio sistema de opción (a través de sitecustomize.py), pero en tiempos más recientes de software de contenerización (docker) cada proceso puede ser iniciado en su ambiente perfecto w/o sobrecarga.


    Con respecto a la mezcla y la len() comportamiento:

    Dice que incluso con una modificación de la def.enc. todavía no se puede ser ignorante acerca de los tipos de cadenas de proceso en el programa. u» y » son diferentes secuencias de bytes en la memoria – no siempre, pero en general.

    Así que cuando pruebas asegúrese de que su programa se comporta correctamente también con falta de datos Ascii.

    Algunos dicen que el hecho de que el hash puede ser desigual cuando los datos de los valores de cambio – aunque debido a las conversiones implícitas de la ‘==’ operaciones permanecen iguales – es un argumento en contra de cambiar def.enc.

    Yo personalmente no comparto que desde los hash comportamiento sólo sigue siendo igual a w/o cambio de la misma. Aún veo un convincente ejemplo de mal comportamiento debido a que el establecimiento de un proceso de I ‘propio’.

    Todos en todos, con respecto a setdefaultencoding(«utf-8»): La respuesta sobre si su tonto o no debe ser más equilibrada.

    Depende.
    Mientras que él no evitar los accidentes por ejemplo, en la str() las operaciones en un registro de instrucción – el precio es una mayor oportunidad para que los resultados inesperados después, ya que mal tipos de hacerlo más largo en el código de cuyo correcto funcionamiento depende de un cierto tipo.

    En ningún caso, debe ser la alternativa para el aprendizaje de la diferencia entre cadenas de bytes y cadenas unicode para su propio código.


    Por último, la configuración de codificación predeterminada lejos de Ascii no hacer su vida más fácil para el común de las operaciones de texto como len(), cortar en rodajas y las comparaciones asumir que (byte)stringyfying todo con UTF-8 resuelve los problemas de aquí.

    Que desgraciadamente no en general.

    El ‘==’ y len() los resultados se mucho más de un problema complejo de lo que uno podría pensar – pero incluso con la mismo tipo en ambos lados.

    W/o def.enc. cambiado, «==» no siempre para no Ascii, como se muestra en la tabla. Con ella, funciona – a veces:

    Unicode hizo estandarizar alrededor de un millón de símbolos del mundo y les dio un número -, pero lamentablemente NO es 1:1 bijection entre los glifos se muestra a un usuario en los dispositivos de salida y los símbolos que se generan a partir de.

    Para motivar la investigación de este: Tener dos archivos, j1, j2 escrito con la mismo programa que utiliza la misma codificación, que contiene la entrada del usuario:

    >>> u1, u2 = open('j1').read(), open('j2').read()
    >>> print sys.version.split()[0], u1, u2, u1 == u2

    Resultado: 2.7.9 José José Falso (!)

    El uso de la impresión como una función en Py2 que ver la razón: por Desgracia, hay DOS formas de codificar el mismo carácter, el acentuado ‘e’:

    >>> print (sys.version.split()[0], u1, u2, u1 == u2)
    ('2.7.9', 'Jos\xc3\xa9', 'Jose\xcc\x81', False)

    Estúpido codec usted podría decir, pero no es culpa de el códec. Es un problema en unicode como tal.

    Por lo que incluso en Py3:

    >>> u1, u2 = open('j1').read(), open('j2').read()
    >>> print sys.version.split()[0], u1, u2, u1 == u2

    Resultado: 3.4.2 José José Falso (!)

    => Independiente de Py2 y Py3, en realidad, independiente de cualquier lenguaje de computación que utiliza: Para escribir software de calidad es probable que tenga que «normalizar» todas las entradas de usuario. El estándar unicode hizo estandarizar la normalización.
    En Python 2 y 3 de la unicodedata.normalizar la función es tu amigo.

    • Usted está asumiendo que su código fuente está codificado en UTF-8. O que todos de sus cadenas de bytes están codificados en UTF-8. Implícito de codificación de Unicode UTF-8, entonces la concatenación de los datos con cualquier otra cadena de bytes mediante una arbitraria de codificación sería un error enorme, y enmascarada por la configuración de la codificación predeterminada.
    • Otro problema es que el código que se puede se basan en la codificación o decodificación de los errores para el tipo de señal diferencias. Que incluye la 3ª parte de las bibliotecas. Mediante el establecimiento de una codificación predeterminada distintos de ASCII, puede no detectar bytes UTF-8 -> Unicode Unicode y -> bytes implícito codificaciones donde usted quiere realmente el uso explícito de las codificaciones.
    • En cualquier caso, yo todavía no he llegado a través de un caso de uso donde la configuración de la codificación predeterminada fue una idea mejor que la manipulación de las codificaciones correctamente. Es como el uso de variables globales, que no los uso, porque en la práctica aumentar significativamente el probabilidad de errores.
    • Así que si las pruebas se asegura de que el código funciona correctamente con datos que no son ASCII, ¿por qué no ir un paso más y manejar la codificación y decodificación correctamente, y no mezcle tipos arbitrariamente? ¿Por qué confiar en la setdefaultencoding() muleta a todos?
    • En general, no estoy realmente seguro de a dónde va con esta respuesta; sí, Unicode comparaciones tienen sus problemas, pero que realmente no están diciendo nada en claro acerca de por qué sys.setdefaultencoding() debe ser evitado.
    • eso es correcto – el objetivo de mi post era para dejar claro que 1. la respuesta a esta pregunta debe ser más equilibrada. 2. def.enc = utf-8 no se alivio el desarrollador de la comprensión de byte y de cadena unicode diferencias – por su propio código 3. la calidad de procesamiento de texto es mucho más complejo que los novatos podría pensar, incluso para las operaciones atómicas como len() y comparaciones.
    • Categóricamente negarse 1. es mi punto de vista descuidar los problemas de la gente tiene por ahí, especialmente con toneladas de código heredado – me atrevo a afirmar que mucho Py2 código fue escrito por gente motivada por la resolución de un problema específico fuera de procesamiento de texto – con toneladas de str() las operaciones en el interior… Además, muy de moda idiomas como el ir y el óxido en estos días de demostrar que es posible trabajar en un ‘utf-8 cadena de bytes sandwich’ y el uso de las funciones unicode sólo cuando sea necesario, a mediano plazo.
    • Python es, por supuesto, no vaya o herrumbre 🙂 veo que hay legado proyectos, pero eso no significa que cuando llegan a unicode manejo deben establecer una configuración global que puede tener consecuencias no deseadas. Indagación de los pequeños errores que esto puede introducir van a tomar tanto trabajo como la compuerta de las secciones y decodificamos su bytes unicode objetos en esos puntos. Eso es, al menos, el enfoque de Plone está tomando, por ejemplo.
    • En mi humilde opinión que la mejor respuesta hasta ahora, como claramente muestra las alternativas y consecuencias, frente a la dangerland! argumentos. Gracias.

  4. 2

    Real de la palabra ejemplo #1

    No funciona en unidad de pruebas.

    El test runner (nose, py.test, …) inicializa sys primero, y sólo entonces se descubre y las importaciones de los módulos. En ese momento es demasiado tarde para cambiar de codificación predeterminada.

    Por la misma virtud, no funciona si alguien se ejecuta su código como un módulo, como su inicialización que ocurra primero.

    Y sí, la mezcla de str y unicode y confiando en la conversión implícita sólo empuja el problema más abajo de la línea.

    • la unidad de prueba del módulo de importaciones módulo principal que establece sys.defaultencoding('utf-8'), así que ¿por qué no funciona?
    • También, puede proporcionar un ejemplo real donde sys.defaultencoding('utf-8') no funciona si alguien lo ejecuta como módulo?
    • por el tiempo de prueba módulo se importa, un montón de otros módulos fueron importados y algunas otras pruebas pueden haber sido ejecutado. Además, stdio ya estaba inicializado con verdadero sistema de codificación predeterminada. Es discutible no debe cambiar la codificación predeterminada en importar a todos, por ejemplo, pydoc no funciona bien. Además se debe restablecer el sistema al estado original después de su análisis se realizan. En resumen, si sólo probar el código y nada más, y sólo usar la conversión implícita de datos propia y no por ejemplo stdio, sí puede trabajar para usted. Pero sólo tú.
    • «stdio ya estaba inicializado con verdadero sistema de codificación predeterminada» – no es siempre ascii?
    • parece que el verdadero problema en tu caso es que todas las pruebas unitarias están compartiendo el mismo intérprete. Si la prueba de unidad se mete con el estado global, debe ser aislado y ejecutar en otro intérprete. Pero para el ámbito de la aplicación de todas las pruebas de unidad son consistentes y el uso de la misma sys.defaultencoding('utf-8'). También, tenga en cuenta que yo UTF-8 es fundamental para esta pregunta, y es compatible con ASCII.
    • sys.setdefaultencoding() no establece de entrada o de salida de la codificación; creo que no entendieron bien lo que la función de no. Se establece el códec utilizado cuando implícitamente codificación de unicode a str o decodificación str a unicode cuando la mezcla de los tipos.
    • Si se trabaja con la unidad de pruebas o no es entonces depende de los mismos factores como la 3ª parte de las bibliotecas; si el código es confiando en ASCII siendo el valor predeterminado, a continuación, esas pruebas pueden fallar debido a que por defecto ha cambiado, a nivel mundial.
    • re: módulos de mezcla. Otros módulos se cargan en primer lugar, que ya importados sys. Cuando el módulo se ejecuta, es demasiado tarde para cambiar la codificación. Disponible hacks son sitecustomize.py y reload(sys). El anterior no funciona con la unidad de pruebas y no es extensible. La última es la magia negra, estás en tu propio.
    • De hecho stdio es inicializado basado en PYTHONIOENCODING y la configuración regional. Gracias, @MartijnPieters.

  5. 1

    Una cosa que debe saber es

    Python 2 uso sys.getdefaultencoding() para decodificar/codificar entre str y unicode

    Peligros de sys.setdefaultencoding('utf-8')

    así que si cambiamos la codificación predeterminada, habrá todo tipo de cuestiones incompatibles. por ejemplo:

    # coding: utf-8
    import sys
    print "你好" == u"你好"
    # False
    reload(sys)
    sys.setdefaultencoding("utf-8")
    print "你好" == u"你好"
    # True

    Más ejemplos:

    Que dijo, creo recordar que hay algún blog que sugiere utilizar unicode cuando sea posible, y sólo la cadena de bits cuando lidiar con I/O. creo que si la siguen esta convención, la vida será mucho más fácil. Más soluciones se pueden encontrar:

    • Es posible sobrecargar == operador para la sub-cadenas para que siempre salga con un error cuando la conversión implícita como ocurre esto?
    • No, No puede. En python no hay manera de cambiar la definición de builtin tipo
    • A partir de lo que observa de lo anterior, se deben de utilizar sys.setdefaultencoding("utf-8") todo el tiempo con el fin de hacer "你好" == u"你好" como True que es correcto
    • Exactamente!! Como 3 == 3.0 es también True. Equaliity es una declaración acerca de la información en sí y no sobre qué tipo de datos está envuelto en.
    • 2018 ahora y creo que es cerca de loco, que la misma gente que todos los años se negó a permitir que python def.enc utf-8 cambio, se negó a reparar un comportamiento como este, porque le ser «peligroso»…. >>> print "abc" == u"abc" => True >>> print "你bc" == u"你bc" => False …son los mismos que, en su unicode sándwich idea, aceptar un silencio decode('utf-8') en casi CUALQUIER e/S lib de Python3.
    • Mejor que no. FYI he actualizado mi respuesta para proporcionar una solución.
    • href=»http://utf8everywhere.org/» >utf8everywhere.org – el unicode sándwich idea, es decir, innecesariamente decodificar todos los valores de texto en I/O (y dejar que el I/O librerías para hacer decode(‘utf-8’) de forma automática, en todas partes) es simple roto, en comparación con el uso de unicode como una api cuando usted necesita el significado semántico de los valores de los seres humanos, que rara vez es el caso de la informática. Aún más: En tiempos de microservices en todas partes, I/O está en todas partes y dentro de los sistemas de tuberías de elaboración de atención acerca de la presencia de de los valores de texto, no su significado semántico de los seres humanos. La decodificación no tiene sentido y es propenso a errores, en el 99%.
    • Lo que uno quiso decir por la solución? Veo que la única solución para la interfaz con Unicode en Python 2 es por sys.setdefaultencoding("utf-8")
    • href=»https://pythonhosted.org/kitchen/unicode-frustrations.html#a-few-solutions» >pythonhosted.org/kitchen/…
    • Estoy de acuerdo con usted, tal vez podemos utilizar algunas de las bibliotecas para ayudarnos a lidiar con esto. pythonhosted.org/kitchen/…
    • la cocina está bien diseñado de la biblioteca. Aún así, muchas de las «frustraciones», dirigida en su vínculo simplemente no están presentes con la defaultencoding a utf-8 interruptor. El mundo se ha acordado en UTF-8 como omnipresente texto codificación de los datos, mientras tanto – y esa es la razón por la que Python3 funciona en todos: Compruebe las e/S lib (redis, httpie, …) y verás .decode(‘utf-8’) en todas partes con el fin de transmitir valores a sus «unicode sandwhich». Con Py2 & dflt.la codificación utf8 todo esto no es necesario en el mundo ideal. Uno puede utilizar unicode como API donde sea necesario y apropiado conversión se realiza mediante el lenguaje.

Dejar respuesta

Please enter your comment!
Please enter your name here