أفضل ممارسات نوع الإخراج وممارسات الترميز لوظائف __repr __ ()؟

StackOverflow https://stackoverflow.com/questions/3627793

  •  26-09-2019
  •  | 
  •  

سؤال

في الآونة الأخيرة ، واجهت الكثير من المتاعب __repr__(), format(), والترميزات. يجب أن يكون إخراج __repr__() تكون مشفرة أو تكون سلسلة يونيكود؟ هل هناك أفضل ترميز لنتيجة __repr__() في بيثون؟ ما أريد إخراجه لديه أحرف غير ASCII.

أستخدم Python 2.x ، وأريد كتابة رمز يمكن تكييفه بسهولة مع Python 3. يستخدم البرنامج بالتالي

# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function  # The 'Hello' literal represents a Unicode object

فيما يلي بعض المشكلات الإضافية التي كانت تزعجني ، وأنا أبحث عن حل يحلها:

  1. يجب أن تعمل الطباعة على محطة UTF-8 (لدي sys.stdout.encoding ضبط ل UTF-8, ، ولكن سيكون من الأفضل إذا نجحت حالات أخرى أيضًا).
  2. يجب أن تعمل الأنابيب إلى ملف (مشفر في UTF-8) (في هذه الحالة ، sys.stdout.encoding هو None).
  3. رمزتي للكثيرين __repr__() الوظائف حاليا لديها الكثير return ….encode('utf-8'), ، وهذا ثقيل. هل هناك أي شيء قوي وأخف وزنا؟
  4. في بعض الحالات ، لدي وحوش قبيحة مثل return ('<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8'), ، أي ، تم فك تشفير تمثيل الكائنات ، ووضعه في سلسلة تنسيق ، ثم إعادة ترميزها. أود تجنب مثل هذه التحولات المعقدة.

ما الذي تنصح به من أجل الكتابة البسيطة __repr__() الوظائف التي تتصرف بشكل جيد فيما يتعلق بهذه الأسئلة الترميز؟

هل كانت مفيدة؟

المحلول

في Python2 ، __repr____str__) يجب إرجاع كائن سلسلة ، وليس كائن Unicode. في Python3 ، يتم عكس الوضع ، __repr__ و __str__يجب إرجاع كائنات Unicode ، وليس الكائنات البايت (Née String):

class Foo(object):
    def __repr__(self):
        return u'\N{WHITE SMILING FACE}' 

class Bar(object):
    def __repr__(self):
        return u'\N{WHITE SMILING FACE}'.encode('utf8')

repr(Bar())
# ☺
repr(Foo())
# UnicodeEncodeError: 'ascii' codec can't encode character u'\u263a' in position 0: ordinal not in range(128)

في Python2 ، ليس لديك خيار حقًا. عليك اختيار ترميز لقيمة الإرجاع __repr__.

بالمناسبة ، هل قرأت printfails wiki؟ قد لا يجيب بشكل مباشر على أسئلتك الأخرى ، لكنني وجدت أنه مفيد في إلقاء الضوء على سبب حدوث بعض الأخطاء.


عند استخدام from __future__ import unicode_literals,

'<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')

يمكن أن يكون أكثر كتابًا أكثر من ذلك

str('<{}>').format(repr(x))

على افتراض str يشفر إلى utf-8 على نظامك.

بدون from __future__ import unicode_literals, ، يمكن كتابة التعبير على النحو التالي:

'<{}>'.format(repr(x))

نصائح أخرى

أعتقد أن الديكور يمكن أن يديره __repr__ عدم التوافق بطريقة عاقلة. هذا ما أستخدمه:

from __future__ import unicode_literals, print_function
import sys

def force_encoded_string_output(func):

    if sys.version_info.major < 3:

        def _func(*args, **kwargs):
            return func(*args, **kwargs).encode(sys.stdout.encoding or 'utf-8')

        return _func

    else:
        return func


class MyDummyClass(object):

    @force_encoded_string_output
    def __repr__(self):
        return 'My Dummy Class! \N{WHITE SMILING FACE}'

أستخدم وظيفة مثل ما يلي:

def stdout_encode(u, default='UTF8'):
    if sys.stdout.encoding:
        return u.encode(sys.stdout.encoding)
    return u.encode(default)

ثم بلدي __repr__ الوظائف تبدو هكذا:

def __repr__(self):
    return stdout_encode(u'<MyClass {0} {1}>'.format(self.abcd, self.efgh))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top