Class constructor able to init with an instance of the same class object
python可以创建一个可以用同一类对象的实例初始化的类吗?
我试过了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Class(): def __init__(self,**kwargs): print self self = kwargs.get('obj',self) print self if not hasattr(self,'attr1'): print 'attr1' self.attr1 = kwargs.pop('attr1',[]) if not hasattr(self,'attr2'): print 'attr2' self.attr2 = kwargs.pop('attr2',[]) print self self.attr1 = kwargs.pop('attr1',self.attr1) self.attr2 = kwargs.pop('attr2',self.attr2) print self.attr1 print self.attr2 |
如果我创建了一个新实例,就没有问题:
1 2 3 | inst = Class(attr1=[1,2,3]) print inst print inst.attr1,inst.attr2 |
号
输出为:
1 2 3 4 5 6 7 8 9 | <__main__.Class instance at 0x7f2025834cf8> <__main__.Class instance at 0x7f2025834cf8> attr1 attr2 <__main__.Class instance at 0x7f2025834cf8> [1, 2, 3] [] <__main__.Class instance at 0x7f2025834cf8> [1, 2, 3] [] |
但如果我用实例
1 2 3 | inst2 = Class(obj=inst) print inst2 print inst2.attr1,inst2.attr2 |
。
输出为:
1 2 3 4 5 6 | <__main__.Class instance at 0x7f202584b7e8> <__main__.Class instance at 0x7f2025835830> <__main__.Class instance at 0x7f2025835830> [1, 2, 3] [] <__main__.Class instance at 0x7f202584b7e8> |
1 2 3 4 5 6 7 | AttributeError Traceback (most recent call last) <ipython-input-228-29c9869a9f4d> in <module>() 1 inst2 = Class(obj=inst) 2 print inst2 ----> 3 print inst2.attr1,inst2.attr2 AttributeError: Class instance has no attribute 'attr1' |
。
我处理这个问题,但我不知道如何解决:
- 在第一种情况下,实例地址总是相同的("内部"和"外部"类)
在第二种情况下:
- "内部"课程:
- init调用在新地址创建新实例
- 然后将self设置为上一个实例并更改地址:确定
self 已经有了attr1 和atrr2 的属性:好的。但在课堂之外:
inst2 有init的地址,没有属性!
怎么了?在Python中,如何处理矫揉造作?这是一种很好的方式吗?
不知道你想达到什么样的目标,但从技术上讲,你的错误是:
1 | self = kwargs.get('object',self) |
如果您想要将属性从
1 2 3 4 5 | other = kwargs.get('object') if other is not None: self.attrx = other.attrx self.attry = other.attry # etc |
号
哦,是的:Python是高级语言,没有什么比"地址矫揉造作"更像的了——您所拥有的只是引用对象的名称(实际上,名称=>对象映射)。名称只是一个名称,而对象实际生活的地方并不是您关心的问题。
感谢以上评论,我了解两件事:
self 只是一个局部变量,而不是类实例_init_ 是一个类内置方法,用于从其他对象初始化实例。
因此,如果我想从现有实例初始化一个新的类实例,我只需要创建一个"initializer"方法来调用
_init_ :1
2
3
4
5
6
7
8
9
10
11
12class Class():
def __init__(self,**kwargs):
self.attr1 = kwargs.pop('attr1',[])
self.attr2 = kwargs.pop('attr2',[])
def Class(self,**kwargs):
return Class(attr1 = kwargs.pop('attr1',self.attr1),\
attr2 = kwargs.pop('attr2',self.attr2))
像这样使用:
1 2 3 | inst = Class(attr1=[1,2,3]) print inst print inst.attr1,inst.attr2 |
。
输出:
1 2 | <__main__.Class instance at 0x7eff842d5368> [1, 2, 3] [] |
1 2 3 | inst2 = inst.Class(attr2=[12,11]) print inst2 print inst2.attr1,inst2.attr2 |
。
输出:
1 2 | <__main__.Class instance at 0x7eff842d56c8> [1, 2, 3] [12, 11] |
。