在父类中访问子类变量 [英] Access Child class variables in Parent class

查看:56
本文介绍了在父类中访问子类变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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 class and 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来源

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')]

这篇关于在父类中访问子类变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆