Python model inheritance and order of model declaration

前端 未结 2 786
感情败类
感情败类 2021-01-03 09:21

The following code:

class ParentModel(models.Model):
    pass

class ChildA(ChildB):
    pass

class ChildB(ParentModel):
    pass

Obviousl

2条回答
  •  佛祖请我去吃肉
    2021-01-03 10:09

    Perfectionists look away!! This is a workaround (hack); the solution would be to solve the incorrect declaration order.

    WARNING: This is extremely daft.

    Concept:

    Imagine a namespace where anything can exist. Literally anything that is asked of it. Not the smartest thing usually but out-of-order declaration isn't smart either, so why not?

    The key problem of out-of-sequence classes is that dependent classes were being defined before their dependencies, the base classes. At that point of evaluation, the base classes are undefined resulting in a NameError.

    Wrapping each class in try except statements would take as much effort as rewriting the module anyway, so that can be dismissed out of hand.

    A more efficient (in terms of programmer time) means of suppressing NameError must be used. This can be achieved by making the namespace totally permissible, as in, if a lookup object doesn't exist, it should be created thereby avoiding a NameError. This is the obvious danger of this approach as a lookup becomes a creation.

    Implementation:

    Namespaces in Python are dictionaries, I believe, and dictionaries methods can be overloaded, including the lookup function: __getitem__. So mr_agreeable is a dictionary subclass with an overloaded __getitem__ method which automatically creates a blank class when a lookup key doesn't exist. An instance of mr_agreeable is passed to execfile as the namespace for the classes.py script. The objects (aside from the builtins) created execfile call are merged with the globals() dict of the calling script: hack.py.

    This works because Python doesn't care if class' base classes are changed after the fact.

    This may be implementation dependent, I don't know. Tested on: Python 2.7.3 64bit on Win7 64bit.

    Assuming your out-of-order classes are defined in classes.py:

    class ParentModel(object):
        name = "parentmodel"
    
    class ChildC(ChildA):
        name = "childc"
    
    class ChildA(ChildB):
        name = "childa"
    
    class ChildB(ParentModel):
        name = "childb"
    

    The loader script, lets call it hack.py:

    from random import randint
    from codecs import encode
    
    class mr_agreeable(dict):
        sin_counter = 0
        nutty_factor = 0
        rdict = {0 : (0, 9), 200 : (10, 14), 500 : (15, 16), 550 : (17, 22)}
        def __getitem__(self, key):
            class tmp(object):
                pass
            tmp.__name__ = key
            if(not key in self.keys()):
                self.prognosis()
                print self.insanity()
            return self.setdefault(key, tmp)
        def prognosis(self):
            self.sin_counter += 1
            self.nutty_factor = max(filter(lambda x: x < self.sin_counter, self.rdict.keys()))
        def insanity(self):
            insane_strs = \
            [
                "Nofbyhgryl", "Fher, jul abg?", "Sbe fher", "Fbhaqf terng", "Qrsvangryl", "Pbhyqa'g nterr zber",
                "Jung pbhyq tb jebat?", "Bxl Qbnxl", "Lrc", "V srry gur fnzr jnl", "Zneel zl qnhtugre",
                "Znlor lbh fubhyq svk gung", "1 AnzrReebe vf bar gbb znal naq n 1000'f abg rabhtu", "V'ir qbar qvegvre guvatf",
                "Gur ebbz vf fgnegvat gb fcva", "Cebonoyl abg", "Npghnyyl, ab ..... nyevtug gura", "ZNXR VG FGBC",
                "BU TBQ AB", "CYRNFR AB", "LBH'ER OERNXVAT CLGUBA", "GUVF VF ABG PBAFRAGHNY", "V'Z GRYYVAT THVQB!!"
            ]
            return encode("ze_nterrnoyr: " + insane_strs[randint(*self.rdict[self.nutty_factor])], "rot13")
    
    def the_act():
        ns = mr_agreeable()
        execfile("classes.py", ns)
        hostages = list(set(ns.keys()) - set(["__builtins__", "object"]))
        globals().update([(key, ns[key]) for key in hostages])
    
    the_act()
    

    mr_agreeable acts as the permissible namespace to the complied classes.py. He reminds you this is bad form.

提交回复
热议问题