разделить строку между двумя объектами

1

Я хочу, чтобы два объекта разделили один строковый объект. Как передать строковый объект с первого на второй так, чтобы любые изменения, применяемые одним, были видны другому? Я предполагаю, что мне придется обернуть строку в виде буферного объекта и сделать всевозможную сложность, чтобы заставить ее работать.

Тем не менее, у меня есть тенденция переубеждать проблемы, поэтому, несомненно, есть более простой способ. Или, может быть, обмен цепочкой - это неправильный способ? Имейте в виду, что я хочу, чтобы оба объекта могли редактировать строку. Любые идеи?

Вот пример решения, которое я мог бы использовать:

class Buffer(object):
    def __init__(self):
        self.data = ""
    def assign(self, value):
        self.data = str(value)
    def __getattr__(self, name):
        return getattr(self.data, name)

class Descriptor(object):
    def __get__(self, instance, owner):
        return instance._buffer.data
    def __set__(self, instance, value):
        if not hasattr(instance, "_buffer"):
            if isinstance(value, Buffer):
                instance._buffer = value
                return
            instance._buffer = Buffer()
        instance._buffer.assign(value)

class First(object):
    data = Descriptor()
    def __init__(self, data):
        self.data = data
    def read(self, size=-1):
        if size < 0:
            size = len(self.data)
        data = self.data[:size]
        self.data = self.data[size:]
        return data

class Second(object):
    data = Descriptor()
    def __init__(self, data):
        self.data = data
    def add(self, newdata):
        self.data += newdata
    def reset(self):
        self.data = ""
    def spawn(self):
        return First(self._buffer)

s = Second("stuff")
f = s.spawn()
f.data == s.data
#True
f.read(2)
#"st"
f.data
# "uff"
f.data == s.data
#True
s.data
#"uff"
s._buffer == f._buffer
#True

Опять же, это кажется абсолютным излишеством для того, что кажется простой проблемой. Кроме того, для этого требуется использование класса Buffer, дескриптора и переменной наложения _buffer.

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

Теги:
string
object

3 ответа

2
Лучший ответ

Я хочу, чтобы два объекта разделили один Строковый объект.

Они будут, если вы просто передадите строку - Python не копирует, если вы не скажете его, чтобы скопировать.

Как передать строковый объект из от первого до второго, так что любой изменения, примененные одним, будут видны к другому?

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

Я предполагаю, что мне придется оберните строку в виде буфера объекта и выполнять всевозможные сложности чтобы заставить его работать.

Вы можете использовать (предположим, что это Python 2 и вы хотите строку байтов) array.array с кодом типа c. Массивы изменяемы, поэтому вы действительно можете их изменить (с помощью методов mutating - и некоторых операторов, которые являются особым случаем методов, поскольку они вызывают специальные методы для объекта). У них нет бесчисленных не мутирующих методов строк, поэтому, если вам это нужно, вам действительно понадобится простая оболочка (делегирование указанных методов к str(...) массива, который также содержит оболочку).

Кажется, что не должно быть особых сложностей, если, конечно, вы не хотите делать что-то действительно странное, поскольку вы, кажется, даете свой примерный код (у вас есть назначение, т.е. * перевязка названия, магически влияют на другое имя - это абсолютно не имеет никакого отношения к тому, какой объект ранее был привязан к имени, которое вы перевязываете, и никак не меняет этот объект - только объект, который он "изменяет", - это один удерживающий атрибут, поэтому очевидно, что вам нужны дескрипторы или другая магия для указанного объекта).

Вы, кажется, исходите из какого-то языка, где переменные (и особенно строки) являются "контейнерами данных" (например, C, Fortran или С++). В Python (например, на Java) имена (предпочтительный способ вызова того, что другие называют "переменными" ) всегда просто ссылаются на объекты, они не содержат ничего, кроме точно такой ссылки. Некоторые объекты могут быть изменены, некоторые из них не могут, но это абсолютно не имеет отношения к оператору присваивания (см. Примечание 1) (который не меняет объекты: он переименовывает имена).

(примечание 1): за исключением того, что переупорядочение атрибута или элемента изменяет объект, который "содержит" этот элемент или атрибут - объекты могут содержать и содержать, это имена, которые этого не делают.

  • 0
    @ Алекс, снова верно. Может быть, моя формулировка была немного не в порядке. Это не так, что мне нужно изменить строку, скорее, я хочу, чтобы строковые данные были синхронизированы между двумя объектами. Это назначение , где эта функциональность нуждается в специальном лечении. Как вы сказали, строки неизменны. Так что мой пример кажется подходящим решением. Как вы думаете, есть лучшая альтернатива, где два объекта могут синхронизировать строковые данные? Как насчет альтернативы, которую я поставил в конце?
  • 0
    Если честно, мои потребности могут быть или не быть особенными. У меня есть код, который подключается через XML-RPC к удаленному хосту. Я хочу протестировать свой код с локальным симулякром удаленного хоста. Чтобы сделать это, я планировал обмануть все это, используя поддельный сокет, метод makefile которого вернет поддельный объект файла (который использует модуль httplib). Я хотел, чтобы данные в фальшивом сокете оставались синхронизированными с фальшивым файлом, как если бы объект файла, возвращаемый реальным сокетом, фактически имел те же данные. Так что у вас есть это.
Показать ещё 6 комментариев
2

Просто поместите свое значение в общий список и назначьте список для обоих объектов.

class A(object):
    def __init__(self, strcontainer):
        self.strcontainer = strcontainer
    def upcase(self):
        self.strcontainer[0] = self.strcontainer[0].upper()
    def __str__(self):
        return self.strcontainer[0]

# create a string, inside a shareable list
shared = ['Hello, World!']
x = A(shared)
y = A(shared)

# both objects have the same list
print id(x.strcontainer)
print id(y.strcontainer)

# change value in x
x.upcase()

# show how value is changed in both x and y
print str(x)
print str(y)

Печать

10534024
10534024
HELLO, WORLD!
HELLO, WORLD!
  • 0
    Спасибо за ответ. Ваша рекомендация на самом деле является эффективным решением, но менее прозрачным. Конечно, прозрачность не может быть актуальной. Опять же, я хочу, чтобы общие данные действовали как строка, а не как список.
1

Я не большой эксперт в python, но я думаю, что если вы объявите переменную в модуле и добавите getter/setter в модуль для этой переменной, вы сможете поделиться ею таким образом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню