首页 > 编程知识 正文

带自定义后端的python(前端自定义组件)

时间:2023-12-24 12:05:50 阅读:321032 作者:YOHG

本文目录一览:

Python能做什么,能够开发什么项目?

Python是一种计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。

Python是一种解释型脚本语言,可以应用于Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发这些领域。

Python的应用

1、系统编程

提供API(Application Programming Interface应用程序编程接口),能方便进行系统维护和管理,Linux下标志性语言之一,是很多系统管理员理想的编程工具。

2、图形处理

有PIL、Tkinter等图形库支持,能方便进行图形处理。

3、数学处理

NumPy扩展提供大量与许多标准数学库的接口。

4、文本处理

python提供的re模块能支持正则表达式,还提供SGML,XML分析模块,许多程序员利用python进行XML程序的开发。

5、数据库编程

程序员可通过遵循Python DB-API(数据库应用程序编程接口)规范的模块与Microsoft SQL Server,Oracle,Sybase,DB2,MySQL、SQLite等数据库通信。python自带有一个Gadfly模块,提供了一个完整的SQL环境。

6、网络编程

提供丰富的模块支持sockets编程,能方便快速地开发分布式应用程序。很多大规模软件开发计划例如Zope,Mnet 及BitTorrent. Google都在广泛地使用它。

7、Web编程

应用的开发语言,支持最新的XML技术。

8、多媒体应用

Python的PyOpenGL模块封装了“OpenGL应用程序编程接口”,能进行二维和三维图像处理。PyGame模块可用于编写游戏软件。

9、pymo引擎

PYMO全称为python memories off,是一款运行于Symbian S60V3,Symbian3,S60V5, Symbian3, Android系统上的AVG游戏引擎。因其基于python2.0平台开发,并且适用于创建秋之回忆(memories off)风格的AVG游戏,故命名为PYMO。

10、黑客编程

python有一个hack的库,内置了你熟悉的或不熟悉的函数,但是缺少成就感。

参考资料来源:百度百科—Python

python后端开发需要学什么?

可以参考下面的路径去学习,祝你学有所成,公司最近在人工智能和自然语言处理的项目后端项目,我也是网上找了很多知识,最后给自己列了一个学习的目录,按照这个在复习并在总结,希望能帮到你:

计算机基本认知,环境搭建    python环境搭建

计算机基本认识,进制转换

python注释使用

python变量使用

python数据类型_Number

python数据类型    str字符串类型

容器类型数据list,tuple,str

容器类型数据set,dict

变量缓存机制

自动类型转换

Number强制类型转换  

python运算符的使用    容器类型数据强制类型转换

字典强转等长二级容器

运算符_算数_比较

运算符_赋值_成员

运算符_身份_逻辑

运算符_位运算_优先级  

python流程控制    代码块

流程控制if

多项巢状分支

循环结构while

循环判断经典题

字符串的相关操作  

python循环结构    

关键字continue_break_pass

for循环的遍历_range  

字符串,列表内置方法    

字符串函数

format字符串格式化

format特殊符号的使用

列表的操作

列表函数  

字典,集合内置方法+文件操作    

字典的相关函数

集合操作_函数

文件操作

文件加号模式  

函数,函数参数    文件相关函数 

函数

形参实参

默认形参_关键字形参

收集参数

命名关键字参数

全局/局部变量,闭包    return返回值

函数名的使用

局部变量_全局变量

函数的嵌套LEGB

关键字nonlocal

闭包函数  

递归,匿名函数    

locals和globals

闭包特点意义

递归含义

斐波那契_尾递归

匿名函数lambda  

迭代器,高阶函数    迭代器

高阶函数_map

高阶函数_reduce

高阶函数_sorted

高阶函数_filter  

推导式    列表推导式

推导式题

集合_字典推导式

生成器表达式

生成器函数  

内置方法,linux基本命令    内置函数

可滑动序列

面试题演练

linux安装

linux基本命令  

python模块    序列化模块

数学模块

随机模块

time模块  

python模块    os模块

os_shutil

os.path模块

计算文件夹大小

zipfile

tarfile  

导入模块包,oop面向对象认知    

import_from绝对导入

import_from相对导入(单入口)

oop面向对象

类的封装性

oop之封装,继承    类的相关操作

对象和类的删除操作

单继承

多继承

菱形继承

oop之多态,魔术方法    多态

魔术方法__new__

单态模式

析构方法__del__  

oop之魔术方法,异常处理    魔术方法__call__

魔术方法__str__repr__

魔术方法__bool_add_len__

了解异常

异常处理语法

主动抛出异常

装饰器  

装饰器

静态绑定方法

property 

正则表达式    单个字符匹配

多个字符匹配

匹配分组

命名分组

正则函数

正则计算器小程序

认识网络    bs_cs流程

传输数据流程

交换机和局域网的网络通讯

arp协议  

认识tcp/udp协议  

tcp基本语法

tcp循环发消息

udp基本语法

udp循环发消息

黏包  

基于tcp协议下的应用    socketserver并发

文件校验

服务器合法性校验

tcp登录

并发编程之进程    进程

join

守护进程

lock锁

Semaphore

生产者消费者模型    Event事件

进程队列Queue

生产者和消费者模型

JoinableQueue

Manager.py

并发编程之线程

.线程

用类定义线程

守护线程

lock保证线程数据安全

信号量_Semaphore

死锁,互斥锁,递归锁

线程池,进程池,协成的使用

事件Event

线程队列

进程池和线程池

回调函数

协程

协程的爬虫案例

mysql安装(linux+windows+xshell+navicat)  

掌握数据库mysql基本操作

mysql登录,服务启动

创建账户,用户授权

数据库,数据表,数据的增删改查

认识常用数据类型  

数据库的存储引擎和约束  

字段约束

约束的删减

存储引擎区别用法

数据表之间的关系  

查询数据表  

单表查询

多表联查

子查询

带EXISTS关键字的子查询

python操作mysql  

python连接mysql的事务处理

sql注入

python连接mysql增删改查

mysql数据恢复  

HTML/CSS    html文档介绍,html标签,body标签,head标签介绍,head标签中的meta标签和link标签和title标签介绍,body中的标签分类,基础标签,img、a、列表、表格、input、label、select等标签,作业讲解,form标签介绍和示例讲解,css介绍,引入,css选择器,背景设置,高度宽度,字体效果,边框、盒子模型、display属性、float属性等  

CSS    伪类选择器,文字装饰、a标签补充、定位、权重、小米商城导航栏讲解,原型头像示例讲解  

JS基础/BOM和DOM操作    小米商城作业,js介绍和js引入,js数据类型、流程控制、函数等操作,js中的JSON,BOM对象的弹框、location对象、定时器、直接查找选择器、间接查找选择器、值操作、类值操作、样式操作、button按钮补充、事件和绑定事件的两种方式,常用事件练习  

jQuery/Bootstrap    作业讲解,jquery介绍,引入、选择器、筛选器、值操作、文档操作、删除和清空标签、逻辑运算符、克隆、事件冒泡和事件委托、绑定事件的方式,作业讲解和模态对话框示例,input事件和页面载入事件补充、bootstrap介绍和引入、全局css样式、组件和常用插件

自定义web框架    作业讲解、web框架介绍、自定义web框架实现、动态页面、返回不同的html页面、函数版、多线程版、返回静态文件版,wsgiref版等web框架通过socket来实现,还有jinja2的简单使用  

django下载安装和URL路由系统    django介绍、MTV和MVC框架介绍、常用指令、目录结构、pycharm创建django项目、request的常用属性介绍、登录示例、url路由系统介绍、有名分组和无名分组,  

视图/模板    request对象的常用方法和属性、响应方法介绍和使用,CBV和FBV、CBV和FBV加装饰器,CBV源码讲解,模板渲染系统介绍,语法、简单示例、内置过滤器、for循环标签、if标签、with标签、自定义过滤器和标签、模板继承等  

Dajngo的ORM(1)    orm介绍,数据库同步指令使用和流程分析、配置连接mysql模型类中的属性介绍和常用参数说明,创建表和数据、增加的两种方法、删除、更新的两种方法、查询的13个api接口  

Dajngo的ORM(2)    单表图书管理系统展示和添加作业讲解、choices属性、auto_now_add和auto_now参数讲解、url别名和反向解析,基于双下划线的模糊查询,多表结构介绍,图书管理系统编辑和删除作业讲解、多表关系模型类创建和字段说明和参数介绍、多表数据的添加操作,多表的删除和修改、基于对象的跨表查询、双下划线跨表查询、查看原生sql语句的方法、聚合查询、分组查询、F查询、Q查询等  

Ajax与Django/ 中间件    ajax的介绍和简单示例,ajax登录示例、列表数据展示示例,ajax操作cookie的补充、中间件介绍、自定义中间件的方法、5个中间件方法的介绍和使用、基于中间件的session登录认证 

cookie、session以及用户认证组件    cookie介绍,cookie的流程解析,django操作cookie和其他参数介绍、session的说明、django的session操作等,多表图书管理系统作业讲解  

vue初识、es6基本语法、指令系统    let、const、v-if、v-for、v-html、v-text、v-model、v-show、生命周期钩子函数、  

组件化开发、组件传值、axios简单使用    组件化开发、组件传值、axios简单使用、vue-router使用、vue-cli安装  

项目初始化/首页    项目介绍、创建、初始化、element-ui的使用,单文件组件的使用和axios在单文件中的使用和配置、vue-cli的介绍和使用、路飞项目顶部导航栏页面效果搭建,轮播图组件的使用和调整、购物车页面搭建和课程详情页面搭建,vue-video-player视频播放插件  

drf组件    序列化器、drf简单示例、restful规范、反序列化的校验机制  

drf组件    apiview、request和response对象、modelserializer、序列化器保存数据、read_only和write_only的参数  

drf组件    viewset、drf路由功能、viewset视图基类的使用、视图子类、通用视图类genericapiview/排序、django-filter过滤器、频率组件、分页组件、接口文档、异常处理、xadmin的安装和使用、认证组件和权限组件  

git、消息队列    git企业中的使用模式,rabbimq消息队列的应用  

rpc通信,grpc组件    rpc的概念以及通信模式,最火的grpc组件使用 

轻量级Flask框架    Werkzeug服务介绍、Flask框架介绍  

路由系统、自定义路由扩展  

Cookie、Session、Http请求和响应  

蓝图、消息闪现、中间件  

Flask常用扩展、WTForms、使用SQLAchemy ORM  

Admin、Restful、websocket原理、magic string, payload len,masking key   

请求和上下文、多app应用、离线脚本、自定义扩展 

服务端项目搭建,项目配置(session、数据库、日志相关),项目初始化  

jsonrpc模块基本配置和使用,客户端展示首页及登录注册叶绵,APICloud页面控制管理

python进阶    并发、同步、异步、锁,线进程概念以及协程实现原理  

mysql进阶课    基础知识梳理、索引、执行计划  

mysql进阶课    存储引擎、日志管理、备份恢复、主从赋值、优化  

redis,mongodb    事务和发布订阅、RDB和AOF持久化、缓存击穿、缓存雪崩等原理介绍、 用户管理和复制集(RS)总结、sharding cluster 分片集群的搭建、分片使用和相关策略等  

算法与设计模式    链表、二叉树、常见算法、二分查找、插入排序、希尔排序、快排、堆排序、哈希查找  

算法与设计模式    设计模式,单例模式、工厂模式、策略模式、观察者模式  

算法与设计模式    leetcode经典算法解析  

知识体系差不多就这么多了,再就是项目部分,具体项目要看需求了,学会了钓鱼的方法,不怕钓不到鱼哦,无论在哪个行业做什么样的项目都没问题呢!

我自己也搜集了一些经典的资料,要是想要加我百度网盘:艾美电商,我发给你!

Python用来做什么开发比较有优势

python在Web开发、数据分析、机器学习等方面,有较好的优势。

1、Web开发

Django和Flask等基于Python的Web框架最近在Web开发中非常流行。这些Web框架可以帮助你用Python编写服务器端代码(后端代码)。这是在你的额服务器上运行的代码,而不是运行在用户设备和浏览器的代码(前端代码)。

2、数据科学

数据科学,这里包括机器学习,数据分析和数据可视化。机器学习通过实现算法,该算法能够自动检测输入中的模式。

3、数据分析和数据可视化

使用Python进行数据分析/可视化,进行数据可视化时,Matplotlib是非常热门的库。

扩展资料

1、应该使用哪种Python Web框架

Django和Flask是最流行的两种Python Web框架。如果你刚刚入门,可以使用其中一种。

2、有一些热门的机器学习库和Python框架。其中两个最热门的是scikit-learn和TensorFlow。scikit-learn带有一些内置的热门机器学习算法。TensorFlow是一个低级库,能让你创建自定义机器学习算法。

参考资料

百度百科-Python

有哪些值得推荐的 Python 开发工具?

第一款:最强终端 Upterm

它是一个全平台的终端,可以说是终端里的IDE,有着强大的自动补全功能,之前的名字叫做:BlackWindow。有人跟他说这个名字不利于社区推广,改名叫Upterm之后现在已经17000+Star了。

第二款:交互式解释器 PtPython

一个交互式的Python解释器,支持语法高亮、提示,甚至是VIM和emacs的键入模式。

第三款:包管理必备 Anaconda

强烈推荐:Anaconda。它能帮你安装许多麻烦的东西,包括:Python环境、pip包管理工具、常用的库、配置好环境路径等等。这些小事情小白自己一个个去做的话,容易遇到各种问题,也容易造成挫败感。如果你想用Python搞数据方面的事情,安装它就可以了,它甚至开发了一套JIT的解释器Numba。所以Anaconda有了JIT之后,对线上科学计算效率要求比较高的东西也可以搞定了。

第四款:编辑器 Sublime3

如果你是小白的话,推荐从PyCharm开始上手,但是有时候写一些轻量的小脚本,就会想到轻量级一点的工具。Sublime3很多地方都有了极大的提升,并且用起来比原来还要简单,配合安装Anaconda或CodeIntel插件,可以让Sublime3拥有近乎IDE的体验。

第五款:前端在线编辑器 CodeSandbox

虽然这个不算是真正意义上的Python开发工具,但如果后端工程师想要写前端的话,这个在线编辑器太方便了,节省了后端工程师的生命。不用安装npm的几千个包了,它已经在云端完成了,才让你直接就可以上手写代码、看效果。对于React、Vue这些主流前端框架都支持。

第六款:Python Tutor

Python Tutor是一个免费教育工具,可帮助学生攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。通过这个工具,教师或学生可以直接在web浏览器中编写Python代码,并逐步可视化地运行程序。

第七款:IPython

如何进行交互式编程?没错,就是通过IPython。IPython相对于Python自带的shell要好用的多,并且能够支持代码缩进、TAB键补全代码等功能。如果进行交互式编程,这是不可缺少的工具。

第八款:Jupyter Notebook

Jupyter Notebook就像一个草稿本,能将文本注释、数学方程、代码和可视化内容全部组合到一个易于共享的文档中,以Web页面的方式展示,它是数据分析、机器学习的必备工具。

第九款:Pycharm

Pycharm是程序员常常使用的开发工具,简单、易用,并且能够设置不同的主题模式,根据自己的喜好来设置代码风格。

第十款:Python Tutor

这个工具可能对初学者比较有用,而对于中高级程序员则用处较少。这个工具的特色是能够清楚的理解每一行代码是如何在计算机中执行的,中高级程序员一般通过分步调试可以实现类似的功能。这个工具对于最初接触Python、最初来学习编程的同学还是非常有用的,初学者可以体验一下。

5款程序员常用的Python开发工具

很多Python学习者想必都会有如下感悟:最开始学习Python的时候,因为没有去探索好用的工具,吃了很多苦头。后来工作中深刻体会到,合理使用开发的工具的便利和高效。今天,我就把Python程序员使用频率比较高的5款开发工具推荐给大家,希望对大家的工作和学习有帮助。

一、最强终端:Upterm

本来想推荐 fish 或者 zsh,但其实这两个我也主要是贪图自动补全这个特性。最近在用的这个 Upterm 其实很简单好用,它是一个全平台的终端,可以说是终端里的 IDE,有着强大的自动补全功能。之前的名字叫 BlackWindow,有人跟他说这个名字不利于社区推广,改名叫 Upterm 之后现在已经17000+ Star了。

二、交互式解释器:Ptpython

一个交互式的 Python 解释器。支持语法高亮、提示甚至是 vim 和 emacs 的键入模式。其实我们在课程里提供的在线终端也内置了ptpython。

相关推荐:《Python视频教程》

三、包管理必备:Anaconda

强烈推荐Anaconda ,它能帮你安装好许多麻烦的东西,包括: Python 环境、pip 包管理工具、常用的库、配置好环境路径等等。这些事情小白自己一个个去做的话,容易遇到各种问题,带来挫败感。如果你想用Python搞数据方面的事情,就安装它就好了,它甚至开发了一套JIT的解释器Numba。所以 Anaconda有了JIT之后,对线上科学计算效率要求比较高的东西也可以搞了。

四、编辑器:Sublime3

小白的话当然还是推荐从PyCharm开始上手,但有时候写一些轻量的小脚本,就会想用轻量级一点的工具。Sublime3很多地方都有了极大的提升,并且用起来比原来还要简单。配合安装Anaconda或CodeIntel插件,可以让 Sublime拥有近乎IDE的体验。

五、前端在线编辑器:CodeSandbox

虽然这个不算是真正意义上的Python开发工具,但如果后端工程师想写前端的话,这个在线编辑器太方便了,简直是节省了后端工程师的生命啊!不用安装npm的几千个包了,它已经在云端完成了,采让你直接就可以上手写代码、看效果。对于 React、Vue 这些主流前端框架都支持。算是一个补充推荐吧。

后端编程Python3-数据库编程

对大多数软件开发者而言,术语数据库通常是指RDBMS(关系数据库管理系统), 这些系统使用表格(类似于电子表格的网格),其中行表示记录,列表示记录的字段。表格及其中存放的数据是使用SQL (结构化査询语言)编写的语句来创建并操纵的。Python提供了用于操纵SQL数据库的API(应用程序接口),通常与作为标准的SQLite 3数据库一起发布。

另一种数据库是DBM (数据库管理器),其中存放任意数量的键-值项。Python 的标准库提供了几种DBM的接口,包括某些特定于UNIX平台的。DBM的工作方式 与Python中的字典类似,区别在于DBM通常存放于磁盘上而不是内存中,并且其键与值总是bytes对象,并可能受到长度限制。本章第一节中讲解的shelve模块提供了方便的DBM接口,允许我们使用字符串作为键,使用任意(picklable)对象作为值。

如果可用的 DBM 与 SQLite 数据库不够充分,Python Package Index, pypi.python.org/pypi中提供了大量数据库相关的包,包括bsddb DBM ("Berkeley DB"),对象-关系映射器,比如SQLAlchemy (),以及流行的客户端/服务器数据的接口,比如 DB2、Informix、Ingres、MySQL、ODBC 以及 PostgreSQL。

本章中,我们将实现某程序的两个版本,该程序用于维护一个DVD列表,并追踪每个DVD的标题、发行年份、时间长度以及发行者。该程序的第一版使用DBM (通过shelve模块)存放其数据,第二版则使用SQLite数据库。两个程序都可以加载与保存简单的XML格式,这使得从某个程序导出DVD数据并将其导入到其他程序成为可能。与DBM版相比,基于SQL的程序提供了更多一些的功能,并且其数据设计也稍干净一些。

12.1 DBM数据库

shelve模块为DBM提供了一个wrapper,借助于此,我们在与DBM交互时,可以将其看做一个字典,这里是假定我们只使用字符串键与picklable值,实际处理时, shelve模块会将键与值转换为bytes对象(或者反过来)。

由于shelve模块使用的是底层的DBM,因此,如果其他计算机上没有同样的DBM,那么在某台计算机上保存的DBM文件在其他机器上无法读取是可能的。为解决这一问题,常见的解决方案是对那些必须在机器之间可传输的文件提供XML导入与导出功能,这也是我们在本节的DVD程序dvds-dbm.py中所做的。

对键,我们使用DVD的标题;对值,则使用元组,其中存放发行者、发行年份以及时间。借助于shelve模块,我们不需要进行任何数据转换,并可以把DBM对象当做一个字典进行处理。

程序在结构上类似于我们前面看到的那种菜单驱动型的程序,因此,这里主要展示的是与DBM程序设计相关的那部分。下面给出的是程序main()函数中的一部分, 忽略了其中菜单处理的部分代码。

db = None

try:

db = shelve.open(filename, protocol=pickle.HIGHEST_PROTOCOL)

finally:

if db is not None:

db.dose()

这里我们已打开(如果不存在就创建)指定的DBM文件,以便于对其进行读写操作。每一项的值使用指定的pickle协议保存为一个pickle,现有的项可以被读取, 即便是使用更底层的协议保存的,因为Python可以计算出用于读取pickle的正确协议。最后,DBM被关闭——其作用是清除DBM的内部缓存,并确保磁盘文件可以反映出已作的任何改变,此外,文件也需要关闭。

该程序提供了用于添加、编辑、列出、移除、导入、导出DVD数据的相应选项。除添加外,我们将忽略大部分用户接口代码,同样是因为已经在其他上下文中进行了展示。

def add_dvd(db):

title = Console.get_string("Title", "title")

if not title:

return

director = Console.get_string("Director", "director")

if not director:

return

year = Console.get_integer("Year", "year",minimum=1896,

maximum=datetime,date.today().year)

duration = Console.get_integer("Duration (minutes)", "minutes“, minimum=0, maximum=60*48)

db[title] = (director, year, duration)

db.sync()

像程序菜单调用的所有函数一样,这一函数也以DBM对象(db)作为其唯一参数。该函数的大部分工作都是获取DVD的详细资料,在倒数第二行,我们将键-值项存储在DBM文件中,DVD的标题作为键,发行者、年份以及时间(由shelve模块pickled在一起)作为值。

为与Python通常的一致性同步,DBM提供了与字典一样的API,因此,除了 shelve.open() 函数(前面已展示)与shelve.Shelf.sync()方法(该方法用于清除shelve的内部缓存,并对磁盘上文件的数据与所做的改变进行同步——这里就是添加一个新项),我们不需要学习任何新语法。

def edit_dvd(db):

old_title = find_dvd(db, "edit")

if old_title is None:

return

title = Console.get.string("Title", "title", old_title)

if not title:

return

director, year, duration = db[old_title]

...

db[title]= (director, year, duration)

if title != old_title:

del db[old_title]

db.sync()

为对某个DVD进行编辑,用户必须首先选择要操作的DVD,也就是获取DVD 的标题,因为标题用作键,值则用于存放其他相关数据。由于必要的功能在其他场合 (比如移除DVD)也需要使用,因此我们将其实现在一个单独的find_dvd()函数中,稍后将査看该函数。如果找到了该DVD,我们就获取用户所做的改变,并使用现有值作为默认值,以便提高交互的速度。(对于这一函数,我们忽略了大部分用户接口代码, 因为其与添加DVD时几乎是相同的。)最后,我们保存数据,就像添加时所做的一样。如果标题未作改变,就重写相关联的值;如果标题已改变,就创建一个新的键-值对, 并且需要删除原始项。

def find_dvd(db, message):

message = "(Start of) title to " + message

while True:

matches =[]

start = Console.get_string(message, "title")

if not start:

return None

for title in db:

if title.lower().startswith(start.lower()):

matches.append(title)

if len(matches) == 0:

print("There are no dvds starting with", start)

continue

elif len(matches) == 1:

return matches[0]

elif len(matches) DISPLAY_LIMIT:

print("Too many dvds start with {0}; try entering more of the title".format(start)

continue

else:

matches = sorted(matches, key=str.lower)

for i, match in enumerate(matches):

print("{0}: {1}".format(i+1, match))

which = Console.get_integer("Number (or 0 to cancel)",

"number", minimum=1, maximum=len(matches))

return matches[which - 1] if which != 0 else None

为尽可能快而容易地发现某个DVD,我们需要用户只输入其标题的一个或头几个字符。在具备了标题的起始字符后,我们在DBM中迭代并创建一个匹配列表。如果只有一个匹配项,就返回该项;如果有几个匹配项(但少于DISPLAY_LIMIT, 一个在程序中其他地方设置的整数),就以大小写不敏感的顺序展示所有这些匹配项,并为每一项设置一个编号,以便用户可以只输入编号就可以选择某个标题。(Console.get_integer()函数可以接受0,即便最小值大于0,以便0可以用作一个删除值。通过使用参数allow_zero=False, 可以禁止这种行为。我们不能使用Enter键,也就是说,没有什么意味着取消,因为什么也不输入意味着接受默认值。)

def list_dvds(db):

start =”"

if len(db) DISPLAY.LIMIT:

start = Console.get_string(“List those starting with [Enter=all]”, "start”)

print()

for title in sorted(db, key=str.lower):

if not start or title.Iower().startswith(start.lower()):

director, year, duration = db[title]

print("{title} ({year}) {duration} minute{0}, by "

"{director}".format(Util.s(duration),**locals()))

列出所有DVD (或者那些标题以某个子字符串引导)就是对DBM的所有项进行迭代。

Util.s()函数就是简单的s = lambda x: "" if x == 1 else "s",因此,如果时间长度不是1分钟,就返回"s"。

def remove_dvd(db):

title = find_dvd(db, "remove")

if title is None:

return

ans = Console.get_bool("Remove {0}?".format(title), "no")

if ans:

del db[title]

db.sync()

要移除一个DVD,首先需要找到用户要移除的DVD,并请求确认,获取后从DBM中删除该项即可。

到这里,我们展示了如何使用shelve模块打开(或创建)一个DBM文件,以及如何向其中添加项、编辑项、对其项进行迭代以及移除某个项。

遗憾的是,在我们的数据设计中存在一个瑕疵。发行者名称是重复的,这很容易导致不一致性,比如,发行者Danny DeVito可能被输入为"Danny De Vito",用于 一个电影;也可以输入为“Danny deVito",用于另一个。为解决这一问题,可以使用两个DBM文件,主DVD文件使用标题键与(年份,时间长度,发行者ID)值; 发行者文件使用发行者ID (整数)键与发行者名称值。下一节展示的SQL数据库 版程序将避免这一瑕疵,这是通过使用两个表格实现的,一个用于DVD,另一个用于发行者。

12.2 SQL数据库

大多数流行的SQL数据库的接口在第三方模块中是可用的,Python带有sqlite3 模块(以及SQLite 3数据库),因此,在Python中,可以直接开始数据库程序设计。SQLite是一个轻量级的SQL数据库,缺少很多诸如PostgreSQL这种数据库的功能, 但非常便于构造原型系统,并且在很多情况下也是够用的。

为使后台数据库之间的切换尽可能容易,PEP 249 (Python Database API Specification v2.0)提供了称为DB-API 2.0的API规范。数据库接口应该遵循这一规范,比如sqlite3模块就遵循这一规范,但不是所有第三方模块都遵循。API规范中指定了两种主要的对象,即连接对象与游标对象。表12-1与表12-2中分别列出了这两种对象必须支持的API。在sqlite3模块中,除DB-API 2.0规范必需的之外,其连接对象与游标对象都提供了很多附加的属性与方法。

DVD程序的SQL版本为dvds.sql.py,该程序将发行者与DVD数据分开存储,以 避免重复,并提供一个新菜单,以供用户列出发行者。该程序使用的两个表格在图12-1

def connect(filename):

create= not os.path.exists(filename)

db = sqlite3.connect(filename)

if create:

cursor = db.cursor()

cursor.execute("CREATE TABLE directors ("

"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "

"name TEXT UNIQUE NOT NULL)")

cursor.execute("CREATE TABLE dvds ("

"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "

"title TEXT NOT NULL, "

"year INTEGER NOT NULL,"

"duration INTEGER NOT NULL, "

"director_id INTEGER NOT NULL, ”

"FOREIGN KEY (director_id) REFERENCES directors)")

db.commit()

return db

sqlite3.connect()函数会返回一个数据库对象,并打开其指定的数据库文件。如果该文件不存在,就创建一个空的数据库文件。鉴于此,在调用sqlite3.connect()之前,我们要注意数据库是否是准备从头开始创建,如果是,就必须创建该程序要使用的表格。所有査询都是通过一个数据库游标完成的,可以从数据库对象的cursor()方法获取。

注意,两个表格都是使用一个ID字段创建的,ID字段有一个AUTOINCREMENT 约束——这意味着SQLite会自动为ID字段赋予唯一性的数值,因此,在插入新记录时,我们可以将这些字段留给SQLite处理。

SQLite支持有限的数据类型——实际上就是布尔型、数值型与字符串——但使用数据'‘适配器”可以对其进行扩展,或者是扩展到预定义的数据类型(比如那些用于日期与datetimes的类型),或者是用于表示任意数据类型的自定义类型。DVD程序并不需要这一功能,如果需要,sqlite3模块的文档提供了很多详细解释。我们使用的外部键语法可能与用于其他数据库的语法不同,并且在任何情况下,只是记录我们的意图,因为SQLite不像很多其他数据库那样需要强制关系完整性,sqlite3另一点与众不同的地方在于其默认行为是支持隐式的事务处理,因此,没有提供显式的“开始事务” 方法。

def add_dvd(db):

title = Console.get_string("Title", "title")

if not title:

return

director = Console.get_string("Director", "director")

if not director:

return

year = Console.get_integer("Year", "year”, minimum=1896,

maximum=datetime.date.today().year)

duration = Console.get_integer("Duration (minutes)", "minutes",

minimum=0,maximum=60*48)

director_id = get_and_set_director(db, director)

cursor = db.cursor()

cursor.execute("INSERT INTO dvds ”

"(title, year, duration, director_id)"

"VALUES (?, ?, ?, ?)",

(title, year, duration, director_id))

db.commit()

这一函数的开始代码与dvds-dbm.py程序中的对应函数一样,但在完成数据的收集后,与原来的函数有很大的差别。用户输入的发行者可能在也可能不在directors表格中,因此,我们有一个get_and_set_director()函数,在数据库中尚无某个发行者时, 该函数就将其插入到其中,无论哪种情况都返回就绪的发行者ID,以便在需要的时候插入到dvds表。在所有数据都可用后,我们执行一条SQL INSERT语句。我们不需要指定记录ID,因为SQLite会自动为我们提供。

在査询中,我们使用问号(?)作为占位符,每个?都由包含SQL语句的字符串后面的序列中的值替代。命名的占位符也可以使用,后面在编辑记录时我们将看到。尽管避免使用占位符(而只是简单地使用嵌入到其中的数据来格式化SQL字符串)也是可能的,我们建议总是使用占位符,并将数据项正确编码与转义的工作留给数据库模块来完成。使用占位符的另一个好处是可以提高安全性,因为这可以防止任意的SQL 被恶意地插入到一个査询中。

def get_and_set_director(db, director):

director_id = get_director_id(db, director)

if directorjd is not None:

return director_id

cursor = db.cursor()

cursor.execute("lNSERT INTO directors (name) VALUES (?)”,(director,))

db.commit()

return get_director_id(db, director)

这一函数返回给定发行者的ID,并在必要的时候插入新的发行者记录。如果某个记录被插入,我们首先尝试使用get_director_id()函数取回其ID。

def get_director_id(db, director):

cursor = db.cursor()

cursor.execute("SELECT id FROM directors WHERE name=?",(director,))

fields = cursor.fetchone()

return fields[0] if fields is not None else None

get_director_id()函数返回给定发行者的ID,如果数据库中没有指定的发行者,就返回None。我们使用fetchone()方法,因为或者有一个匹配的记录,或者没有。(我们知道,不会有重复的发行者,因为directors表格的名称字段有一个UNIQUE约束,在任何情况下,在添加一个新的发行者之前,我们总是先检査其是否存在。)这种取回方法总是返回一个字段序列(如果没有更多的记录,就返回None)。即便如此,这里我们只是请求返回一个单独的字段。

def edit_dvd(db):

title, identity = find_dvd(db, "edit")

if title is None:

return

title = Console.get_string("Title","title", title)

if not title:

return

cursor = db.cursor()

cursor.execute("SELECT dvds.year, dvds.duration, directors.name"

“FROM dvds, directors "

"WHERE dvds.director_id = directors.id AND "

"dvds.id=:id", dict(id=identity))

year, duration, director = cursor.fetchone()

director = Console.get_string("Director", "director", director)

if not director:

return

year = Console,get_integer("Year","year", year, 1896,datetime.date.today().year)

duration = Console.get_integer("Duration (minutes)", "minutes",

duration, minimum=0, maximum=60*48)

director_id = get_and_set_director(db, director)

cursor.execute("UPDATE dvds SET title=:title, year=:year,"

"duration=:duration, director_id=:directorjd "

"WHERE id=:identity", locals())

db.commit()

要编辑DVD记录,我们必须首先找到用户需要操纵的记录。如果找到了某个记录,我们就给用户修改其标题的机会,之后取回该记录的其他字段,以便将现有值作为默认值,将用户的输入工作最小化,用户只需要按Enter键就可以接受默认值。这里,我们使用了命名的占位符(形式为:name),并且必须使用映射来提供相应的值。对SELECT语句,我们使用一个新创建的字典;对UPDATE语句,我们使用的是由 locals()返回的字典。

我们可以同时为这两个语句都使用新字典,这种情况下,对UPDATE语句,我们可以传递 dict(title=title, year=year, duration=duration, director_id=director_id, id=identity)),而非 locals()。

在具备所有字段并且用户已经输入了需要做的改变之后,我们取回相应的发行者ID (如果必要就插入新的发行者记录),之后使用新数据对数据库进行更新。我们采用了一种简化的方法,对记录的所有字段进行更新,而不仅仅是那些做了修改的字段。

在使用DBM文件时,DVD标题被用作键,因此,如果标题进行了修改,我们就需要创建一个新的键-值项,并删除原始项。不过,这里每个DVD记录都有一个唯一性的ID,该ID是记录初次插入时创建的,因此,我们只需要改变任何其他字段的值, 而不需要其他操作。

def find_dvd(db, message):

message = "(Start of) title to " + message

cursor = db.cursor()

while True: .

start = Console.get_stnng(message, "title")

if not start:

return (None, None)

cursor.execute("SELECT title, id FROM dvds "

"WHERE title LIKE ? ORDER BY title”,

(start +"%",))

records = cursor.fetchall()

if len(records) == 0:

print("There are no dvds starting with", start)

continue

elif len(records) == 1:

return records[0]

elif len(records) DISPLAY_LIMIT:

print("Too many dvds ({0}) start with {1}; try entering "

"more of the title".format(len(records),start))

continue

else:

for i, record in enumerate(records):

print("{0}:{1}".format(i + 1, record[0]))

which = Console.get_integer("Number (or 0 to cancel)",

"number", minimum=1, maximum=len(records))

return records[which -1] if which != 0 else (None, None)

这一函数的功能与dvdsdbm.py程序中的find_dvd()函数相同,并返回一个二元组 (DVD标题,DVD ID)或(None, None),具体依赖于是否找到了某个记录。这里并不需要在所有数据上进行迭代,而是使用SQL通配符(%),因此只取回相关的记录。

由于我们希望匹配的记录数较小,因此我们一次性将其都取回到序列的序列中。如果有不止一个匹配的记录,但数量上又少到可以显示,我们就打印记录,并将每条记录附带一个数字编号,以便用户可以选择需要的记录,其方式与在dvds-dbm.py程序中所做的类似:

def list_dvds(db):

cursor = db.cursor()

sql = ("SELECT dvds.title, dvds.year, dvds.duration, "

"directors.name FROM dvds, directors "

"WHERE dvds.director_id = directors.id")

start = None

if dvd_count(db) DISPLAY_LIMIT:

start = Console.get_string("List those starting with [Enter=all]", "start")

sql += " AND dvds.title LIKE ?"

sql += ” ORDER BY dvds.title"

print()

if start is None:

cursor.execute(sql)

else:

cursor.execute(sql, (start +"%",))

for record in cursor:

print("{0[0]} ({0[1]}) {0[2]} minutes, by {0[3]}".format(record))

要列出每个DVD的详细资料,我们执行一个SELECT査询。该査询连接两个表,如果记录(由dvd_count()函数返回)数量超过了显示限制值,就将第2个元素添加到WHERE 分支,之后执行该査询,并在结果上进行迭代。每个记录都是一个序列,其字段是与 SELECT査询相匹配的。

def dvd_count(db):

cursor = db.cursor()

cursor.execute("SELECT COUNT(*) FROM dvds")

return cursor.fetchone()[0]

我们将这几行代码放置在一个单独的函数中,因为我们在几个不同的函数中都需要使用这几行代码。

我们忽略了 list_directors()函数的代码,因为该函数在结构上与list_dvds()函数非常类似,只不过更简单一些,因为本函数只列出一个字段(name)。

def remove_dvd(db):

title, identity = find_dvd(db, "remove")

if title is None:

return

ans = Console.get_bool("Remove {0}?".format(title), "no")

if ans:

cursor = db.cursor()

cursor.execute("DELETE FROM dvds WHERE id=?", (identity,))

db.commit()

在用户需要删除一个记录时,将调用本函数,并且本函数与dvds-dbm.py程序中 相应的函数是非常类似的。

到此,我们完全查阅了 dvds-sql.py程序,并且了解了如何创建数据库表格、选取 记录、在选定的记录上进行迭代以及插入、更新与删除记录。使用execute()方法,我们可以执行底层数据库所支持的任意SQL语句。

SQLite提供了比我们这里使用的多得多的功能,包括自动提交模式(以及任意其他类型的事务控制),以及创建可以在SQL查询内执行的函数的能力。提供一个工厂函数并用于控制对每个取回的记录返回什么(比如,一个字典或自定义类型,而不是字段序列)也是可能的。此外,通过传递“:memory:”作为文件名,创建内存中的SQLite 数据库也是可能的。

以上内容部分摘自视频课程05后端编程Python22 数据库编程,更多实操示例请参照视频讲解。跟着张员外讲编程,学习更轻松,不花钱还能学习真本领。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。