Итак, просто чтобы понять это, преимущество интерфейса в том, что я могу отделить вызов метода от любого конкретного класса. Вместо этого создается экземпляр интерфейса, где реализация предоставляется из того класса, который я выбираю, который реализует этот интерфейс. Таким образом, у меня есть много классов, которые имеют сходную, но немного отличающуюся функциональность, а в некоторых случаях (случаи, связанные с намерением интерфейса) не заботятся о том, какой именно объект.
Например, я мог бы интерфейс движения. Метод, который делает что-то «движение», и любой объект (Person, Car, Cat), который реализует интерфейс движения, может быть передан и передан для перемещения. Без метода, каждый из которых знает тип класса.
Вот какой код, который примет любой символ, который отображает два слова UTF-16 и преобразует их в шестнадцатеричную последовательность.
s = '\U0001f62c \U0001f60e hello'
def pairup(b):
return [(b[i] << 8 | b[i+1]) for i in range(0, len(b), 2)]
def utf16(c):
e = c.encode('utf_16_be')
return ''.join(chr(x) for x in pairup(e))
u = ''.join(utf16(c) for c in s)
print(repr(u))
print(u[0] == '\ud83d' and u[1] == '\ude2c')
print(len(u))
'\ud83d\ude2c \ud83d\ude0e hello'
True
11
Я думал, что это будет непросто, но это оказалось сложнее, чем я ожидал. Тем более, что я не понял проблему правильно в первый раз.
Непонятно, зачем вам это нужно, но вот как вы могли бы представить символы Unicode без BMP в качестве суррогатных пар:
#!/usr/bin/env python3
import re
def as_surrogates(astral):
b = astral.group().encode('utf-16be')
return ''.join([b[i:i+2].decode('utf-16be', 'surrogatepass')
for i in range(0, len(b), 2)])
s = '\U0001f62c \U0001f60e hello'
u = re.sub(r'[^\u0000-\uFFFF]+', as_surrogates, s)
print(ascii(u))
assert u.encode('utf-16', 'surrogatepass').decode('utf-16') == s
'\ud83d\ude2c \ud83d\ude0e hello'