问题描述
我有一个Parent类和一个继承的子类,我想知道如何在我的Parent类中访问子类变量。
I have a Parent class and a inherited child class, I would like to know how to access the child class variable in my Parent class..
我尝试了这个并失败-
class Parent(object):
def __init__(self):
print x
class Child(Parent):
x = 1;
x = Child();
错误:-
NameError: global name 'x' is not defined
此问题与到Django表单,我们继承了表单类
并声明了一些类变量。
This question is in relation to Django forms where we inherit the form classand declare some class variables.
例如:-
我的表单看起来像这样
from django import forms
class EmployeeForm(forms.Form):
fname = forms.CharField(max_length=100)
lname = forms.CharField(max_length=100)
我认为表单字段被视为类变量,并以某种方式传递给父类。
I believe the form fields are considered as class variable and somehow passed to the parent class..
推荐答案
Django使用元类来做到这一点。 ()
Django does this with metaclasses. (Relevant Django source)
以下是相关代码的精炼示例:
Here's a distilled example of the relevant code:
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)
关于Python元类,这里有很多问题(示例),所以我不会尝试重新解释这个概念。
There are many questions on here about Python metaclasses (example), so I won't try to re-explain the concept.
在这种情况下,当您创建类 MyForm
,检查每个类属性是否为 Field
的实例。如果是,则将它们添加到列表中( field_list
)。
In this case, when you create the class MyForm
, each of the class attributes are checked for being instances of Field
. If they are, they're added to a list (field_list
).
将创建该类,然后创建一个属性 .fields
已添加到类中,该类为 field_list
,即 Field
元素。
The class is created, then an attribute .fields
is added to the class, which is field_list
, the list of Field
elements.
然后您可以通过< FormSubclass> .fields
访问表单字段或在本例中为 MyForm.fields
。
You can then access the form fields through <FormSubclass>.fields
or in the case of this example, MyForm.fields
.
编辑:
值得注意的是,无需元类语法糖,您就可以完成非常相似的功能:
It's worth noting that you can accomplish very similar functionality, without the metaclass syntactic sugar with something like:
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')]
这篇关于在父类中访问子类变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!