从其中一种方法替换对象

时间:2020-02-10 08:31:48

标签: python python-3.x oop metaprogramming

我正在使用python并有一个对象,该对象有一个方法。我正在寻找一种简单的方法,从该函数中替换整个对象。

例如

class a():
    def b(self):
        self = other_object

您该怎么做?

谢谢

2 个答案:

答案 0 :(得分:1)

您使用代理/外观对象保存对实际对象的引用,如果需要,可以使用self,其余部分就是该代理(比Facade更好的词,但现在不更改我的代码)。代码库看到。但是,任何属性/方法访问都将转发到可交换的实际对象上。

下面的代码应该给您一个大概的想法。请注意,您需要注意围绕__the_instance进行递归,这就是为什么我直接分配给__dict__的原因。有点混乱,因为已经有一段时间我编写了完全包装getattr和setattr的代码。

class Facade:
    def __init__(self, instance):
        self.set_obj(instance)

    def set_obj(self, instance):
        self.__dict__["__theinstance"] = instance

    def __getattr__(self, attrname):
        if attrname == "__theinstance":
            return self.__dict__["__theinstance"]                

        return getattr(self.__dict__["__theinstance"], attrname)

    def __setattr__(self, attrname, value):
        if attrname == "__theinstance":
            self.set_obj(value)

        return setattr(self.__dict__["__theinstance"], attrname, value)


class Test:
    def __init__(self, name, cntr):
        self.name = name 
        self.cntr = cntr

    def __repr__(self):
        return "%s[%s]" % (self.__class__.__name__, self.__dict__)

obj1 = Test("first object", 1)

obj2 = Test("second", 2)
obj2.message = "greetings"


def pretend_client_code(facade):
    print(id(facade), facade.name, facade.cntr, getattr(facade, "value", None))


facade = Facade(obj1)

pretend_client_code(facade)

facade.set_obj(obj2)

pretend_client_code(facade)

facade.value = 3

pretend_client_code(facade)

facade.set_obj(obj1)

pretend_client_code(facade)

输出:

4467187104 first object 1 None
4467187104 second 2 None
4467187104 second 2 3
4467187104 first object 1 None

因此,基本上,“客户端代码”始终会看到相同的外观对象,但实际上要访问的对象取决于您完成的def b等效项。

Facade在“设计模式”术语中具有特定含义,在这里可能并不真正适用,但是足够接近。也许代理会更好。

请注意,如果要更改相同对象上的类,这是另一回事,可以通过分配self.__class__来完成。例如,假设有一个EnemyClass被杀死后被换成DeadEnemyClass的RPG游戏:self.__class__ = DeadEnemyClass

答案 1 :(得分:0)

您不能直接这样做。您可以做的就是将其另存为实例变量。

class A():
    def __init__(self, instance=None):
        self.instance = val or self

    # yes, you can make it a property as well.
    def set_val(self, obj):
        self.instance = obj

    def get_val(self):
        return self.instance

替换'self'变量不太可能完成 无论您要做什么,都无法通过以下方式完成 将func(self)的结果存储在另一个变量中。 “自我”是 有效地仅在 方法调用,用于传入正在被传递的类的实例 操作。替换自我实际上不会替换对 其他对象持有的类的原始实例,也不会 创建对分配给的新实例的持久引用 它。

原始来源:Is it safe to replace a self object by another object of the same type in a method?