Python操作SQLite数据库
最后更新于:2022-04-01 16:06:18
### 连接数据库
从2.5版本开始,Python的标准库中就有了一个专门用于SQLite的sqlite3模块。连接SQLite数据库方式如下:
~~~
import sqlite3 as dbapi
con = dbapi.connect('population.db')
cur = con.cursor()
~~~
第一个语句用于引用数据库API;
第二个语句创建了一个到数据库的连接(connection):调用数据库模块的connect方法。该方法的参数是一个字符串,它定义了我们所要连接的那个数据库。由于SQLite是将整个数据库保存在磁盘上的某个文件中的,因此这里就是该文件的路径。如果该数据库不存在,就会直接创建出来;
第三个语句用于获取一个游标,它类似于文本编辑器中的光标,用于记录我们当前在数据库中的位置;当多个程序同时访问数据库时,该数据库可以知道谁在干什么。
**数据类型对比**
| SQLite | Python | 说明 |
|-----|-----|-----|
| NULL | NontType | 啥也不知道 |
| INTEGER | int或long | 整数 |
| REAL | float | 8字节浮点数 |
| TEXT | unicode或str | 字符串 |
| BLOB | buffer | 二进制数据(Binary Large OBject) |
### 操作数据库
现在我们就可以操作数据库了,我们将要执行的SQL语句放到一个字符串中,并告诉数据库去执行这个字符串,如下所示:
~~~
cur.execute('CREATE TABLE Student(Stuid TEXT, Age INTERGER, Name TEXT)')
cur.execute('INSERT INTO Student VALUES("00001", 20, "Lucy")')
cur.execute('INSERT INTO Student VALUES("00002", 21, "Lily")')
~~~
在将数据库插入到数据库或对数据库做了任何其他修改之后,我们必须通过连接的commit方法提交(commit)这些修改:
~~~
con.commit()
~~~
现在我们可以用如下方式来获取数据:
~~~
cur.execute('SELECT * FROM Student')
print(cur.fetchone())
print(cur.fetchall())
~~~
fetchone方法以**元组**的形式返回每条记录,其中各元素按查询所指定的顺序排列。如果不再有其他记录存在,则返回None。默认情况下,数据库中的TEXT是以Unicode字符串的形式返回的,我们可以告诉sqlite3以str的类型返回字符串:将连接的text_factory成员设置为类型str。
~~~
con.text_factory = str
~~~
fetchall方法的功能是以元组列表的形式返回查询所产生的全部数据。
一种较为快捷的插入方式:
~~~
ss = [("00003", 20, "David"), ("00004", 23, "Cneagle"),
("00005", 22, "qxzy")]
for s in ss:
cur.execute('INSERT INTO Student VALUES(?, ?, ?)', (s[0], s[1], s[2]))
con.commit()
~~~
这次execute的调用用到了两个参数,第一个是带有问号的SQL语句,这些问号是将要插入的值的占位符,第二个是由待插入值所组成的元组,数据库在执行该语句时,会用这些值从左到右地替换那些问号。
注意:
- SQL的数据类型与编程语言中的数据类型并不完全相同,因此在编写应用程序的时候很有必要在它们之间进行类型转换。
- 在被提交之前,对数据库做出的修改不会有任何效果。这保证了当数据库被两个以上的程序同时操作时,能够保持一致的状态。
Python图形用户界面
最后更新于:2022-04-01 16:06:16
tkinter是Python中可用于构建GUI的众多工具集之一。
# tkinter模块
~~~
# 可以使用import tkinter as tk并通过tk.thing去引用其中的内容
from tkinter import *
window = Tk()
window.mainloop()
~~~
以上代码可以显示一个空白的根窗口。可以将其看成是应用程序的最外层容器,创建其他插件(widget)的时候就需要用到它。如果关闭屏幕上的窗口,则相应的窗口对象就会被销毁。所有的应用程序都只有一个主窗口;此外,还可以通过TopLevel这个小插件来创建额外的窗口。
**tkinter小插件**包括Button, Canvas, Checkbutton, Entry, Frame, Label, Listbox, Menu, Message, Menubutton, Text, TopLevel等。
### 可变的变量
在Python中字符串、整数、浮点数以及布尔值都是不可变的,于是tkinter自带了一些类型;他们可以就地更新,并可以在其值发生变化时通知相关的插件。
**tkinter中的可变类型**
| 不可变类型 | 可变类型 |
|-----|-----|
| int | IntVar |
| string | StringVar |
| bool | BooleanVar |
| double | DoubleVar |
# 模型、视图、控制器
顾名思义,视图用于把信息显示给用户;模型则只是存储数据;控制器则可以更新应用程序的模型,并进而出发相应的视图发生变化。
如下例子实现点击按钮之后标签上的计数增加:
~~~
from tkinter import *
# The controller.
def click():
counter.set(counter.get() + 1)
if __name__ == '__main__':
# More initialization
window = Tk()
# The model.
counter = IntVar()
counter.set(0)
# The views.
frame = Frame(window)
frame.pack()
button = Button(frame, text='Click', command=click)
button.pack()
label = Label(frame, textvariable=counter)
label.pack()
window.mainloop()
~~~
### 使用Lambda
如果我们不仅希望能增加counter的值,还希望能降低它的值。则我们需要添加另一个按钮和另一个控制器函数。代码如下:
~~~
from tkinter import *
# The controller.
def click_up():
counter.set(counter.get() + 1)
def click_down():
counter.set(counter.get() - 1)
if __name__ == '__main__':
# More initialization
window = Tk()
# The model.
counter = IntVar()
counter.set(0)
# The views.
frame = Frame(window)
frame.pack()
button = Button(frame, text='Up', command=click_up)
button.pack()
button = Button(frame, text='Down', command=click_down)
button.pack()
label = Label(frame, textvariable=counter)
label.pack()
window.mainloop()
~~~
上述实现代码看起来有点傻,`click_up`和`click_down`做的事情看起来几乎是一样的,应该将它们合成一个。这时,我们应该显示的把counter传递给函数,而不是使用全局变量。
~~~
# The model.
counter = IntVar()
counter.set(0)
# One controller with parameters
def click(variable, value):
varaible.set(variable.get() + value)
~~~
tkinter要求由按钮(以及别的插件)出发的控制器函数不能含有参数,目的就是为了以同一种方式去调用它们。我们要做的事情就是:对这个带有两个参数的函数进行处理,使其变成一个不带参数的函数。
一个好一点的做法是使用lambda函数,它使我们能够创建一个没有名字的单行函数。
~~~
from tkinter import *
window = Tk()
# The model
counter = IntVar()
counter.set(0)
# General controller.
def click(var, value):
var.set(var.get() + value)
# The views.
frame = Frame(window)
frame.pack()
button = Button(frame, text='Up', command=lambda: click(counter, 1))
button.pack()
button = Button(frame, text='Down', command=lambda: click(counter, -1))
button.pack()
label = Label(frame, textvariable=counter)
label.pack()
window.mainloop()
~~~
这段代码分别为两个按钮创建了一个不带参数的lambda函数,这两个lambda函数会将正确的值传进click。
# 样式
~~~
from tkinter import *
window = Tk()
# 字体
button = Button(window, text='hello', font=('Courier', 14, 'bold italic'))
# 布局
button.pack(side='left')
# 颜色
label = Label(window, text='hello', bg='green', fg='white')
label.pack()
window.mainloop()
~~~
控制布局,就可以使用pack,也可以使用grid,但是不能两者都用。
~~~
from tkinter import *
window = Tk()
button = Button(window, text='button1', font=('Courier', 14, 'bold italic'))
button.grid(row=0, column=0)
label = Label(window, text='label1', bg='green', fg='white')
label.grid(row=0, column=1)
label = Label(window, text='label2', bg='green', fg='white')
label.grid(row=1, column=1)
window.mainloop()
~~~
可以使用rowspan和columnspan设置插件所占据的行数,默认为1。
# 面向对象的GUI
几乎所有真实的GUI都是以类和对象来建造的:他们讲模型、视图和控制器一起放到一个干净整洁的包(package)中。例如下面的计数器函数,其模型是Counter类的一个名为`self.state`的成员变量,其控制器是`upClick`和`quitClick`方法。
~~~
from tkinter import *
class Counter:
'''A simple counter GUI using object-oriented programming.'''
def __init__(self, parent):
'''Create the GUI.'''
# Framework.
self.parent = parent
self.frame = Frame(parent)
self.frame.pack()
# Model.
self.state = IntVar()
self.state.set(1)
# Label displaying current state.
self.label = Label(self.frame, textvariable=self.state)
self.label.pack()
# Buttons to control application.
self.up = Button(self.frame, text='up', command=self.upClick)
self.up.pack(side='left')
self.right = Button(self.frame, text='quit', command=self.quitClick)
self.right.pack(side='left')
def upClick(self):
'''Handle click on 'up' button.'''
self.state.set(self.state.get() + 1)
def quitClick(self):
'''Handle click on 'quit' button.'''
self.parent.destroy()
if __name__ == '__main__':
window = Tk()
myapp = Counter(window)
window.mainloop()
~~~
参考资料:
《Python编程实践》
《Practical Programming An Introduction to Computer Science Using Python》
Python面向对象编程
最后更新于:2022-04-01 16:06:13
### Color类
从一个非常简单的类定义开始:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
pass
~~~
关键字def用于告诉Python我们定义了一个新函数,关键字class则表明我们定义了一个新类。(object)这部分内容说的是,类Color是一种对象;文档字符串描述了Color对象的功能,pass则说明该对象是空白的(即为存放任何数据,也没有提供任何的新操作)。使用方式如下:
~~~
>>> black = Color()
>>> black.red = 0
0
>>> black.green = 0
0
>>> black.blue = 0
0
~~~
### 方法
根据定义,颜色亮度就是其最强和最弱的RGB值得平均值对应到0和1之间的那个数值。若写成函数,如下所示:
~~~
def lightness(color):
'''Return the lightness of color.'''
strongest = max(color.red, color.green, color.blue)
weakest = min(color.red, color.green, color.blue)
return 0.5 * (strongest + weakest) / 255
~~~
若将函数`lightness()`作为Color类的一个方法,如下所示:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def lightness(self):
'''Return the lightness of color.'''
strongest = max(self.red, self.green, self.blue)
weakest = min(self.red, self.green, self.blue)
return 0.5 * (strongest + weakest) / 255
~~~
需要移除参数color,并将其替换成self参数。当Python在调用某个对象中的某个方法时,会自动将该对象的引用作为该方法的第一个参数传进去。这就意味着,当我们调用lightness时,完全不需要给它传递任何参数。使用方式如下:
~~~
>>> purple = Color()
>>> purple.red = 255
>>> purple.green = 0
>>> purple.blue = 255
>>> purple.lightness()
0.5
~~~
**定义一个方法的时候,除了实际需要传入的那些参数之外,还必须再多写一个。相反,在调用某个方法的时候,实际提供的参数要比该方法定义中所需的少一个。**
### 构造器
给Color类添加一个当创建新Color的时候就会被执行的方法。这种方法叫做构造器(constructor);在Python中,构造器就是__init__:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def __init__(self, r, g, b):
'''A new color with red value r, green value g, and blue value b. All
components are integers in the range 0-255.'''
self.red = r
self.green = g
self.blue = b
~~~
名称两边的双下划线说明该方法对Python有着特殊的意义——这里的意思就是说,创建新对象的时候,该方法就会被调用。
~~~
purple = Color(128, 0, 128)
~~~
### 特殊方法
当需要从某个对象得到一段简单易懂的信息时,就会调用__str__;当需要这段信息更准确时,则会调用__repr__。在使用print时,__str__就会被调用。为了得到有意义的输出,现在来写个`Color.__str__`:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def __init__(self, r, g, b):
'''A new color with red value r, green value g, and blue value b. All
components are integers in the range 0-255.'''
self.red = r
self.green = g
self.blue = b
def __str__(self):
'''Return a string representation of this Color in the form of an RGB tuple.'''
return'(%s, %s, %s)' %(self.red, self.green, self.blue)
~~~
Python中还有很多特殊方法:Python的官方网站上给出了完成的列表。其中就有__add__、__sub__、__eq__等,它们分别在我们用“+”对对象做加法,用“-”对对象做减法、用“==”对对象做比较的时候调用:
~~~
class Color(object):
'''An RGB color,with red,green,blue component'''
def __init__(self, r, g, b):
'''A new color with red value r, green value g, and blue value b. All
components are integers in the range 0-255.'''
self.red = r
self.green = g
self.blue = b
def __str__(self):
'''Return a string representation of this Color in the form of an RGB tuple.'''
return'(%s, %s, %s)' %(self.red, self.green, self.blue)
def __add__(self, other_color):
'''Return a new Color made from adding the red, green and blue components
of this Color to Color other_color's components. If the sum is greater than
255, the color is set to 255'''
return Color(min(self.red + other_color.red, 255),
min(self.green + other_color.green, 255),
min(self.blue + other_color.blue, 255))
def __sub__(self, other_color):
'''Return a new Color made from subtracting the red, green and blue components
of this Color to Color other_color's components. If the difference is less than
255, the color is set to 0'''
return Color(min(self.red - other_color.red, 0),
min(self.green - other_color.green, 0),
min(self.blue - other_color.blue, 0))
def __eq__(self, other_color):
'''Return True if this Color's components are equal to Color other_color's components.'''
return self.red == other_color.red and self.green == other_color.green \
and self.blue == other_color.blue
def lightness(self):
'''Return the lightness of color.'''
strongest = max(self.red, self.green, self.blue)
weakest = min(self.red, self.green, self.blue)
return 0.5 * (strongest + weakest) / 255
~~~
这些方法的具体用法:
~~~
purple = Color(128, 0, 128)
white = Color(255, 255, 255)
dark_grey = Color(50, 50, 50)
print(purple + dark_grey)
print(white - dark_grey)
print(white == Color(255, 255, 255))
~~~
可以使用`help(Color)`获取有关Color类的帮助信息:
~~~
Help on Color in module __main__ object:
class Color(builtins.object)
| An RGB color,with red,green,blue component
|
| Methods defined here:
|
| __add__(self, other_color)
| Return a new Color made from adding the red, green and blue components
| of this Color to Color other_color's components. If the sum is greater than
| 255, the color is set to 255
|
| __eq__(self, other_color)
| Return True if this Color's components are equal to Color other_color's components.
|
| __init__(self, r, g, b)
| A new color with red value r, green value g, and blue value b. All
| components are integers in the range 0-255.
|
| __str__(self)
| Return a string representation of this Color in the form of an RGB tuple.
|
| __sub__(self, other_color)
| Return a new Color made from subtracting the red, green and blue components
| of this Color to Color other_color's components. If the difference is less than
| 255, the color is set to 0
|
| lightness(self)
| Return the lightness of color.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
~~~
### 小结
- 在面向对象编程语言中,定义新类型的手段是:创建新类。类支持封装,换句话说,类将数据以及相关的操作放在一起,以便使程序的其他部分可以忽略相关的实现细节。
- 类还支持多态。如果两个类拥有相同用法的方法,则他们的实例可以互相替换,且不会影响到程序的其他部分。这就意味着我们能够进行“即插即用型”编程,即代码能够根据所处理的具体类型而执行不同的操作。(多态的意思就是说,某个含有变量的表达式可以根据该变量所引用的对象的实际类型得到不同的结果。)
- 新类还可以通过“继承现有类”的方式来进行定义:`class child(parent)`。系类不仅可以重写父类的功能特点,而且还可以添加新的功能特点。
- 当方法被定义在类中时,其第一个参数必须是一个特殊的变量,该变量表示的是调用该方法的那个对象。按照惯例,这个参数成为self。
- 在Python中,部分方法拥有着特殊的预定义含义:为了有所区别,他们的名称以双下划线开头和结尾。在这些方法中,有的在构造对象时调用(__init__),有的在将对象转换为字符串时调用(__str__和__repr__),有的则用于模拟算数运算(比如__add__和__sub__)。
Python常用函数
最后更新于:2022-04-01 16:06:10
# 常用的字符串方法
| 方法 | 说明 |
|-----|-----|
| capitalize() | 返回首字母的大写副本 |
| find(s) | 返回字符串中首次出现参数s的索引,如果字符串中没有参数s则返回-1 |
| find(s,beg) | 返回字符串中索引beg之后首次出现参数s的索引,如果字符串中索引beg之后没有参数s则返回-1 |
| find(s,beg,end) | 返回字符串中索引beg与end之间首次出现参数s的索引,如果字符串中索引beg和end之间没有参数s则返回-1 |
| islower() | 测试所有字符是否均为小写形式 |
| isupper() | 测试所有字符是否均为大写形式 |
| lower() | 将所有字符穿华为小写形式并返回 |
| replace(old,new) | 将字符串中所有子串old替换为new并返回 |
| split() | 将空格分隔的单词以列表的形式返回 |
| split(del) | 将del分隔的子串以列表的形式返回 |
| strip() | 删除字符串两端的空白符并返回 |
| strip(s) | 删除字符串中的s并返回 |
| upper() | 将所有字符串转化为大写形式并返回 |
# 列表函数
| 函数 | 说明 |
|-----|-----|
| len(L) | 返回列表L中的元素数量 |
| max(L) | 返回列表L中的最大值 |
| min(L) | 返回列表L中的最小值 |
| sum(L) | 返回列表L中所有元素的和 |
# 列表方法
| 方法 | 说明 |
|-----|-----|
| L.append(v) | 将值v添加到列表L中 |
| L.insert(i,v) | 将值v插入到列表L的索引i处,同时将其后的元素往后移以便腾出位置 |
| L.remove(v) | 从列表L中移除第一次找到的值v |
| L.reverse() | 反转列表L中的值的顺序 |
| L.sort() | 队列表L中的值以升序排序(字符串以字母表顺序为准) |
| L.pop() | 移除并返回列表L的最后一个元素(该列表不得为空) |
# 集合运算及运算符
| 方法 | 运算符 | 说明 |
|-----|-----|-----|
| add | | 往集合中添加一个元素 |
| clear | | 移除集合中的所有元素 |
| difference | - | 根据一个集合中不存在于另一个集合中的元素,创建中一个新的集合 |
| intersection | & | 根据两个集合中共有的元素,创建出一个新的集合 |
| issubset | <= | 判断一个集合的所有元素是否都包含于另一个集合 |
| issuperset | >= | 判断一个集合是否包含了另一个集合中的所有元素 |
| remove | | 移除集合中的一个元素 |
| symmetric_difference | ^ | 根据两个集合中所有不存在于对方的元素,创建出一个新的集合 |
| union | | 根据两个集合中所有的元素,创建出一个新的集合 |
# 字典
| 方法 | 说明 |
|-----|-----|
| clear | 清空字典内容 |
| get | 返回关键字所关联的值,如果指定键不存在,则返回默认值 |
| keys | 以列表的形式返回字典中的所有键。所得列表中的每个条目肯定是唯一的 |
| items | 返回(key,value)列表 |
| values | 以列表的形式返回字典中的所有值。所得列表中的每个条目不一定是唯一的 |
| update | 用另一个字典的内容对当前字典进行更新 |
附录:
~~~
def find_two_smallest(L):
'''Return a tuple of the indices of the two smallest values in list L'''
if L[0] < L[1]:
min1,min2 = 0,1
else:
min1,min2 = 1,0
for n in range(2,len(L)):
if L[n] < L[min1]:
min2 = min1
min1 = n
elif L[n] < L[min2]:
min2 = n
return (min1,min2)
def linear_search(L,v):
'''Return the index of the first occurrence of v in list L, or return len
if v is not in L'''
for i in range(len(L)):
if L[i] == v:
return i
return len(L)
def selection_sort(L):
'''Reorder the values in L from smallest to largest.'''
i = 0
while i != len(L):
smallest = find_min(L, i)
L[i],L[smallest] = L[smallest],L[i]
i += 1
def find_min(L,b):
'''Return the index of the smallest value in L[b:].'''
smallest = b # The index of the smallest so far.
i = b + 1
while i != len(L):
if L[i] < L[smallest]:
smallest = i
i += 1
return smallest
def insertion_sort(L):
'''Reorder the values in L from smallest to largest.'''
i = 0
while i != len(L):
insert(L, i)
i += 1
def insert(L, b):
'''Insert L[b] where it belongs in L[0:b+1];
L[0:b-1] must already be sorted'''
i = b
while i != 0 and L[i-1] > L[b]:
i -= 1
value = L[b]
del L[b]
L.insert(i, value)
~~~
Python文件处理
最后更新于:2022-04-01 16:06:08
# 读取文件
### 本地文件
~~~
input_file = open('note.txt','r')
for line in input_file:
line = line.strip() #去除前后空格
print(line)
input_file.close()
~~~
若将其改为函数形式:
~~~
#filename.py
import sys
def process_file(filename):
'''Open, read, and print a file.'''
input_file = open(filename,'r')
for line in input_file:
line = line.strip()
print(line)
input_file.close()
if __name__ == '__main__':
process_file(sys.argv[1])
~~~
在命令行运行该文件,输入如下命令:
~~~
python filename.py test.txt
~~~
命令中的`test.txt`对应于`sys.argv[i]`。
### 互联网上的文件
~~~
# coding=utf-8
import urllib.request
url = 'http://www.weather.com.cn/adat/sk/101010100.html'
web_page = urllib.request.urlopen(url)
for line in web_page:
line = line.strip()
print(line.decode('utf-8')) #加上decode函数才能显示汉字
web_page.close()
~~~
输出结果:
~~~
{"weatherinfo":{"city":"北京","cityid":"101010100","temp":"9","WD":"南风","WS":"2级","SD":"26%","WSE":"2","time":"10:20","isRadar":"1","Radar":"JC_RADAR_AZ9010_JB","njd":"暂无实况","qy":"1014"}}
~~~
若是在命令行运行该文件,输入如下命令:
~~~
python filename.py
~~~
# 写入文件
再打开文件时,除了需要制定文件名外,还需要制定一个模式(“r”,”w”,”a”,分别对应于读取、写入、追加)。如果没有制定模式,则应用默认模式”r”。当以写入模式打开文件且该文件尚不存在时,就会创建出一个相应的新文件。
例如,将“Computer Science”放到文件test.txt中:
~~~
output_file = open('test.txt','w')
output_file.write('Computer Science')
output_file.close()
~~~
一个同时具有读取和写入功能的事例,从输入文件的每一行读取两个数字,在另外一个文件中输出这两个数字以及它们的和。
~~~
#test.py
def mysum(input_filename, output_filename):
input_file = open(input_filename,'r')
output_file = open(output_filename,'w')
for line in input_file:
operands = line.split()
sum_value = float(operands[0]) + float(operands[1])
new_line = line.rstrip() + ' ' + str(sum_value) + '\n'
output_file.write(new_line)
output_file.close()
~~~
`rstrip()`函数用于去掉输入文件每行的换行符。
函数调用:
~~~
from test import *
mysum('test.txt', 'test2.txt')
~~~
Python开发环境搭建
最后更新于:2022-04-01 16:06:06
### Python下载及安装
下载地址:[https://www.python.org/downloads/](https://www.python.org/downloads/)
双击下载文件进行安装,安装时选中`Add python.exe to Path`即可。
### Eclipse下载
下载地址:[http://www.eclipse.org/downloads/](http://www.eclipse.org/downloads/)
解压下载的压缩包
### 在Eclipse中安装PyDev插件
- 使用Eclipse安装插件,打开eclipse,进入Help—>Install New Software,输入[http://pydev.org/updates](http://pydev.org/updates),全选后点击Next,进行在线安装,安装完成会提示重启eclipse。
- 直接下载PyDev插件,解压后,将plugins和features目录下的文件分别复制到Eclipse的plugins和features目录下。重启Eclipse就OK了。
### 配置Python Interpreters
打开eclipse,进入Window—>Preferences,选择PyDev—>interpreters—>Python interpreters,在右侧点击Quick Auto-Confing,自动搜索,点击OK,完成配置。
至此,配置完成,可以开始创建PyDev Project。
前言
最后更新于:2022-04-01 16:06:03
> 原文出处:[Python入门学习](http://blog.csdn.net/column/details/enjoypython.html)
作者:[foreverling](http://blog.csdn.net/foreverling)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
# Python入门学习
> Python学习笔记,与各位分享!