Я хочу, чтобы два объекта разделили один строковый объект. Как передать строковый объект с первого на второй так, чтобы любые изменения, применяемые одним, были видны другому? Я предполагаю, что мне придется обернуть строку в виде буферного объекта и сделать всевозможную сложность, чтобы заставить ее работать.
Тем не менее, у меня есть тенденция переубеждать проблемы, поэтому, несомненно, есть более простой способ. Или, может быть, обмен цепочкой - это неправильный способ? Имейте в виду, что я хочу, чтобы оба объекта могли редактировать строку. Любые идеи?
Вот пример решения, которое я мог бы использовать:
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.
Альтернативой является установка одного из объектов, отвечающих за строку, а затем ее отображение интерфейса для внесения изменений в строку. Упрощенный, но не совсем такой же эффект.
Я хочу, чтобы два объекта разделили один Строковый объект.
Они будут, если вы просто передадите строку - Python не копирует, если вы не скажете его, чтобы скопировать.
Как передать строковый объект из от первого до второго, так что любой изменения, примененные одним, будут видны к другому?
В никогда не может быть никаких изменений, внесенных в строковый объект (он непреложный!), поэтому ваше требование тривиально выполняется (поскольку ложное предварительное условие подразумевает что-либо).
Я предполагаю, что мне придется оберните строку в виде буфера объекта и выполнять всевозможные сложности чтобы заставить его работать.
Вы можете использовать (предположим, что это Python 2 и вы хотите строку байтов) array.array
с кодом типа c
. Массивы изменяемы, поэтому вы действительно можете их изменить (с помощью методов mutating - и некоторых операторов, которые являются особым случаем методов, поскольку они вызывают специальные методы для объекта). У них нет бесчисленных не мутирующих методов строк, поэтому, если вам это нужно, вам действительно понадобится простая оболочка (делегирование указанных методов к str(...)
массива, который также содержит оболочку).
Кажется, что не должно быть особых сложностей, если, конечно, вы не хотите делать что-то действительно странное, поскольку вы, кажется, даете свой примерный код (у вас есть назначение, т.е. * перевязка названия, магически влияют на другое имя - это абсолютно не имеет никакого отношения к тому, какой объект ранее был привязан к имени, которое вы перевязываете, и никак не меняет этот объект - только объект, который он "изменяет", - это один удерживающий атрибут, поэтому очевидно, что вам нужны дескрипторы или другая магия для указанного объекта).
Вы, кажется, исходите из какого-то языка, где переменные (и особенно строки) являются "контейнерами данных" (например, C, Fortran или С++). В Python (например, на Java) имена (предпочтительный способ вызова того, что другие называют "переменными" ) всегда просто ссылаются на объекты, они не содержат ничего, кроме точно такой ссылки. Некоторые объекты могут быть изменены, некоторые из них не могут, но это абсолютно не имеет отношения к оператору присваивания (см. Примечание 1) (который не меняет объекты: он переименовывает имена).
(примечание 1): за исключением того, что переупорядочение атрибута или элемента изменяет объект, который "содержит" этот элемент или атрибут - объекты могут содержать и содержать, это имена, которые этого не делают.
Просто поместите свое значение в общий список и назначьте список для обоих объектов.
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!
Я не большой эксперт в python, но я думаю, что если вы объявите переменную в модуле и добавите getter/setter в модуль для этой переменной, вы сможете поделиться ею таким образом.