我想要两个对象共享一个字符串对象。如何将字符串对象从第一个传递到第二个,以使一个应用的更改对另一个更明显?我猜我必须将字符串包装在一个缓冲区对象中并执行各种复杂性以使其工作。
然而,我倾向于过度思考问题,所以毫无疑问有一种更简单的方法。或者也许共享字符串是错误的方式去?请记住,我希望两个对象都能够编辑字符串。有什么想法吗?
以下是我可以使用的解决方案示例:
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类,描述符和描述符的imptaal _buffer变量。
另一种方法是让其中一个对象负责字符串,然后让它公开一个接口来更改字符串。更简单但效果不尽相同。
答案 0 :(得分:2)
我想要两个对象共享一个 字符串对象。
如果你只是传递字符串,他们会这样做 - 除非你告诉它复制,否则Python不会复制。
如何传递字符串对象 第一个到第二个这样任何 一个人应用的更改将是可见的 对方?
永远不会对字符串对象进行任何更改(它是不可变的!),因此您的要求很容易满足(因为错误的前提条件暗示了任何内容)。
我猜我必须这样做 将字符串包装在一种缓冲区中 对象并做各种复杂性 让它发挥作用。
您可以使用(假设这是Python 2并且您需要一个字节字符串)array.array
,其类型标识为c
。数组是可变的,所以你确实可以改变它们(使用变异方法 - 和一些运算符,这是方法的一个特例,因为它们在对象上调用特殊方法)。它们没有无数的非变异字符串方法,所以,如果你需要它们,你确实需要一个简单的包装器(将所述方法委托给包装器也保存的数组的str(...)
)。
似乎没有任何特殊的复杂性,除非你想要做一些真正奇怪的事情,因为你似乎给出了你的示例代码(有赋值,即 *重新绑定一个名称,神奇地影响一个不同的名称 - 这与以前绑定到你正在重新绑定的名称的任何对象完全无关,也不会改变它对象以任何方式 - 它“改变”的唯一对象是持有属性,因此很明显你需要在所述对象上使用描述符或其他魔法。)
您似乎来自某种语言,其中变量(尤其是字符串)是“数据容器”(如C,Fortran或C ++)。在Python中(比如说,在Java中),名称(称为其他人称之为“变量”的首选方式)始终只是引用到对象,它们不包含除了这样的参考之外的任何东西有些对象可以更改,有些则不能,但这与赋值语句完全无关(参见注释1)(它不会更改对象:它重新绑定名称)。
(注释1):除了重新绑定属性或项目之外确实改变了“包含”该项或属性的对象 - 对象可以包含的内容,它的名称不包含
答案 1 :(得分: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!
答案 2 :(得分:1)
我不是python的优秀专家,但我认为如果你在模块中声明一个变量并为该变量添加一个getter / setter到模块,你将能够以这种方式共享它。