摇摆更多的类参数而不是参数?怎么回事?

2024-04-27 09:14:46 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,Stackoverflow社区

我一直在试图理解Django(和Wagtail的流场)是如何在引擎盖下工作的。这样做,我学会了元类,并相信有一个处理的原则。但是有一段代码让我困惑(见下文)。你知道吗

当我们遵循StreamField定义时,这段代码似乎将元组列表传递给一个类构造函数,而这个类构造函数似乎不适合这种类型的列表。这怎么行?你知道吗

如有任何建议,我们将不胜感激。代码如下:

型号.py

这就是我们定义流场的地方。它采用格式为('title',blockType)的元组列表。我们的目标是遵循StreamField呼吁:

class BlogPage(Page):
    blogElement = StreamField([
        ('heading', blocks.CharBlock(classname="full title")),
        ('paragraph', blocks.TextBlock()),
        ('picture', ImageChooserBlock()),
    ], default=[])

字段。py>;流域

当我们跟随对StreamField的调用时,我们到达下面的类构造函数。在这里调用StreamBlock(block类型)会让人困惑:

class StreamField(models.Field):
    def __init__(self, block_types, **kwargs):
        if isinstance(block_types, Block):
            self.stream_block = block_types
        elif isinstance(block_types, type):
            self.stream_block = block_types()
        else:
            self.stream_block = StreamBlock(block_types)
        super(StreamField, self).__init__(**kwargs)

流块

而对类构造函数的调用将块类型作为参数(包含中定义的三个元组的列表)型号.py)接收类构造函数调用六.带元类作为参数(代码包括在下面):

class StreamBlock(six.with_metaclass(DeclarativeSubBlocksMetaclass, BaseStreamBlock)):
    pass

我的问题

这怎么可能?六.带元类它本身是对一个方法的调用,该方法使用两个参数<;gt;和<;gt;,这两个参数本身都是类构造函数(下面包含代码)。你知道吗

StreamBlock不应该容纳接收符合块类型的参数,而这些类型又包含中定义的三个元组的列表吗型号.py?我肯定我在这里遗漏了什么,但就是看不见。如有任何建议,我们将不胜感激。你知道吗

Z轴

上下文 我在下面的上下文中包含了其他代码片段的代码。我知道六.带元类在这个岗位上工作:[哇哦六.带元类()工作? ][1] 但我正在努力解决上述问题。你知道吗

六.带元类

def with_metaclass(meta, *bases):
    """Create a base class with a metaclass."""
    # This requires a bit of explanation: the basic idea is to make a dummy
    # metaclass for one level of class instantiation that replaces itself with
    # the actual metaclass.
    class metaclass(meta):

        def __new__(cls, name, this_bases, d):
            print("In with_metaclass: %s " %d )
            return meta(name, bases, d)
    return type.__new__(metaclass, 'temporary_class', (), {})

声明性SubBlocksMetaClass

class DeclarativeSubBlocksMetaclass(BaseBlock):
"""
Metaclass that collects sub-blocks declared on the base classes.
(cheerfully stolen from      https://github.com/django/django/blob/master/django/forms/forms.py)
"""
def __new__(mcs, name, bases, attrs):
    # Collect sub-blocks declared on the current class.
    # These are available on the class as `declared_blocks`
    current_blocks = []
    for key, value in list(attrs.items()):
        if isinstance(value, Block):
            current_blocks.append((key, value))
            value.set_name(key)
            attrs.pop(key)
    current_blocks.sort(key=lambda x: x[1].creation_counter)
    attrs['declared_blocks'] = collections.OrderedDict(current_blocks)

    new_class = (super(DeclarativeSubBlocksMetaclass, mcs).__new__(mcs, name, bases, attrs))

    # Walk through the MRO, collecting all inherited sub-blocks, to make
    # the combined `base_blocks`.
    base_blocks = collections.OrderedDict()
    for base in reversed(new_class.__mro__):
        # Collect sub-blocks from base class.
        if hasattr(base, 'declared_blocks'):
            base_blocks.update(base.declared_blocks)

        # Field shadowing.
        for attr, value in base.__dict__.items():
            if value is None and attr in base_blocks:
                base_blocks.pop(attr)
    new_class.base_blocks = base_blocks

    return new_class

基本流块

class BaseStreamBlock(Block):

def __init__(self, local_blocks=None, **kwargs):
    self._constructor_kwargs = kwargs

    super(BaseStreamBlock, self).__init__(**kwargs)

    # create a local (shallow) copy of base_blocks so that it can be supplemented by local_blocks
    self.child_blocks = self.base_blocks.copy()
    if local_blocks:
        for name, block in local_blocks:
            block.set_name(name)
            self.child_blocks[name] = block

    self.dependencies = self.child_blocks.values()

Tags: the代码nameselfnewbasevalueblock