Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django、Python和类变量_Python_Django - Fatal编程技术网

Django、Python和类变量

Django、Python和类变量,python,django,Python,Django,我一边学习Python,一边学习Django。我熟悉许多其他语言 在下面的代码段中,x是classFoo的类变量 class Foo(object): x = 9000 考虑到之前的声明,以下工作可以正常进行 printfoo.x Django框架允许您通过定义Python类来创建模型。它使用Python类中的不同类变量生成字段 class Question(models.Model): question_text = models.CharField(max_length=2

我一边学习Python,一边学习Django。我熟悉许多其他语言

在下面的代码段中,
x
是class
Foo
的类变量

class Foo(object):
    x = 9000
考虑到之前的声明,以下工作可以正常进行

printfoo.x

Django框架允许您通过定义Python类来创建模型。它使用Python类中的不同类变量生成字段

class Question(models.Model):
    question_text = models.CharField(max_length=200)
为什么会出现以下代码段:

#!/usr/bin/env
import os, django
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
django.setup()
from polls.models import Question, Choice
print Question.question_text
抛出以下错误:

AttributeError: type object 'Question' has no attribute 'question_text'

据我所知,我的
Question
类定义了一个静态成员:
Question.Question\u text
Question是类型的对象。您需要一个问题的实例:

>>> q= Question(text = "Does a dog have the buddha nature?")
那你应该去

q、 正文 “狗有佛性吗?”

请注意,除非保存()该对象,否则该对象不会持久存在:

魔法

不,真的

Python类不是以石头结构来设置的,就像它们是C++一样。它们本身就是对象——另一种类型的实例:

class Foo(object):
    pass

print(type(Foo))  # <class 'type'>
这实际上(或多或少)是语法上的糖分:

Bar = type('Bar', (object,), {'a': 1, 'b': 2})
type
获取新类的名称、其超类的列表以及该类的所有属性,并输出一个新类

但是,因为
type
和其他类一样只是一个类,所以可以对它进行子类化并赋予它不同的行为。Django就是这么做的:它创建了一个
type
的子类,它对传递给它的属性的dict做了一些不同的事情

您不会在自己的代码中直接看到这种情况,但是如果您检查
type(models.Model)
,您会发现它的类型不是
type
,而是Django特有的类型。它的名字中可能有“meta”,因为它被称为元类:类的类

这是在Python中创建“声明性”库的一种相当常见的模式,类的属性实际上定义了某种结构。在表单验证(wtforms)、模式验证(colander)、其他ORM(sqlalchemy)甚至stdlib enum模块中也可以看到同样的情况。

Django模型使用一个函数来改变正常的类行为

使用
dir(Question)
您将看到该类上现在有不同的属性。然而,这只是Django模型的自定义行为


如果您很好奇,您可以学习,但它会做很多特定于对象关系映射任务的工作

你希望它打印什么?由于question_文本字段是一个数据库属性映射类成员,因此它不打算保存值,这就是数据库的作用所在。因此,如果您希望打印字符串值,它将不起作用。如果这段代码能够发挥最大的作用,您可以得到类models.CharField的字符串描述,那么Django模型可能会使用元类来改变正常的类行为。使用
dir(Question)
您将看到该类上现在有不同的属性。不过,这只是Django型号的自定义行为。@Freestyle076
正是我希望在屏幕上显示的内容。@MartijnPieters您介意将您的回答作为我问题的答案吗?我想勾选它作为我的问题的选定答案。这是我第一次使用Python这样的“动态”语言。我没有意识到“看起来像鸭子”的哲学可以达到动态重新定义类的程度。谢谢你的提示。这并不能解释为什么Django模型是不同的。注意:我认为这是“最有帮助的”答案,但Martijn Pieters在我的原始问题下的回答实际上是对我的问题的更简洁、切中要害的回答。
class Bar(object):
    a = 1
    b = 2
Bar = type('Bar', (object,), {'a': 1, 'b': 2})