内部类 - 继承和覆盖其属性

时间:2018-01-03 14:02:25

标签: python django python-3.x django-models

我试图了解Django如何在其数据库模型(选项)中使用python的元类,并提出了下面应该大致模仿Django的精简版代码片段。逻辑。

<div class="tabs">
  <ul>
      <li><a href="#apps">apps</a></li>
      <li><a href="#features">features</a></li>
      <li><a href="#faqs">faqs</a></li>
  </ul>

  <div id="apps">
  </div>

  <div id="features">
  </div>

  <div id="faqs">
  </div>

</div>

<script type="text/javascript">jQuery(function() { jQuery(".tabs").tabs() });</script>

使用上面的代码,我希望得到以下输出:

class DatabaseOptions(object):

    def __init__(self, opts):
        if opts:
            for key, val in opts.__dict__.items():
                if not key.startswith('__') and not callable(val):
                    setattr(self, key, val)


class MetaModel(type):

    def __new__(cls, name, bases, classdict):
        result = super().__new__(cls, name, bases, dict(classdict))

        opts = classdict.pop('DbMeta', None)
        if opts:
            setattr(result, '_db_meta', DatabaseOptions(opts))

        return result


class Model(object, metaclass=MetaModel):

    class DbMeta:
        database = 'default'
        migrate = True


class User(Model):

    class DbMeta(Model.DbMeta):
        database = 'user'


class GroupUser(User):

    class DbMeta(User.DbMeta):
        database = 'group_user'

相反,我得到以下异常

print(Model._db_meta.database)  # default
print(Model._db_meta.migrate)  # True

print(User._db_meta.database)  # user
print(User._db_meta.migrate)   # True

print(GroupUser._db_meta.database)  # group_user
print(GroupUser._db_meta.migrate)  # True

我的问题是为什么>>> python3 test.py default True user Traceback (most recent call last): File "test.py", line 48, in <module> print(User._db_meta.migrate) # True AttributeError: 'DatabaseOptions' object has no attribute 'migrate' 不会继承User.DbMeta的{​​{1}}属性?这种问题有解决办法吗?

修改

根据丹尼尔的回答,我提出了以下对我有用的信息:

migrate

1 个答案:

答案 0 :(得分:1)

这不是一个关于内部类的问题。

类属性就是类本身的属性。因此,__dict__的{​​{1}}包含&#34;数据库&#34;并且&#34;迁移&#34;,Model.DbMeta只包含 &#34;数据库&#34;因为那是该类定义的唯一属性。

但是,User.DbMeta显示 属性。你可能应该迭代在DatabaseOptions而不是dir()上调用它的结果。