Django框架模板从基础入门到进阶

Django框架模板基础

模板使用
模板基本由两个部分组成,一是HTML代码,二是逻辑控制代码。
逻辑控制的实现又基本由三个部分组成:
1. 变量的使用
{{ person_name }} #使用双大括号来引用变量
2. tag的使用
{% if ordered_warranty %} #使用大括号和百分号的组成来表示使用Django提供的
template tag
{% for item in item_list %}

  • {{ item }}
  • {% endfor %}
  • 3. filter的使用
  • {{ ship_date|date:"F j, Y" }},ship_date变量传给data过滤器,data过滤器通过使用
  • "F j, Y"这几个参数来格式化日期数据。"|"代表类似Unix命令中的管道操作。
  • Template system不仅仅可以和view进行合作,也可以自己独立使用。
  • 最基本的使用方法是:
  • 1. 使用模板代码字符串作为参数,创建一个Template类
  • 2. 创建模板代码中所需要的上下文Context对象,包含所需要的各个引用参数的值
  • 3. 调用Template.render()方法,把template渲染成一个完整的字符串。
  • >>> from django import template
  • >>> t = template.Template('My name is {{ name }}.')
  • >>> c = template.Context({'name': 'Adrian'})
  • >>> print t.render(c)
  • >>> My name is Adrian.
  • 还可以在template代码中使用dict索引,然后在context传入所需要的dict
  • >>> from django.template import Template, Context
  • >>> person = {'name': 'Sally', 'age': '43'}
  • >>> t = Template('{{ person.name }} is {{ person.age }} years old.')
  • >>> c = Context({'person': person})
  • >>> t.render(c)
  • u'Sally is 43 years old.'
  • 还可以使用函数,不过只能使用无参数的函数
  • >>> from django.template import Template, Context
  • >>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
  • >>> t.render(Context({'var': 'hello'}))
  • u'hello -- HELLO -- False'
  • 还可以使用列表索引,但是item.-1是不被允许的
  • >>> from django.template import Template, Context
  • >>> t = Template('Item 2 is {{ items.2 }}.')
  • >>> c = Context({'items': ['apples', 'bananas', 'carrots']})
  • >>> t.render(c)
  • u'Item 2 is carrots.'
  • 以上的使用方法被称为Dot Lookup方法。
  • 使用dot lookup的访问函数功能时,需要注意的问题:
  • 1. 当在模板代码中执行的函数抛出异常时,会一直向上层传播,除非这个异常中有一个参数
  • silent_variable_failure=True; 这样的话,这个出错的函数信息就会被渲染成空字符串。
  • >>> class SilentAssertionError(AssertionError):
  • ... silent_variable_failure = True
  • >>> class PersonClass4:
  • ... def first_name(self):
  • ... raise SilentAssertionError
  • >>> p = PersonClass4()
  • >>> t.render(Context({"person": p}))
  • u'My name is .'
  • 2. 很明显,调用函数会产生一些不好的结果,安全漏洞之类的,如果你有一个BankAccout,
  • 然后在模板中写成{{ account.delete }}, 这样在渲染的时候,你的账号就被删除了。。。。
  • 所以要在修改一下你的delete函数
  • def delete(self):
  • # Delete the account
  • delete.alters_data = True#缩进没有问题,把delete看成一个对象,设置它的alters_data属性。
  • 这样在渲染的时候,就会变成failed silent。
  • 当在渲染的时候,简单的key值没有找到时,会failed silent,变成空字符串,而不是大动干戈的
  • 报错。
  • >>> from django.template import Template, Context
  • >>> t = Template('Your name is {{ name }}.')
  • >>> t.render(Context())
  • u'Your name is .'
  • >>> t.render(Context({'var': 'hello'}))
  • u'Your name is .'
  • Context对象也可以进行增删改值的操作。
  • >>> from django.template import Context
  • >>> c = Context({"foo": "bar"})
  • >>> c['foo']
  • 'bar'
  • >>> c['newvariable'] = 'hello'
  • >>> del c['foo']
  • >>> c['foo']
  • 使用python manage.py shell启动python交互式命令行窗口与一般直接启动python自带的
  • 交互式命令行窗口的区别是前者会通过找一个DJANGO_SETTINGS_MODULE环境变量,
  • 告诉Django导入settings.py的配置信息。
  • 基本的tag和filter的用法
  • tag:
  •     {% if %}的使用
  • 可以使用and, or, not来组织你的逻辑。但不允许and和or同时出现的条件语句中。
  • 没有{% elif %}这样的用法,只能用嵌套来实现多重if语句。
  • {% if athlete_list %}

Here are the athletes: {{ athlete_list }}.

{% else %}

No athletes are available.

{% if not coach_list %}

Here are the coaches: {{ coach_list }}.

{% endif %}

{% endif %}

    {% for %} 的使用

用来循环一个list,还可以使用resersed关键字来进行倒序遍历,一般可以用if语句来先

判断一下列表是否为空,再进行遍历;还可以使用empty关键字来进行为空时候的跳转。

{% for athlete in athlete_list resersed %}

{{ athlete.name }}

{% empty %}

There are no athletes. Only computer programmers.

{% endfor %}

for tag还提供了一些内置参数来提供模板循环的信息。

1. forloop.counter 当前循环计数,从1开始

{% for item in todo_list %}

{{ forloop.counter }}: {{ item }}

{% endfor %}

2. forloop.counter0 当前循环计数,从0开始,标准索引方式

3. forloop.revcounter 当前循环的倒数计数,从列表长度开始

4. forloop.revcounter0 当前循环的倒数计数,从列表长度减1开始,标准

5. forloop.first bool值,判断是不是循环的第一个元素

6. forloop.last 同上,判断是不是循环的最后一个元素

7. forloop.parentloop 用在嵌套循环中,得到parent循环的引用,然后可以使用以上的参数

{% for country in countries %}

{% for city in country.city_list %}

{% endfor %}

Country #{{ forloop.parentloop.counter }} City #{{ forloop.counter }} {{ city }}

{% endfor %}

    ifequal和ifnotequal,一看就是直接比较值的tag,需要两个参数,用法比较有限,

    只限于字符串,整数,小数的比较,什么列表,字典,元组不支持。

{% ifequal user currentuser %}

Welcome!

{% ifequal section "community" %}

Community

{% endifequal %}

{% endifequal %}

    {# #},模板中注释的用法,只能用在一行

    如果要使用多行注释,要使用{% comment %}

{# This is a comment #}

{% comment %}

This is a

multi-line comment.

{% endcomment %}

filter:

filter用于变量在显示之前的一些简单的处理。使用类似管道的操作符"|",也可以进行链式操作

{{ name|lower }}

{{ my_list|first|upper }}

{{ bio|truncatewords:"30" }}

介绍几个重要的filter:

    addslashes :给任何的反斜线,单引号,双引号,再加一个反斜线。在文本中含有

javascript
字符串的时候有用。

    date :用来对data和datatime对象的字符串信息进行格式化。

    {{ pub_date|date:"F j, Y" }}

    length :返回变量的长度。

在view中使用template:

首先在settings.py中配置模板文件的路径。

TEMPLATE_DIRS = (

'/home/django/mysite/templates',

)

记住一个路径的时候要使用逗号,这样是来区分是一个tuple还是一个block expression

也可以在设置的时候使用python文件路径操作代码:

import os.path

TEMPLATE_DIRS = (

os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),

)

然后,可以在view中使用模板

from django.template.loader import get_template

from django.template import Context

from django.http import HttpResponse

import datetime

def current_datetime(

request
):

now = datetime.datetime.now()

t = get_template('current_datetime.html')

html = t.render(Context({'current_date': now}))

return HttpResponse(html)

大多数情况下,你会使用一种shortcut方法,render_to_response()去完成以上的工作。

from django.shortcuts import render_to_response

import datetime

def current_datetime(request):

now = datetime.datetime.now()

return render_to_response('current_datetime.html', {'current_date': now})

locals()的小技巧

如果你有很多变量要传给render,一个一个构造dict元素很麻烦。直接把变量名改成模板中所需要的变量名,

再使用locasl()函数,轻松搞定

def current_datetime(request):

current_date = datetime.datetime.now()

return render_to_response('current_datetime.html', locals())

locals()会返回局部空间中变量信息的dict,直接可以传给render,但有一点需要注意,它会返回把有的局部变量

信息,有一些可能不需要用到,如request变量。

{%

include
%}的使用

{% include 'nav.html' %},用来引入其它模板的内容,减少重复的模板代码

{% include template_name %},还可以使用变量名

如果include的模板文件没有找到,当DEBUG为真时,会报错TemplateDoesNotExist,当为假时,页面那一块为

空白。

诚然,include可以有效减少模板的重复代码。但一种更优雅的方式是:

template inheritance.

首先,创建base.html

{% block title %}{% endblock %}

My helpful timestamp site

{% block content %}{% endblock %}
{% block footer %}


Thanks for visiting my site.

{% endblock %}

 
我们使用一个新的tag,{% block %}用来告诉template engine,这个部分会被子模板
来实现。如果子模板没有实现这些部分,就会默认使用父模板的代码。
 
再看看,子模板要怎么写:
{% extends "base.html" %}
 
{% block title %}The current time{% endblock %}
 
{% block content %}

It is now {{ current_date }}.

{% endblock %}
只需要先使用{% extends %}继承父模板,再把相应需要实现的部分写上所需要的内容。
 
{% extends template_name %}也可以使用变量名来实现动态。
模板继承的三层继承策略:
1. 创建一个base.html,用来设置外观
2. 为网站的每一个部分,创建base_SECTION.html,比如base_phote.html, base_forum.html
3. 为每一个页面创建自己的模板。

Django框架模板高级进阶

1. RequestContext函数和context处理器

  首先,我们回顾模板的视图函数如何书写:

from django.shortcuts import render_to_response

def diary(request):
    return render_to_response('diary.html', {'name': 'qiqi'})

  为了说明方便,我们同时给出另一种写法:

from django.http import HttpResponse
from django.template import loader, Context
def diary(request):
    t = loader.get_template('diary.html')
    c = Context({'name': 'qiqi'})
    return HttpResponse(t.render(c))

  或许还是有同学看不懂,那我就再给出第三种最笨的等价写法,大家大可略过直接往后看:

from django.http import HttpResponse
from django.template import Template, Context
def diary(request):
    tin = open('./templates/diary.html')
    html = tin.read()
    tin.close()
    inf = {'name': 'qiqi'}
    t = Template(html)
    c = Context(inf)
    return HttpResponse(t.render(c))

  在上述代码中,我们是用Context函数进行渲染的。

  而与django.template.Context函数差不多的,还有一个django.template.RequestContext函数,它默认在模板中加了一些变量,比如HttpRequest对象、当前登录用户的相关信息……

  来看下面这段代码:

from django.http import HttpResponse
from django.template import loader, Context
def view_1(request):
    # ...
    t = loader.get_template('template1.html')
    c = Context({
        'app': 'My app',
        'user': request.user,
        'ip_address': request.META['REMOTE_ADDR'],
        'message': 'I am view 1.'
    })
    return HttpResponse(t.render(c))
def view_2(request):
    # ...
    t = loader.get_template('template2.html')
    c = Context({
        'app': 'My app',
        'user': request.user,
        'ip_address': request.META['REMOTE_ADDR'],
        'message': 'I am the second view.'
    })
    return HttpResponse(t.render(c))

  其中app、user、ip_address这三个变量,可能需要在很多模板的渲染中重复写入,很麻烦。而利用RequestContext函数,我们便可以将之简化为这样:

from django.http import HttpResponse
from django.template import loader, RequestContext
def custom_proc(request):
    return {
        'app': 'My app',
        'user': request.user,
        'ip_address': request.META['REMOTE_ADDR']
    }
def view_1(request):
    # ...
    t = loader.get_template('template1.html')
    c = RequestContext(request, {'message': 'I am view 1.'}, [custom_proc])
    return HttpResponse(t.render(c))
def view_2(request):
    # ...
    t = loader.get_template('template2.html')
    c = RequestContext(request, {'message': 'I am the second view.'}, [custom_proc])
    return HttpResponse(t.render(c))

  其中,我们写的函数custom_proc,便称为context处理器。用术语来说,我们利用RequestContext函数和context处理器,简化了使用模板的代码。

  而在此基础上使用render_to_response,我们还可以将之简化成:

from django.shortcuts import render_to_response
from django.template import RequestContext
def custom_proc(request):
    return {
        'app': 'My app',
        'user': request.user,
        'ip_address': request.META['REMOTE_ADDR']
    }
def view_1(request):
    # ...
    return render_to_response('template1.html',
        {'message': 'I am view 1.'},
        context_instance=RequestContext(request, [custom_proc]))
def view_2(request):
    # ...
    return render_to_response('template2.html',
        {'message': 'I am the second view.'},
        context_instance=RequestContext(request, [custom_proc]))

  此时,还是有一点美中不足的——渲染语句中,每次都需要手动为processors赋值。

  Django提供了对全局context处理器的支持——可以让你在全局变量中列出一些context处理器,Django在你每次调用RequestContext函数时都会自动加入这些处理器的。这个全局变量在TEMPLATES参数中可以找到,其默认值是:

# TEMPLATES参数中,'OPTIONS'字典中的,'context_processors'列表
[
    'django.template.context_processors.debug',
    'django.template.context_processors.request',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',
]

   这四个值不多说,可以去查书和手册。此时,我们可以进一步简化代码如下:

from django.shortcuts import render_to_response
from django.template import RequestContext
def view_1(request):
    # ...
    return render_to_response('template1.html',
        {'message': 'I am view 1.'},
        context_instance=RequestContext(request))
def view_2(request):
    # ...
    return render_to_response('template2.html',
        {'message': 'I am the second view.'},
        context_instance=RequestContext(request))

  至于context处理器,则应当写在单独的一份代码中,推荐命名为context_processors.py。

  只要把这份代码放在Python搜索路径中,Django就可以找到。推荐把它放在project或者app的目录下。

# context_processors.py
def custom_proc(request):
    return {
        'app': 'My app',
        'user': request.user,
        'ip_address': request.META['REMOTE_ADDR']
    }

  最后,修改全局变量即可:

[
    'context_processors.custom_proc',
]

 

2. html自动转义

  从模板生成html时,总会有一个风险——变量包含了会影响html的字符。

  书中举了小例子,这里不加赘述,直接说解决方法:

    1. 确保每个不被信任的变量都用escape过滤器过滤一遍,把潜在的有害html字符转换为无害的。这是初几年Django的处理策略。

    2. 利用Django的html自动转义。下面介绍这种方法。

  只要你使用Django模板,那么变量标签中的以下五个字符都会被自动转义:
原字符     转义结果
<     <
>     >
'     '
"     "
&     &

  当然,有时候你会自己手动用模板变量写一段html代码,那这时候你就需要关闭自动转义了,关闭方法如下:

    1. 变量级别,用safe过滤器: This will not be escaped: {{ data|safe }}

    2. 模板级别,用autoescape标签: {% autoescape off %} ... {% endautoescape %}

        这个标签有两种状态:off、on。

        这个标签是可以嵌套的,例如你可以在一个off的标签内嵌套on的标签。

        当你使用模板继承的时候,显而易见,这个标签依旧会持续生效的。

    3. 站点级别,这个书中只说有方法,却没写,暂时存疑。

  注意:

    1. 过滤多次和过滤一次效果完全一样。

    2. 模板中的字符串常量(例如过滤器中包含的常量)会逃过自动转义,而变量中的字符串则不会。

{{ data|default:"3 < 2" }}
{{ data|default:"3 < 2" }}  <-- Bad! Don't do this.

   存疑:

    1. escape过滤器是什么?根据文档中所写,好像是专指autoescape标签?

3. Django如何加载模板

  3.1 什么是Engine

    Engine,简单来说就是关于模板的一份设置,具体定义这里暂不介绍,大家可以先去文章开头所给的文档中查看,以后有时间会补上。

    平时加载模板,使用的就是Django中默认的一个Engine对象,其内容就是咱们在settings.py中那个TEMPLATES参数。因此,你用默认的方式加载模板,也就等同于你用Django中这个默认的Engine对象来加载模板。这个对象是: django.template.engines['django']

    而如果你想要实例化另一个Engine对象,则需要用这个定义: django.template.Engine()

  3.2 加载模板的语句

    Django加载模板的语句有三种:

      1. Engine.from_string(template_code)

        按照Engine对象的设置,编译所给代码生成模板,返回一个Template对象。

# 方法一,使用默认的Engine

from django.template import engines
template = engines['django'].from_string(template_code)

# 方法二,使用一个空的Engine(没有context_processors之类的东西)

from django.template import Engine
template = Engine().from_string(template_code)

       2. Engine.get_template(template_name)

        按照Engine对象的设置,根据所给名称找到模板,在内部进行编译,最后返回一个Template对象。

        如果模板不存在,则返回一个TemplateDoesNotExist的异常。

      3. Engine.select_template(self, template_name_list)

        按照Engine对象的设置,根据所给列表中的名称,顺次寻找模板,把找到的第一个同样处理,返回一个Template对象。

        如果全都不存在,则返回一个TemplateDoesNoeExist的异常。

  3.3 模板加载器

    我们一直说在加载模板,但是TEMPLATES参数中却并没有加载器的设置,此时我们所用的一直是Django中默认的加载器。

    下面,我们就一一介绍Django中的模板加载器:

      1. django.template.loaders.filesystem.Loader(默认)

        从文件系统中加载模板。

        路径:TEMPLATE参数中'DIRS'列表。

      2. django.template.loaders.app_directories.Loader

        从文件系统中加载模板。

        路径:各app,即INSTALLED_APPS参数每个app目录下的templates文件夹。

        开启方式:将TEMPLATES参数中'APP_DIRS'设置为True。

      3. django.template.loaders.eggs.Loader

        从Python egg中加载模板。

        路径:各app。

        开启方式:写出类似代码(未经测试,仅供参考)——

TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    'OPTIONS': {
        'loaders': [
            ('django.template.loaders.eggs.Loader'),
        ],
    },
}]

       4. django.template.loaders.cached.Loader

        加载模板时,第一次调用各加载器加载模板并存入缓存,以后则从缓存中直接加载模板。

        路径:取决于调用的各加载器。

        注意:实际加载的各模板应该保证其结点(Node)是进程安全(thread-safe)的,详见文档。

        开启方式:写出类似代码(源自文档)——

TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    'OPTIONS': {
        'loaders': [
            ('django.template.loaders.cached.Loader', [
                'django.template.loaders.filesystem.Loader',
                'django.template.loaders.app_directories.Loader',
            ]),
        ],
    },
}]

       5. django.template.loaders.locmem.Loader

        从Python字典中加载模板,常用于测试。

        存疑:实际效果未测试过,不是很能理解。

        开启方式:写出类似代码(源自文档)——

TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'OPTIONS': {
        'loaders': [
            ('django.template.loaders.locmem.Loader', {
                'index.html': 'content here',
            }),
        ],
    },
}]

实际上,书和文档中还提到了如何写自己的模板、模板中用于debug的两个类、如何写独立模型下的模板……

但由于暂时还用不到,所以先不写了,等以后用到再补充。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索函数
, 变量
, 参数
, django
, context
代码
django 模板、django html模板、django 模板语法、django 模板继承、django 模板 if,以便于您获取更多的相关知识。

时间: 2024-12-22 17:15:31

Django框架模板从基础入门到进阶的相关文章

学习网页制作基础入门教程(8)框架标签

教程|入门教程|网页 相关文章: 学习网页制作基础入门教程(1)网页编写 学习网页制作基础入门教程(2)排版标签 学习网页制作基础入门教程(3)字体标签 学习网页制作基础入门教程(4)图象标签 学习网页制作基础入门教程(5)图象标签 学习网页制作基础入门教程(6)连接标签 学习网页制作基础入门教程(7)表格标签 框架概念 1. 首先,各位先看看右边这张图片,将利用这张图来做解释,这样子,讲起来可能会清楚一些. 我们可以看见,右边的这个图片,一共分为 1 . 2 . 3 三个框架,每一个框架,各有

Python的Django框架使用入门指引_python

 前言 传统 Web 开发方式常常需要编写繁琐乏味的重复性代码,不仅页面表现与逻辑实现的代码混杂在一起,而且代码编写效率不高.对于开发者来说,选择一个功能强大并且操作简洁的开发框架来辅助完成繁杂的编码工作,将会对开发效率的提升起到很大帮助.幸运的是,这样的开发框架并不少见,需要做的仅是从中选出恰恰为开发者量身打造的那款Web框架. 自从基于 MVC 分层结构的 Web 设计理念普及以来,选择适合的开发框架无疑是项目成功的关键性因素.无论是 Struts.Spring 或是其他 Web 框架的出现

smarty模板引擎基础知识入门_php实例

本文实例讲述了smarty模板引擎基础知识.分享给大家供大家参考.具体如下: 一.基本概念 1.什么是mvc? mvc是一种开发模式,核心思想是:数据的输入.数据的处理.数据显示的强制分离. 2.什么是smarty? smarty是一个php的模板引擎.更明确的来说,它可以帮助开发者更好的分离程序逻辑和页面显示. 3.smarty运行原理 模板文件,就是一个显示数据的模板,其中需要显示的数据用占位符代替. smarty运行时,会读取模板文件,将模板文件中的占位符替换成真正的数据,并输出一个处理后

Thinkphp入门三—框架模板、变量(47)

原文:Thinkphp入门三-框架模板.变量(47) [在控制器调用模板] display()   调用当前操作名称的模板 display('名字')  调用指定名字的模板文件 控制器调用模板四种方式: [在控制器给模板传递变量] 在smarty里边给模板传递变量信息 $smarty -> assign(变量名称,值); 在tp框架里边同样适用assign()给模板传递变量信息 ThinkPHP的模板引擎的左右标记:        ThinkPHP/Lib/ Behavior/ ParseTem

在Django框架中自定义模板过滤器的方法_perl

自定义过滤器就是有一个或两个参数的Python函数:     (输入)变量的值     参数的值, 可以是默认值或者完全留空 例如,在过滤器 {{ var|foo:"bar" }} 中 ,过滤器 foo 会被传入变量 var 和默认参数 bar. 过滤器函数应该总有返回值. 而且不能触发异常,它们都应该静静地失败. 如果出现错误,应该返回一个原始输入或者空字符串,这会更有意义. 这里是一些定义过滤器的例子: def cut(value, arg): "Removes all

对于Python的Django框架部署的一些建议_python

"Django应用.配置文件以及其他各种相关目录的最佳布局是什么样的?" 总是有朋友问我们这个问题,因此我想花一点时间,写一下我们究竟是如何看待这个问题的,这样我们就可以很容易让其他人参照这个文档.请注意,这里是基于 Django 1.7.1 版写的,但是可以很容易应用在 Django 1.4 版之后任何版本. 虽然 Django 1.4 发布时,它包含了一个改进后的项目布局(这还用了很长一段时间),但本文有一些优化项目布局的更好建议.为什么这种布局比较好 我们在这里推荐的项目布局有几

使用Python的Django框架实现事务交易管理的教程_python

 如果你花费了很多的时间去进行Django数据库事务处理的话,你将会了解到这是让人晕头转向的. 在过去,只是提供了简单的基础文档,要想清楚知道它是怎么使用的,还必须要通过创建和执行Django的事务处理. 这里有众多的Django事务处理的名词,例如:commit_on_success , commit_manually , commit_unless_maneged,rollback_unless_managed,enter_transaction_management,leace_trans

简化Python的Django框架代码的一些示例_python

尽管Django的流行和普及, 一些开发者仍然认为她是一个过时的web开发框架, 仅仅适合内容丰富的web程序. 然而现在大多数web程序往往不是富内容的, 这似乎让Django看起来不是最佳选择的web框架. 那么让我们花点时间从现在的web开发实践中重新认识下她吧. 简单清晰的Django 一个web框架主要是帮助web程序生成核心的架构, 以便在其他的项目中重用. Django正是以此为基础, 快速构建web程序. Django的核心主要是WSGI程序, 通过处理HTTP请求并返回有意义的

详尽讲述用Python的Django框架测试驱动开发的教程_python

测试驱动开发(TDD)是一个迭代的开发周期,强调编写实际代码之前编写自动化测试. 这个过程很简单:     先编写测试.     查看测试失败的地方     编写足够的代码以使测试通过.     再次测试.     代码重构 .     重复以上操作. 为什么要用TDD? 使用TDD,你将学会把你的代码拆分成符合逻辑的,简单易懂的片段,这有助于确保代码的正确性. 这一点非常重要,因为做到下面这些事情是非常困难的:     在我们的脑中一次性处理所有复杂的问题.     了解何时从哪里开始着手解决