簡體   English   中英

在 class 屬性定義中使用相同的 class

[英]Using the same class in the class attribute definition

我怎么能做這樣的事情?

class Form(object, metaclass=...):
    pass


class Field(object):
    def __init__(self, nested_form_class=None):
        self.nested_form_class = nested_form_class


class TaskForm(Form):
    children = Field(nested_form_class=TaskForm)

渲染:

NameError: name 'TaskForm' is not defined

錯誤發生在定義children屬性的行上。

I use class attributes in the __new__ function of the metaclass and I can not move it to __init__ function of current class.

我的元類(如 django 框架中):

class FormMeta(type):
    """
    Meta class for extract fields from model
    """

    def __new__(mcs, name, bases, attrs):
        found_fields = dict()

        for k, v in attrs.items():
            if isinstance(v, Field):
                found_fields[k] = v

        attrs['found_fields'] = found_fields

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

        parent_fields = {}

        for base in reversed(new_class.__mro__):
            # Collect fields from base class.
            if hasattr(base, 'found_fields'):
                parent_fields.update(base.found_fields)

            # Disable reordered fields.
            for attr, value in base.__dict__.items():
                if value is None and attr in parent_fields:
                    parent_fields.pop(attr)

        new_class.base_fields = parent_fields
        new_class.found_fields = parent_fields

        return new_class

class語句正文中,正在聲明的 class 尚不存在 - 因此不能像您的示例中那樣引用它。 Django and the original use of type annotations in Python PEP 484 work around this by allowing you to put the class name as a string instead - but this does not help when you want a plain reference to the class.

Python 中的內容是“描述符協議” - 如果在旨在用作字段的事物類中實現的少數方法 - 就像在您的情況下一樣,由 Python 自動調用。 __get____set____delete__方法在屬性訪問時被調用,而__set_name__在創建 class 並傳遞所有者 class 時被調用。 您可以將其用於您的Field class。 您的元類不需要更改。 (請記住,在執行type.__new__ __set_name__時調用 __set_name__ ,在元類__init__運行之前。):

class Form(object, metaclass=...):
    pass


class Field(object):
    def __init__(self, nested_form_class=None):
        self.nested_form_class = nested_form_class

    def __set_name__(self, owner, name):
         if self.nested_form_class is None:
            self.nested_form_class = owner
         self.name = name


class TaskForm(Form):
    children = Field()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM