【问题标题】:In a nested class in Python what's the best way to access the outer classes parent class?在 Python 的嵌套类中,访问外部类父类的最佳方法是什么?
【发布时间】:2018-01-26 16:46:20
【问题描述】:

我有一个不平凡的 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

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

这与 Python2 的 super 需要父类的名称基本上是相同的问题。

就像这样,我想要一种以不明确引用外部类基础的方式编写这些行的方式。比如:

class Base:
    class Meta:
        pass

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

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

有没有办法做到这一点?

【问题讨论】:

  • 不是一个有用的答案 - 但这看起来有点像你正在进行的疯狂模式。无论如何 - 烦人的是,从内部类到外部类没有简单的方法。
  • 其次 - python 中的元类是一个特定的东西,这不是它。 Django 和 SqlAlchemy 使用一个名为 Meta 的内部类来存储一些内部元数据,这没关系 - 不过,你真的不想在内部类中有任何逻辑,因为范围变得很棘手,正如你已经发现的那样。

标签: python django inheritance nested inner-classes


【解决方案1】:

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

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)

两个打印语句产生:

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

【讨论】:

    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2018-12-17
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多