开发者

Python, overiding itself

开发者 https://www.devze.com 2023-04-12 02:27 出处:网络
I\'ve a following problem. I have a model class in MVC and it has a special purpose. In certain cases it should be able to override itself. Is this kind of behavior possible?

I've a following problem. I have a model class in MVC and it has a special purpose. In certain cases it should be able to override itself. Is this kind of behavior possible?

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

    def save(self):
        if 1==Tex开发者_运维知识库t.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()


There's no trivial way for an object to become another object in python. Assigning to self won't do this; self is a local variable in the method definition, And assigning to it won't change the existing instance in any way; only make it inaccessible for the rest of the method.

There are a few ways to approach this problem. The preferred way is to have a method that returns the correct instance.

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

There is also a hackish way to get a similar effect to your original example. Ordinary python classes store most of their attributes in a special __dict__ attribute. You can copy that and it will be as though one instance is replaced by the other. Of course, that only works for perfectly plain python classes, and may or may not work classes defined in an ORM, or which retain state in more clever ways.

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)


Yes it is possible :-)

Seriously, using a conditional call to super as in your example will achieve the result.

However, the style of your example is a little confusing, and changing it may allow you to achieve your overall objectives more easily. (But neither of these directly affects your question.)

  1. I would not recommend putting a method in your class called object unless I had no other choice.
  2. The fact that you are passing self.a to Text.object, within method Text.save, doesn't seem right. It would be cleaner to simply call self.object() and have method object use self.a directly in its code.
0

精彩评论

暂无评论...
验证码 换一张
取 消