如何更改方法调用中的基础对象?

2024-09-27 19:34:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我以为Python中的所有函数和方法参数都是通过引用传递的,这使我相信以下代码可以工作:

class Insect:
    def status(self):
        print "i am a %s" % self

class Caterpillar(Insect):
        def grow_up(self):
                self = Butterfly() # replace myself with a new object
                return

class Butterfly(Insect):
        pass

my_obj = Caterpillar()
my_obj.status() # i am a <__main__.Caterpillar instance at 0x100494710>

# ok, time to grow up:
my_obj.grow_up()

my_obj.status() # want new Butterfly object, but it is still Caterpillar! :(

如何在方法调用中更改对象本身?在

--编辑:

到目前为止,得到的答复是:

1)更改自身。更改与当前对象关联的类。
2) “别这样。”

最初的问题是:如何在旧类上定义的方法调用中生成一个新的对象来代替旧的对象?在

我想答案可能是“你不能”

——编辑2:

为什么每个人都害怕说“不可能”?在


Tags: 对象方法caterpillarselfobjnewmydef
3条回答

self.__class__ = Butterfly可能有用,因为它重新绑定了一个限定的名称(这是一个完全不同于重新绑定名称的事情)。在

重新绑定一个裸名永远不会对之前绑定到它的任何对象产生任何影响(除非该裸名是对“前一个对象”的唯一引用,在这种情况下,后者可能会被破坏——但这里显然不是这样,{{cdm>不能与

编辑

您提到需要初始化新重新分类的对象—这很简单:

self.__dict__.clear()
self.__class__ = Butterfly
self.__init__(whatever, you, want)

但是在你提到需要“备份属性”的评论中——我不知道你到底是什么意思,也不知道为什么这与你直接分配给self的“梦幻案例”有什么不同(这当然也会把属性吹走)。也许这个想法是__init__的(一些)参数必须是self的属性?然后,例如,您可以编写如下代码:

^{pr2}$

亚历克斯说得很清楚,没有办法严格做到这一点。 我想不出有什么办法能让你这么做。也许你需要一个工厂功能的插件?或者同一物体的不同状态?在

然而,Python就是这样,您可以有一个“shell”对象,它的唯一目的是授予对underlyign对象的访问权。然后可以修改底层对象:当shell对象保持不变时,底层对象是另一个对象。在

一个可能的实现如下(我已经尝试了一次__getattribute__的不干净的实现-它可以做得更好)

# -*- coding: utf-8 -*-
class Insect(object):
        pass

class Catterpillar(Insect):
    a = "I am a caterpillar"
class Butterfly(Insect):
    a = "I am a butterfly"

class Cocoon(object):
    def __init__(self, *args, **kw):
        self._true = Catterpillar(*args, **kw)

    def __getattribute__(self, attr):
        try:
            if attr != "_true":
                return getattr(object.__getattribute__(self, "_true"),attr)
        except AttributeError:
            pass
        return object.__getattribute__(self, attr)
    def __setattr__(self, attr, val):
        if attr != "_true":
            setattr(self._true, attr, val)
        else:
            object.__setattr__(self, attr, val)

    def change(self, *args, **kw):
        self._true = Butterfly(*args, **kw)

有了这个,你可以得到如下信息:

^{pr2}$

一。 在change函数上,您可以备份您想要的任何属性,并且可以在__getattribute__方法中免除其他属性的更改。在

当你说self = Butterfly()时,你所做的只是改变self所指向的;你改变的不是自我,而是:

x = 1
x = 2

。。。将数字1改为2。在

一般来说,当人们需要这样做,而不是改变对象的类型(许多语言都禁止这样做),人们使用合成策略:

^{pr2}$

相关问题 更多 >

    热门问题