[英]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.