在Python的嵌套类中,访问外部类父类的最佳方法是什么?

时间:2022-01-28 22:56:16

I have a non trivial Django system and there's a lot of Meta class inheritance going on. Boiled down to it's essence that looks like this:

我有一个非常简单的Django系统,并且有很多Meta类继承。归结为它的本质看起来像这样:

class Base:
    class Meta:
        pass

class Child(Base):
    class Meta(Base.Meta):  # this
        pass

class GrandChild(Child):
    class Meta(Child.Meta):  # this
        pass

The problem with this is it's easy to overlook the lines marked "this" when making changes to the inheritance structure.

这样做的问题是,在对继承结构进行更改时,很容易忽略标记为“this”的行。

This is fundamentally the same problem as with Python2's super requiring the name of the parent class.

这基本上与Python2的超级要求父类名称的问题相同。

And like with that what I'd like is a way of writing those lines in a way that doesn't explicitly reference the outer classes base. Something like:

和我一样,我想要的是一种以不明确引用外部类库的方式编写这些行的方法。就像是:

class Base:
    class Meta:
        pass

class Child(Base):
    class Meta(super.Meta):  # this
        pass

class GrandChild(Child):
    class Meta(super.Meta):  # this
        pass

Is there anyway of doing this?

无论如何这样做?

1 个解决方案

#1


0  

I think you can tackle the problem with a class factory function

我认为你可以用类工厂函数来解决这个问题

def MetaClassFactory(name, SuperClass):
    newclass = type(name, (SuperClass.Meta,), {})
    return newclass


class Base(object):
    class Meta(object):
        someattr = 0

class Child(Base):
    Meta = MetaClassFactory("Meta", Base)

class GrandChild(Child):
    Meta = MetaClassFactory("Meta", Child)

# The class with its attribute is everywhere present (no AttributeError raised)
print "Base: {}, Child: {}, Grandchild: {}".format(Base.Meta.someattr, Child.Meta.someattr, GrandChild.Meta.someattr)

# Override it for Child (Grandchild inherits it)
Child.Meta.someattr = 1
print "Base: {}, Child: {}, Grandchild: {}".format(Base.Meta.someattr, Child.Meta.someattr, GrandChild.Meta.someattr)

The two print statements yield:

这两个印刷语句产生:

Base: 0, Child: 0, Grandchild: 0
Base: 0, Child: 1, Grandchild: 1

#1


0  

I think you can tackle the problem with a class factory function

我认为你可以用类工厂函数来解决这个问题

def MetaClassFactory(name, SuperClass):
    newclass = type(name, (SuperClass.Meta,), {})
    return newclass


class Base(object):
    class Meta(object):
        someattr = 0

class Child(Base):
    Meta = MetaClassFactory("Meta", Base)

class GrandChild(Child):
    Meta = MetaClassFactory("Meta", Child)

# The class with its attribute is everywhere present (no AttributeError raised)
print "Base: {}, Child: {}, Grandchild: {}".format(Base.Meta.someattr, Child.Meta.someattr, GrandChild.Meta.someattr)

# Override it for Child (Grandchild inherits it)
Child.Meta.someattr = 1
print "Base: {}, Child: {}, Grandchild: {}".format(Base.Meta.someattr, Child.Meta.someattr, GrandChild.Meta.someattr)

The two print statements yield:

这两个印刷语句产生:

Base: 0, Child: 0, Grandchild: 0
Base: 0, Child: 1, Grandchild: 1