在 Python 3 / Django 中正确使用元类

电子冲浪蛇

我一直在查看参考资料和示例,但仍然不能完全正确。

Django 提供了许多使用元类作为工厂系统的一部分的示例,该工厂系统创建各种方法等,特定于传入的值。这个想法很清楚。但它的真正运作方式有点神秘。

一段典型的 Django(直接来自 Django“入门”教程)代码如下所示:

from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

现在,稍后,将有这些类的实际实例,例如:

q1 = Question(question_text='my question', pub_date='01-01-2017')

然而,对于全世界而言,在类定义中, question_text 和 pub_data 看起来像是类范围的对象(即,由该类的所有实例共享,例如 q1、q2 等)。

执行此操作并保持隔离的更传统方法是在每个前面都有一个“自我”,因此类 def 看起来像:

class Question(models.Model):
    self.question_text = models.CharField(max_length=200)
    self.pub_date = models.DateTimeField('date published')

我什至尝试查看 Django 的源代码。实际上,models.Model 是一个类,它上面有一个元类,只要声明了一个基于models.Model 的新类,就会调用它。但是代码相当神秘。

这里有什么惯用语吗?我认为类中声明的变量不打算跨实例共享。也许,我想,在那里声明变量(以及它们的类型,如果你愿意的话)只是一种将它们推入内部属性字典的方法,并且元类做了一些魔法来使事情发生,从而导致那种结果这似乎更合乎逻辑。

但是,不知何故,随着代码的进行,人们创建了另一个实例,例如:

q2 = Question(question_text='my next question', pub_date='01-02-2017')

如果您引用 q1.question_text 或 q2.pub_date,演示代码就可以正常工作,这样它们就好像类声明中声明的变量确实具有“自我”一样。前置。

如果好奇,这里是 Django 源代码(模型位于第 383 行及其上方的元类):https : //github.com/django/django/blob/master/django/db/models/base.py

瓦伦普尔

领域,意在数据库架构列的表示,是类级,但值是实例级别。

假设你有一个 IntegerField:

class WithInt(models.Model):
    fld = models.IntegerField()

这表示:

type(WithInt.fld) # IntegerField
inst = WithInt.objects.get(1)
type(inst.fld) # int

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章