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