我有一个包含数据作为属性的类,它有一个返回包含这些属性的元组的方法:
class myclass(object):
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c
def tuple(self):
return (self.a, self.b, self.c)
我将此类用作元组,其中可以通过属性名称修改/读取项(属性)。现在我想创建这个类的对象,这些对象将是常量并具有预定义的属性值,然后我可以将其分配给变量/可变对象,从而初始化此变量对象的属性以匹配常量对象,而在同时保留修改属性值的能力。例如,我想这样做:
constant_object = myclass(1,2,3)
variable_object = constant_object
variable_object.a = 999
现在当然这在python中不起作用,所以我想知道获得这种功能的最佳方法是什么?
答案 0 :(得分:1)
import copy
class myclass(object):
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c
def tuple(self):
return (self.a, self.b, self.c)
constant_object = myclass(1,2,3)
variable_object = copy.deepcopy(constant_object)
variable_object.a = 999
print constant_object.a
print variable_object.a
输出:
1
999
答案 1 :(得分:1)
在这种情况下,深度复制并不是完全必要的,因为您设置tuple
方法的方式
class myclass(object):
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c
def tuple(self):
return (self.a, self.b, self.c)
constant_object = myclass(1,2,3)
variable_object = myclass(*constant_object.tuple())
variable_object.a = 999
>>> constant_object.a
1
>>> variable_object.a
999
通常(正如其他人所建议的那样),你想要深度复制。这会创建一个全新的对象,与被复制的对象无关。但是,鉴于您仅使用int
s,深度复制是过度的。你最好做一个浅拷贝。事实上,在你已经拥有的对象的参数上调用类构造函数甚至可能更快,因为这些参数是int
s。这就是我建议上面代码的原因。
答案 2 :(得分:1)
现在我想创建这个类的对象,它们是常量并具有预定义的属性值,然后我可以将其分配给变量/可变对象,从而初始化此变量对象的属性以匹配常量对象,
嗯,你不能拥有那个。 Python中的赋值不会初始化任何内容。它不会复制或创建任何内容。它只是给现有值一个新名称。
如果要初始化对象,在Python中执行此操作的方法是调用构造函数。
所以,使用现有代码:
new_object = myclass(old_object.a, old_object.b, old_object.c)
如果你看一下大多数内置和stdlib类,它会更方便。例如:
a = set([1, 2, 3])
b = set(a)
他们是如何做到的?简单。只需定义一个可以使用现有实例调用的__init__
方法。 (在set
的情况下,这是免费的,因为set
可以使用任何可迭代进行初始化,set
可以迭代。)
如果你不想放弃现有的设计,你需要一个非常笨拙的__init__
,但它至少是可行的。也许这个:
_sentinel = object()
def __init__(myclass_or_a, b=_sentinel, c=_sentinel):
if isinstance(a, myclass):
self.a, self.b, self.c = myclass_or_a.a, myclass_or_a.b, myclass_or_a.c
else:
self.a, self.b, self.c = myclass_or_a, b, c
...加上一些错误处理,以检查第一种情况下的b is _sentinel
,而不是另一种情况。
所以,不过你这样做了:
constant_object = myclass(1,2,3)
variable_object = myclass(constant_object)
variable_object.a = 999