Python,压倒自己

时间:2011-10-11 18:12:06

标签: python oop class

我遇到了以下问题。我在MVC中有一个模型类,它有一个特殊的用途。在某些情况下,它应该能够覆盖自己。这种行为可能吗?

Class Text(Document):
    a =  StringField()
    b =  StringField()

    def save(self):
        if 1==Text.object(a=self.a).count():       # if similar object exists in db,
             self = Text.object(a=self.a).first()  # get the instance from db and
                                                   # override the origian class.
        else:                                      #use super class' save-function
             return super(Text, self).save()

2 个答案:

答案 0 :(得分:1)

对象成为在python中的另一个对象没有什么琐碎的方法。分配给self不会这样做; self是方法定义中的局部变量,并且分配给它不会以任何方式更改现有实例;只允许其余的方法无法访问。

有几种方法可以解决这个问题。首选方法是使用返回正确实例的方法。

class Foo(...):
    def get_or_save(self):
        existing = load_from_database(self.bar)
        if existing is not None:
            return existing
        else:
            save_to_database(self)
            return self

new_inst = Text()
new_inst.bar = "baz"

inst = new_inst.get_or_save()
# stop using new_inst

还有一种使用原始示例获得类似效果的hackish方法。普通的python类将大多数属性存储在特殊的__dict__属性中。您可以复制它,就好像一个实例被另一个实例替换。当然,这只适用于完全普通的python类,可能会也可能不会在ORM中定义的类中运行,或者以更聪明的方式保留状态。

class Foo(...):
    def save(self):
        existing = load_from_database(self.bar)
        if existing is not None:
            self.__dict__ = existing.__dict__
        else:
            save_to_database(self)

答案 1 :(得分:0)

是的,有可能: - )

说真的,在你的例子中使用super的条件调用将获得结果。

但是,您的示例的样式有点令人困惑,更改它可能会让您更轻松地实现您的整体目标。 (但这些都不会直接影响你的问题。)

  1. 除非我别无选择,否则我不建议在您的班级中使用名为object的方法。
  2. 您在方法self.a内将Text.object传递给Text.save的事实似乎并不正确。简单地调用self.object()并让方法object直接在其代码中使用self.a会更简洁。