python 构造函数里的同名变量_关于python:能够使用相同类对象的实例初始化的类构造函数...

python可以创建一个可以用同一类对象的实例初始化的类吗?

我试过了:

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

如果我创建了一个新实例,就没有问题:

inst = Class(attr1=[1,2,3])

print inst

print inst.attr1,inst.attr2

输出为:

attr1

attr2

[1, 2, 3]

[]

[1, 2, 3]  []

但如果我用实例inst创建一个新实例:

inst2 = Class(obj=inst)

print inst2

print inst2.attr1,inst2.attr2

输出为:

[1, 2, 3]

[]

AttributeError                            Traceback (most recent call last)

in ()

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中,如何处理矫揉造作?这是一种很好的方式吗?

什么?你到底想实现什么?!

想象一下如果你能做到这一点。语法将是什么样的?您将如何向其他人解释如何使用您的代码?

拒绝投票是匿名的,不需要评论(如meta.stackoverflow.com/q/250177/3001761)。更别提你有什么评论了!如果你不能更明确地说,那就不要期待答案。你到底想做什么?通过__init__实现一种奇怪的复制方法?为什么?

什么是"地址矫揉造作"?

@Peterwood此语法将允许第二个实例继承第一个实例的所有属性,但重新初始化的属性除外。

@G.S编辑问题,澄清你想要达到的目标。为什么不使用from_existing_instance类方法,而不是使__init__复杂化呢?

@我说我不能更明确,因为我写了我的整个过程!通过init实现一个奇怪的复制方法?为什么?我在我的问题中说,也许有更好/正确的方式,所以你能解释一下这和复制方法是什么一样的,以及如何做到这一点吗?

@但是你的"整个过程"既不起作用,也没有多大意义。要么给出一个最小限度的可重复的例子,一个散文清晰的解释,或者(最好)两者都给出。也许你想要stackoverflow.com/q/19305296/3001761之类的东西?

我的例子很好,我不会自己写输出!如果这不合理,解释为什么!即使我实现了from_existing_instance方法,我也会遇到同样的问题(除非我剥离了现有实例的所有属性)。我看到了你提出的链接,它与我所做的不一致,因为它使用继承

@Jonrsharpe谢谢你的格式化,你是对的,这个例子不起作用,因为我把object改成了obj

您不必使用继承,我的观点是,在Python中实现备用构造函数的规范方法是使用@classmethod。这感觉像是在和墙争论,所以我不会进一步评论。

@乔恩沙普,我不知道有多少墙可以回答和考虑别人的论点,我只是想清楚你说什么,我回答什么。谢谢你的帮助,我会去看《江户记》的。

不知道你想达到什么样的目标,但从技术上讲,你的错误是:

self = kwargs.get('object',self)

self没有什么魔力,它只是一个函数参数,因此在函数中重新绑定它只会使本地名称self指向函数范围内的另一个对象。它不会影响当前实例(方法包装器传递给__init__的实例),它只是使self成为object的别名。

如果您想要将属性从object复制到self,则必须明确地执行以下操作:

other = kwargs.get('object')

if other is not None:

self.attrx = other.attrx

self.attry = other.attry

# etc

哦,是的:Python是高级语言,没有什么比"地址矫揉造作"更像的了——您所拥有的只是引用对象的名称(实际上,名称=>对象映射)。名称只是一个名称,而对象实际生活的地方并不是您关心的问题。

所以,如果我理解的很好,self-it只是局部变量,它是当前实例的别名(通过方法包装器传递给init)?那么,如果我重新绑定它,我会"丢失"init范围内的当前实例吗?@布鲁诺人

@布鲁诺·德斯惠利埃

@g.s您想阅读nedbatchelder.com/text/names.html

谢谢@brunodesthuilliers

感谢以上评论,我了解两件事:

self只是一个局部变量,而不是类实例

_init_是一个类内置方法,用于从其他对象初始化实例。

因此,如果我想从现有实例初始化一个新的类实例,我只需要创建一个"initializer"方法来调用_init_:

class 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))

像这样使用:

inst = Class(attr1=[1,2,3])

print inst

print inst.attr1,inst.attr2

输出:

[1, 2, 3] []

inst2 = inst.Class(attr2=[12,11])

print inst2

print inst2.attr1,inst2.attr2

输出:

[1, 2, 3] [12, 11]

"self只是一个局部变量,而不是类实例":self是函数作用域中的一个名称,这个名称最初是指当前实例(调用方法的实例)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值