Получить str-ревью с двойными кавычками Python

Я использую небольшой скрипт Python для генерации некоторых двоичных данных, которые будут использоваться в заголовке C.

Эти данные должны быть объявлены как char[] , и будет хорошо, если бы он мог быть закодирован как строка (с соответствующими управляющими последовательностями, если они не находятся в диапазоне символов ASCII для печати), чтобы заголовок был более компактным, чем с десятичная или шестнадцатеричная кодировка массива.

Проблема в том, что когда я печатаю repr строки Python, она ограничивается одинарными кавычками, а C не нравится. Наивное решение состоит в том, чтобы сделать:

 '"%s"'%repr(data)[1:-1] 

но это не работает, когда один из байтов данных является двойной кавычкой, поэтому мне также нужно будет их избежать.

Я думаю, что простая replace('"', '\\"') могла бы выполнить эту работу, но, возможно, там есть лучшее, более питоническое решение.

Дополнительная точка :

Было бы удобно также разделить данные в строках примерно на 80 символов, но опять же простой подход к разделению исходной строки в кусках размером 80 не будет работать, так как каждый непечатаемый символ принимает 2 или 3 символа в escape-последовательности , Разделение списка в кусках 80 после получения рефера также не поможет, поскольку оно может разделить escape-последовательность.

Какие-либо предложения?

3 Solutions collect form web for “Получить str-ревью с двойными кавычками Python”

repr () не то, что вы хотите. Существует фундаментальная проблема: repr () может использовать любое представление строки, которое может быть оценено как Python для создания строки. Это означает, что теоретически, что он может решить использовать любое количество других конструкций, которые не были бы действительны в C, например «длинные строки» «».

Вероятно, этот код правильный. Я использовал стандартную упаковку на 140, что является разумным значением в 2009 году, но если вы действительно хотите, чтобы ваш код был до 80 столбцов, просто измените его.

Если unicode = True, он выводит строку L "wide", которая может успешно хранить escape-коды Unicode. Кроме того, вам может потребоваться преобразовать символы Unicode в UTF-8 и вывести их с экранированием в зависимости от используемой вами программы.

 def string_to_c(s, max_length = 140, unicode=False): ret = [] # Try to split on whitespace, not in the middle of a word. split_at_space_pos = max_length - 10 if split_at_space_pos < 10: split_at_space_pos = None position = 0 if unicode: position += 1 ret.append('L') ret.append('"') position += 1 for c in s: newline = False if c == "\n": to_add = "\\\n" newline = True elif ord(c) < 32 or 0x80 <= ord(c) <= 0xff: to_add = "\\x%02x" % ord(c) elif ord(c) > 0xff: if not unicode: raise ValueError, "string contains unicode character but unicode=False" to_add = "\\u%04x" % ord(c) elif "\\\"".find(c) != -1: to_add = "\\%c" % c else: to_add = c ret.append(to_add) position += len(to_add) if newline: position = 0 if split_at_space_pos is not None and position >= split_at_space_pos and " \t".find(c) != -1: ret.append("\\\n") position = 0 elif position >= max_length: ret.append("\\\n") position = 0 ret.append('"') return "".join(ret) print string_to_c("testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing testing", max_length = 20) print string_to_c("Escapes: \"quote\" \\backslash\\ \x00 \x1f testing \x80 \xff") print string_to_c(u"Unicode: \u1234", unicode=True) print string_to_c("""New lines""") 

Если вы запрашиваете python str для своего объявления, я не думаю, что тип цитаты действительно настраивается. Из функции PyString_Repr в исходном дереве python 2.6.4:

  /* figure out which quote to use; single is preferred */ quote = '\''; if (smartquotes && memchr(op->ob_sval, '\'', Py_SIZE(op)) && !memchr(op->ob_sval, '"', Py_SIZE(op))) quote = '"'; 

Таким образом, я предполагаю использовать двойные кавычки, если в строке есть одна цитата, но даже не тогда, если в строке есть двойная кавычка.

Я бы попробовал что-то вроде написания собственного класса, чтобы содержать строковые данные, а не использовать встроенную строку для этого. Один из вариантов – вывести класс из str и написать собственный repr :

 class MyString(str): __slots__ = [] def __repr__(self): return '"%s"' % self.replace('"', r'\"') print repr(MyString(r'foo"bar')) 

Или, не используйте repr вообще:

 def ready_string(string): return '"%s"' % string.replace('"', r'\"') print ready_string(r'foo"bar') 

Это упрощенное цитирование может не выполнять «правильную» вещь, если в строке уже есть скрытая цитата.

Лучше не взламывать repr() а использовать правую кодировку с самого начала. Вы можете получить кодировку repr сразу с помощью кодировки string_escape

 >>> "naïveté".encode("string_escape") 'na\\xc3\\xafvet\\xc3\\xa9' >>> print _ na\xc3\xafvet\xc3\xa9 

Для избежания «-центов я думаю, используя простую замену после escape-кодирования, строка является абсолютно однозначным процессом:

 >>> '"%s"' % 'data:\x00\x01 "like this"'.encode("string_escape").replace('"', r'\"') '"data:\\x00\\x01 \\"like this\\""' >>> print _ "data:\x00\x01 \"like this\"" 
  • небезопасное использование относительного rpath libboost.dylib при создании boost.python helloword demo?
  • Как передать поток openCV на HTML-страницу?
  • Каково фактическое воздействие вызова socket.recv с bufsize, который не является силой 2?
  • Передача указателя numpy (dtype = np.bool) на C ++
  • Флажки QTreeView
  • Алгоритм разницы текста
  • TNonblockingServer в аварийных ситуациях, когда открывается TFramedTransport
  • Диффи-Хеллман (до RC4) с Wincrypt From Python
  • Python - лучший язык программирования в мире.