我有一个父类和一个继承的子类,我想知道如何访问父类中的子类变量..
我试过这个,但失败了 -
class Parent(object):
def __init__(self):
print x
class Child(Parent):
x = 1;
x = Child();
Run Code Online (Sandbox Code Playgroud)
错误:-
NameError: global name 'x' is not defined
Run Code Online (Sandbox Code Playgroud)
这个问题与我们继承表单类并声明一些类变量的 Django 表单有关。
例如:-
我的表格看起来像这样
from django import forms
class EmployeeForm(forms.Form):
fname = forms.CharField(max_length=100)
lname = forms.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)
我相信表单字段被视为类变量并以某种方式传递给父类..
Django 通过元类来做到这一点。(相关Django源码)
这是相关代码的精炼示例:
class Field(object):
def __init__(self, *args):
self.args = args
def __repr__(self):
return "Form(%s)" % (', '.join(map(repr, self.args)),)
class Meta(type):
def __new__(mcs, name, bases, attrs):
field_list = []
for k,v in attrs.items():
if isinstance(v, Field):
field_list.append(v)
cls = type.__new__(mcs, name, bases, attrs)
cls.fields = field_list
return cls
class Form(object):
__metaclass__ = Meta
class MyForm(Form):
fe1 = Field("Field1", "Vars1")
fe2 = Field("Field2", "Vars2")
x = "This won't appear"
form_fields = MyForm.fields
print(form_fields)
Run Code Online (Sandbox Code Playgroud)
这里有很多关于 Python 元类的问题(示例),所以我不会尝试重新解释这个概念。
在这种情况下,当您创建类 时MyForm,将检查每个类属性是否是 的实例Field。如果是,它们将被添加到列表中 ( field_list)。
创建类,然后将属性.fields添加到类中,即元素field_list列表Field。
<FormSubclass>.fields然后,您可以通过或 在此示例中访问表单字段MyForm.fields。
编辑:
值得注意的是,您可以完成非常相似的功能,而无需元类语法糖,例如:
class Field(object):
def __init__(self, *args):
self.args = args
def __repr__(self):
return "Form(%s)" % (', '.join(map(repr, self.args)),)
class Form(object):
def __init__(self):
self._fields = None
def fields(self):
if self._fields is None:
field_list = []
for k in dir(self):
v = getattr(self, k)
if isinstance(v, Field):
field_list.append(v)
self._fields = field_list
return self._fields
class MyForm(Form):
def __init__(self):
Form.__init__(self)
self.fe1 = Field("Field1", "Vars1")
self.fe2 = Field("Field2", "Vars2")
self.x = "This won't appear"
form_fields = MyForm().fields()
print(form_fields) # [Form('Field1', 'Vars1'), Form('Field2', 'Vars2')]
Run Code Online (Sandbox Code Playgroud)