https://pypi.python.org/pypi #模块网站
#!/usr/bin/env python #在环境变量env中找Python
#coding: utf8
1.自动补全
配置环境: 创建以下文件
vim /usr/local/bin/tab.py
输入:
import readline
import rlcompleter
readline.parse_and_bind('tab:complete')
存储后设置 SPYTHONSTARTUP
vim ~/.bash_profile 增加以下内容
再最后的export PATH前加
PYTHONSTARTUP=/usr/local/bin/tab.py
export PATH PYTHONSTARTUP
保存后修改可执行权限
chmod +x /usr/local/bin/tab.py
source ~/.bash_profile(马上生效)
验证
echo SPYTHONSTARTUP(有值即可)
补全
#source /python_note/tab.sh 即可
关键字查询: improt keyword
keyword.kwlist
循环获取 I %s %(ine for line in data)
思路: 根据功能分函数,函数先写框架
cmp 比较大小
list('abcd') >>>['a','b','c','d']
int 可转进制 int('10',base=2) base指定进制数
abs 返回绝对值
divmod(10,3) >>>(3,1) 可得商和余
pow 指数运算,即几次方
round 四舍五入 round(5.0/3,2)
hex 16进制数
oct 8进制
bin 2进制
ord ACCII码
chr 转为ACCII编码
range(5) 生成0~5的列表
from random improt randint
randint(1,100) 随机生成一个(1,100)内的数
enumerate 返回元组(下标,元素) 用list(enumerate(1,2))
reversed (反转序列) 也可 [::-1]
sorted 排序
string.letters (字母大小写列表)
string.digits (数字列表)
%15s%5s%('name','ager') 格式对齐
%-15s%-5s%('name','ager')左对齐
%s%s%(-10,'name',-5,'ager') *占位 -10和-5
string.centen(48) 居中字符串
string.capitalize() 首字母大写
string.ljust(40,#) 左对齐
string.rjust(40,#)右对齐
string.count('l') 统计l出现次数
string.endswith('o') 是否以O结尾
string.startswith('e') 是否e开头
string.islower 是否小写,有任一大写则返回flase
string.isupper 是否大写,有任一小写则返回flase
string.isdigit 是否数字
string.isacpha 是否字母
string.isalnum 是否数字和字母
string.strip 去除字符串两端的空白,可加参数去除指定
string.strip('!') 去除两端!字符串,不去除中间
string.lstrip() 去除左端空白
string.rstrip() 去除右端空白,
** string.rstrip('\r\n') 去除右端\r,\n,\r\n
string.vpper 小写转大写
string.sqlit('.') 以.切割字符串,返回列表
string.replace('o','a') 把o替换为a
improt subprocess 执行系统命令模块
subprocess.call('ls -l /home',shell=True)
string.Template() 字符串模块
data=f.read().decode('gb1803')
f.write(date.encode('utf8'))
列表切片增加:
alist=[10,11,12,13,'zh','li',30]
alist[5:5]=['ww','zl'] (列表中间插入)
alist=[10,11,12,13,'zh','ww','zl','li',30]
列表删除
del alist[-1] 删除最后一项
alist.pop() 删除最后一项并返回删除项
alist.pop(3) 删除下标3的项
alist.remove(12) 根据值删除,相同值时只删第一个
alist.count(10) 统计10出现次数
alist.extend() 拆分元素增加
alist.index('new') 返回元素的下标,多个时只返回第一个,无则报错
alist.insert(0,200) 向下标0插入200
alist.reverse() 反转列表
alist.sort() 排序,默认升序排列
random.shuffle(alist) 打乱排序
alist.sort(reversed=True) 排序时反转
alist.len() 获取长度
alist.max() 获取最大值
alist.min() 最小值
字符串拼接
str_list=['h','e','o']
'.'.join(str_list) #以.号连接
输出'h.e.o'
多用列表,效率高
字典
adict['name'] 字典访问
for key in adict:
print "%s:%s" %(key,adict[key]) 字典循环
"(name)s:%(age)s"% adict 获取值
adict.pop(key) 弹出健
adict.popitem() 随机弹
adict.setdefault('mail','bobcatudo') 有则不变更
adict.keys() 返回健
adict.values() 返回值
adict.items() 返回健和值
adict.update(bdict) 字典相加
多if 判断多个条件时某些值时用字典
cmds = {'0':push_it,'1':pop_it,'2':view_it}
choice=raw_input(prompt).strip()[0] #去掉输入的空格并获取第一个值
cmds[choice]() #用字典匹配获取对应的值得调用函数
元组
tuple()
创建单元组时要在后面加,
a=('10',)
元组不可变,但元组中的列表可以变
atuple=(1,[],2)
atuple[1].append(10)
atuple[1].append(20)
结果是 atuple=(1,[10,20],2)
max() 返回最大
mint() 返回最小
alist=['hello','word']
enumerate(alist) 返回函数对象
list(enumerate(alist))
集合: 集合可以去重 set(['1','2'])
判断: big=x if x>y else y
生成器表达式:不真正创建列,返回一个生成器,使用时才生成
(expr for iter_var in iterable if (ond_expr))
print "\r" # \r不换行,后面加,连接。
%c 数字转化为ACCII
%s 先转化为字符串后
%d 整数类型,只留整数
% d 前面留空格兼容负数
%05d 前面空格补0
%+5d 正数前面显示+号
%f 浮点数
%5.3f 宽度为5,小数为3位
%i int
%e 科学计数法
%o 8进制数
%#o 显示前缀
花括号格式化
" {} is {} yesas old".format('bob','23')
推荐用花括号格式化
" {0[0]} is {0[1]} yesas old".format(alist)
第一列左对齐宽度为8,第二列为宽度5左对齐,<左对齐, >有对齐
" {0:8s} is {1:<5d} yesas old".format('bob','23')
字符串模版
ori_txt='HI ${name},I WILL SEE YOU ${day}'
t=string.Template(ori_txt)
t.substitute(name='bob',day='tomorrow')
调用系统命令建议使用 subprocess
subprocess.call('ls /home', shell=True)
字典:{} 花括号,无序。
dict工厂函数dict((['name','bob'],['age','23'],['email','bob@qq.com']))
{}.fromkeys(('tom','bob','alice'),7) #值固定为7时可以批量创建
输出:{'bob':7,'alice':7,'tom':7}
adict['key'] 访问字典
adict.pop['key'] 删除字典
del adict['key'] 删除字典
adict.popitem() 随机删除值并返回删除的值
adict.clear 清除字典
adict ={'age':7,'name':'bob'}
'%(name)s:%(age)s' % adict
a=adict.copy() 深复制,值互不影响
clist=alist[:] 列表复制,值互不影响
adict.get('key') 取出值,不存在返回none
adict.get('key',23) 取出值,不存在返回23
adict.get('key','nout found') 取出值,不存在返回not found
adict.setdefault('age',20) 设置值,存在则不改变.
adict.keys() 获取key的列表
adict.items() 获取值和key的列表
adict.values()获取值的列表
bdict={'age':23,'name':'bob','emil':'qq@ww.com'}
{value:key for key,value in bdict.items()} #key和value对换,注意value有相同值时会丢项目
adict.update(bdict) 更新字典,可以把bdict合并到adict里
隐藏密码输入
import getpass
getpass.getpass("password")
集合
aset= set ('abc')
bset= set ('cde')
aset & base 等于 set([c]) 交集
aset | base 等于 set([a b c d e]) 交集
aset - bset 等于 set ([a b]) 差补,即a里有,b里没有,可以做2个文件的比较差异。
set.add() 添加成员
set.remove() 移除成员
set.update() 批量添加成员
批量执行命令,判断每一个语句结果
commands = [
'mkdir /tmp/adb',
'echo hello > /tmp/abc/myfile.txt',
'cat /tmp/abc/myfile.txt'
]
def fun0():
def fun1():
def fun2():
func_dict = {0:func0,1:func1,2:func2}
for i in range(len(commands)):
ret_val=subprocess.call(commands[i],shell=True)
if ret_val !=0:
fun_dict[i]()
break
迭代器
myiter= iter('abc')
myiter.next()
到最后会报错
for 循环可以便利所有类型。
生成器表达式,使用时才生成,节省内存
('172.168.1.%s' %s i for i in range(1,255))
文件处理
.readline() #以/n 结束为一行
flush() 立即同步到文件
\r #回车不换行,即在同一行中
os
os.sep # /
os.curdir #.
os.pardir #..
os.linesep #\n
os.mknod('test.txt') #创建空文件
os.symlink('/etc/host','zhuji') #快捷方式
os.chmod('test.txt',0644) #0代表8进制,需写。
cPickle(c语言写的,数度快),Pickle模块 存储对象类型,方便取出。
adict={'name':'bob'}
f=open('/tmp.tx','w')
cPickle.dump(adict,f) #保存字典到文本
cPickle.load(f) #读取文件中的数据
错误:
keyboardinterrupt :用户中断执行
EOFError :没有内健输入,到达EOF标记 ,
IOError :输入输出操作失败
分析可能产生异常的位置再加try
一个try 可以有多个
except 如:
except (keyboardinterrupt,eoferror) #多个错误类型用()包含
except(valueError)
except valueerror ,e : # e保存错误信息
BaseException 所有异常
keyboardinterrupt #用户中断 即ctrl+c 取消
eoferror 没有内健输入 即ctrl+d
IOError 输入/输出操作失败 ,打开不存在的文件
try:
except:
else: #没报错才执行
finally: #都执行
with 可以简化代码
如:
with open('/etc/fstab') as fs:
print fs.readline()
不必用fs.clock 关闭邮件
定义异常
if not 0 <age<150:
raise ValueError , "age out of rang" #必须为已知异常
断言异常
assert 0<age<150 ,"age out of rang" #不在0和150之间,就弹异常
fun()
b=fun #等于b引用fun的空间
def fun (age,name='bob') #默认参数=需放后面
print '%s:%s' (name,age)
函数参数组
def get_args(*arge)
print args
get_args(10,20,30)
def get_kwargs(**kwargs): #字典接受数据
print jiejiw
get_kwargs(name='jj',age=23)
info=['bob',23]
get_info(*info) #代表传入列表的2个参数
info_dict={'name':'bob','aee':34}
get_info(**info_dict) #拆开字典,传入值
choice('+-') 随机选择一项
匿名函数
a= lambda x,y:x+y #定义匿名函数
a(20,30)
字典使用匿名函数
mcds={'+': lambda x,y:x+y,'-':lambda x,y:x-y}
num_list=[randint(1,100) for i in range(10)]
filter(函数,序列) ,函数或许序列的作为参数,函数结果为真保留,为假过滤
print filter(lambda x:x%2,num_list)
map(lambda x:x*2,num_list) #获取序列的值
reduce(lambda x,y:x+y,num_list) #统计序列中的和,将第一个序列和第二个相加,结果在和第三个相加
vim 自动缩进
set ai
时间
data=time.strftime("%Y-%m-%d")
检查文件
md5sum
global #定义全局变量
偏函数
def add(x,y):
return x+y
import functools
add10=functools.partial(add,10) #可以固定X值的模式,第一个参数时函数,第二个参数没指定y=10时,按顺序赋值
add10(3) #等于13
递归
例子:排序 ,弹出列表最后一个值和列表每项比较,小的放小列表,大的放大列表,最后放回 小+弹出的值+大,如果列表为空或1时,返回列表
def sou(alist):
if len(alist) == 0 or len(alist) == 1:
return alist
num = alist.pop()
l = []
m = []
for i in alist: if i < num: l.append(i) else: m.append(i)return sou(l) + [num] + sou(m)
if name == 'main':
alist = [random.randint(1, 100) for i in range(10)]
print alist
print sou(alist)
闭包
若内部变量想在内部的内部可以使用,则需为可变对象
def count(start=0):
count=[start]
def incr():
counter[0]+=1
return counter[0]
return incr #闭包返回的是函数
if name=='main':
a=count()
b=count(10)
print a()
print a()
print b()
装饰器
mport time
def deco(fun):
def timeit():
start=time.time()
ret_val=fun()
end=time.time()
return ret_val,end-start
return timeit #放回函数
@deco #装饰器,将loop当deco的参数运行
def loop():
result=[]
for i in range(1,11):
result.append(i)
time.sleep(0.3)
return result
if name == 'main':
print loop()
hashlib 模块,作文件校验。
m=hashlib.md5('hello world!')
m.hexdigest()
tarfile 直接访问tar文件
tar=tarfile.open('2.tar.gz','w:gz') #创建tar文件
tar.add('day01') #压缩文件
tar.close()
tar=tarfile.open('day01.tar.gz','r:') #自动识别压缩方式
tar.extractall('/tmp/') #指定解压位置
os.walk 获取文件夹下文件列表
for path,foler,files in os.walk('/etc/')
for each_file in files:
os.path.join(path,each_file)
testcase/增量备份.py
class ClassName(object): #object 是基类或父类
count=0
ClassName.count #引用类
mc=ClassName()
mc.count
mc.name='tom'
mc.dist
name:tom 只显示实例的属性
构造器函数
init 调用类时,先执行
class MyClass(object):
def init(self,name): #绑定方法,需先实例化才能调用,self是变量名,可自己设,如下a=..
self.name=name #实例的属性,外部需调用此属性时,要绑定此属性
def display_name(self):
print name #显示bob
if name=='main':
a=MyClass('bob') #实例对象化对象时,会把实例对象传给self, 即a给self,因此只传一个参数即可
print a.name # 显示bob
a.display_name()
b=MyClass('alice')
b.display_name()
绑定方法
class Hotel(object):
def init(self,room,cf=1.0,bf=15):
self.room=room
self.cf=cf
self.bf=bf
def calc_all(self,days=1):
return (self.roomself.cf+self.bf) days
if name == 'main':
stroom=Hotel(200)
print stroom.calc_all()
print stroom.calc_all(2)
bigroom=Hotel(300)print stroom.calc_all()print stroom.calc_all(2)#非绑定方法print Hotel.calc_all(stroom)
继承类:
addbook.py
class AddrBook(object):
def init(self,name,phone):
self.name=name
self.phone=phone
def get_phone(self):
return self.phone
def updata_phone(self,newphone): self.phone=newphone print '%s updata phone %s' %(self.name,self.phone)
if name == 'main':
bob=AddrBook('bob','1333333')
alis=AddrBook('alis','144444')
print bob.get_phone()
bob.updata_phone('155555')
print bob.get_phone()
email.py
import addbook
class EmplAddrBook(addbook.AddrBook): #继承上一个类
def init(self,name,phone,email):
addbook.AddrBook.init(self,name,phone)
super(EmplAddrBook,self).__init__(name,phone) #super 方法继承 self.email=emaildef get_email(self): return self.email
dict((['name','bob'],['age','23'],['email','bob@qq.com']))
br/>tom=EmplAddrBook('tom','13666','tom@de.cn')<br <="" a="">print tom.get_phone()
print tom.get_email()
父类和子类有同名方法时,会调用子类
tom=EmplAddrBook('tom','13666','tom@de.cn')
if name == 'main':bob=AddrBook('bob','1231332','bob@tt')
多重继承
class A(object):
def get_name(self):
print 'in a'
def start(self):
print '' 20
class B(object):
def display_name(self):
print 'in b'
def start(self):
print '#' * 20
class C(A,B):
pass
if name == 'main':
c=C()
c.display_name() #继承所有父类的方法
c.get_name()
c.start() #先在A中查找,有就打印了
issubclass(B,A) #判断B是否A的子类
isinstance(b,B) #判断b是否B的实例
hasattr() #判断一个对象是否另一个特定的属性
getattr() #获得一个对象的属性
setattr() #设置一个对象的属性
delattr() #删除一个对象的属性
私有化
class A(object):
def init(self):
self.name='bob' #开头的是私有化
def get_name(self):
return self.__name
a =A()
a.get_name()
class Books(object):
def init(self,title,author):
self.title=title
self.author=author
def str(self): #字符串初始化,比下面更易读
return self.title
def repr(self):
return self.title #字符串初始化,
def call(self): #方法调用
print '%s is jiw %s'%(self.title,self.author)
if name == 'main':
py_book=Books('sss','wew')
print py_book
py_book()
正则:
. 匹配任意字符
[..x-y..] 匹配字符组里的任意字符
[^..x-y..] 匹配不再字符组里的任意字符
\d 匹配任意数字【0-9】
\D 非数字字符
\w 匹配任意数字字母下划线 【0-9a-zA-Z】
\W 非数字字母下划线
\s 匹配空白字符【\r\v\f\t\n】
\S 非空白字符
literal 匹配字符串的值
re1|rel2 匹配re1或re2
匹配前面出现的零次或多次
匹配前面出现的一次或多次
? 匹配前面出现的零次或一次
{M,N} 匹配前面出现至少M次,最多N次
^ 匹配字符串的开始
$ 匹配字符串的结尾
\b 匹配字符串的边界 #egrep '\btom\b' ,只匹配 tom
() 对正则表达式分组
\nn 匹配已保存的子组
import re
a=re.match('查找内容','查找目标') #正则查找,但只匹配开始,隐含有^
re.search('查找内容','查找目标') #正则查找,仅匹配一个
a.group() #获取查找内容
c=re.findall('the','apple the,teh the 22') #查找所有,结果放入列表,可以直接输出
print c
c=re.finditer('the','apple the ,teh the 22') #返回一个迭代器对象
for i in c:
print i.group() #打印迭代器内容
IP地址正则表达式
([0-9]{1,3}.){3}[0-9]{1,3}
MAC地址匹配加符号
%/(..)(..)(..)(..)$/\1:\2:\:3\/g
complie 大量匹配时用,可以提高效率
patt=re.compile('foo')
m=patt.match('food')
print m.group()
split 分隔符切割
mylist=re.split('.|-','hello-world.data')
print mylist
import re
z='firefox'
dica={}
data=open('access_log')
for i in data:
m=re.search(z,i)
if m:
ip=m.group()
dica[ip]=dica.get(ip,0)+1
print dica
sub
re.sub() #替换某一个字符
re.sub('X','MR','Hi X ,nice to meet you')
data='my phone number is :1588888696'
m= re.search('.+(\d+)',data)
print m.groups() #获取了()里的值
贪婪匹配 ,即最长匹配,即可能多的匹配
m=re.search('.+?(\d+)',data) #?阻止贪婪匹配
m.groups()
('1588888696')
socket函数与方法:
创建TCP服务器
创建TCP服务器的主要步奏:
1.创建服务器套接字:s=socket.socket()
2.绑定地址到套接字:s.bind()
3.启动监听:s.listen()
4.接受客户连接:s.accept()
5.与客户端通信:recv()/send()
6.关闭套接字:s.close()
import socket
host='' #空串表示所有地址
port=1234
addr=(host,port)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #网络的tcp的套接字
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #套接字选项,允许程序退出后立即可以执行,1是允许
s.bind(addr)
s.listen(1) #为一个程序提供服务
while True: #持续链接
cli_sock,cli_addr = s.accept() #返回一个套接字元组和地址,yum -y install telnet
print "Client connected from:",cli_addr #telnet 127.0.0.1 1234
while True:
cli_sock.send(" i c u \r \n")
data= cli_sock.recv(1024) #每次接受1024字节数据
if data.strip() == '' :
break
print data
cli_sock.close()
s.close()
==================================
爬取图片
bob=AddrBook('bob','1231332','bob@tt')<br/" rel="nofollow">import urllib2
html=urllib2.urlopen('http://www.baidu.com/a.jpg')
data=html.read()
html.close
with open('a.jpg','w') as fobj:
fobj.write(data)
分析apache访问日志
编写一个apche日志分析脚本
1.统计每个客户端的访问apache服务器的次数
2.将统计信息通过字典的方式显示出来
3.分别统计客户端时firefox和msie的访问次数
4.分别使用函数式编程和面向对象编程的方式实现
import re
def count_patt(fname,patt):
result={}
cpatt=re.compile(patt)
with open(fname) as fobf: for line in fobf: m=cpatt.search(line) #全句查找 if m: key=m.group() result[key]=result.get(key,0)+1 #获取字典的值,没有则用0return result
def quick_sort(str_list):
if len(str_list)==0 or len(str_list) ==1:
return str_list
middle=str_list.pop()
smaller=[]
large=[]
for item in str_list:
if item[-1] < middle[-1]:
smaller.append(item)
else:
large.append(item)
return quick_sort(large) +[middle]+quick_sort(smaller)
if name == 'main':
log_file='access_log-2016077'
ip='^(\d+.){3}\d+'
br='Firefox|MSIE'
print count_patt(log_file,ip)
print count_patt(log_file,br)
a=count_patt(log_file,ip)print aprint quick_sort(a.items())
多线程:
import threading
import subprocess,threading
def myiping(ip):
a=subprocess.call('ping -c2 -i0.1 %s &>/dev/null' % ip,shell=True)
if a:
print '%s is down'%ip
else:
print '%s is up'%ip
net=['172.40.55.%s' %i for i in range(1,255)]
for i in net:
t=threading.Thread(target=myiping,args=[i]) #target是函数名,args是参数
t.start()
利用多线程实现ssh并发访问
import paramiko
host = '192.168.4.100'
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username='root', password='123456')
ssh.exec_command('touch /hh22.txt')
stdin,stdout,stderr=ssh.exec_command('ls /') #将结果赋值给3个变量
print stdout.read() #获取输出结果
4 案例4:利用多线程实现ssh并发访问
4.1 问题
编写ssh客户端脚本,主要要求如下:
在文件中取出所有远程主机IP地址在shell命令行中接受远程服务器IP地址文件、远程服务器密码以及在远程主机上执行的命令通过多线程实现在所有的远程服务器上并发执行命令方案
python的paramiko模块可以实现ssh客户端的功能,使用起来也比较简单。但是当服务器非常多的时候,每台服务器上执行完全相同的简单操作,也会花费大量的时间。
通过ssh加上多线程,可以实现并发访问。为了将程序写的灵活性更强,把要执行的命令以位置参数的方式来提供。
4.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:编写脚本
[root@py01 bin]# vim remote_comm.py#!/usr/bin/env pythonimport paramikoimport osimport sysimport threadingdef remote_comm(host, password, comm): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(host, username='root', password=password) stdin, stdout, stderr = ssh.exec_command(comm) out = stdout.read() err = stderr.read() if out: print "[%s:out]: %s" % (host, out), if err: print "%s:Error: %s", (host, err), ssh.close()if __name__ == '__main__': if len(sys.argv) != 4: print "Usage: %s ipfile password 'comm'" % sys.argv[0] sys.exit(1) ipfile = sys.argv[1] if not os.path.isfile(ipfile): print "No such file: %s" % ipfile sys.exit(2) password = sys.argv[2] comm = sys.argv[3] with open(ipfile) as fobj: for line in fobj: ip = line.strip() t = threading.Thread(target=remote_comm, args=(ip, password, comm)) t.start()
xinetd:
yum -y install xinetd
vim /etc/xinetd.d/pyserver
service pyserver
{
flags = NAMEINARGS
type = UNLISTED
socket_type = stream
port = 21345
protocol = tcp
wait = no
user = root
server = /root/lgh/ex1.py
server_args = /root/lgh/ex1.py
}
vim /root/lgh/ex1.py
#!/usr/bin/env python
import sys
sys.stdout.write('sdfe')
sys.stdout.flush() #刷新缓存
父进程
os.fork()
celery 框架
import os
import time
pid=os.fork()
print pid
if pid:
print "in par"
time.sleep(15)
print "par ext"
else:
print "in chi"
for i in range(5):
print time.ctime()
time.sleep(1)
print "ch exit"
父进通过os.wait()来得到子进程是否终止信息
python3.0
依赖
yum -y install gcc gcc-c++ opensll-devel libffi-devel readline-devel
https://www.python.org/ftp/python/3.6.1/
字符串直接是UNICOOK
去除回车
print(line,end='')
输入:
input
5/3 直接返回浮点
5//3 返回整数
异常
except IndexError as e #2用逗号,3用as
raise valueerror,'valll.' #2用逗号
raise valueerror('xxxxx') #3用括号
range() 和2版本的xrange()一样。
adict.keys 返回对象,不是列表。
整数统一了,没长整数
8进制数改成0o11
3也有可变集和和不可变集和
{} 是可变集和
frozenset([])是不可变集和。
数据库
模块 MySQL-python 1.2.5 py2.7
mysqlpy 2.1.7 py3.0
pip3 install PyMySQL 安装组建
插入数据
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="insert into depar(dep_name) values(%s)"
result=cur.execute(sql1,('deve',)) #后面是元组,单元组要加逗号
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
执行后放回1 是影响1行。
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="insert into depar(dep_name) values(%s)"
data=[('hr',),('op',),('财务',)]
result=cur.executemany(sql1,data) #多个数据
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="insert into depar(dep_name) values(%s,%s)"
data=[('hr','aa'),('op','bb'),('财务','cc')]
result=cur.executemany(sql1,data) #多个数据
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
sql1="insert into salary(date,emp_id,basic,extra) values(%s,%s,%s,%s)"
data=(time.strftime('%Y-%m-%d'),1,10000,5000)
result=cur.execute(sql1,data) #多个数据
查询
import pymysql
conn=pymysql.connect(
host='127.0.0.1',
user='root',
port=3306,
passwd='123456',
db='test'
charset='utf8'
)
cursor=conn.cursor() #游标,获取SQL结果
sql1="select * from departments"
result=cur.fetchone() #获取一条数据
result2=cur.fetchmany(2) #获取2条数据
cur.scroll(1,mode="ralative") #相对当前位置移动
result3=cur.fetchmany(2) #获取2条数据
result3=cur.fetchall() #获取全部数据
print(result)
conn.commit()
cur.close() #关闭游标
conn.close() #关闭数据库
移动游标获取数据
cur.scroll(1,mode="ralative") #相对当前位置移动
cur.scroll(2,mode="absolute") #相对查询结果位置移动
更新
sql1="updata salary set dep=%s where dep=%s"
result=cur.execute(sql1,('oppp','op')) #多个数据
删除
sql1="delete from salary where dep=%s"
result=cur.execute(sql1,('oppp',)) #多个数据
SQLalchemy
连接数据库
安装
pip3 install SQLalchemy
连接
数据库类型+驱动://user:password@host/dbname[?key=value...] #[?连接参数]
from sqlalchemy import create_engine
engine=create_engine('mysql+pymysql://root:123456@localhost/dbtest',encoding='utf8',echo=True)
echo=True 表示将日志输出到终端屏幕,默认为False,调试时用
声明映射
当使用ORM的时候,配置过程从描述数据库表开始
通过自定义类映射相应的表
通过声明系统实现类映射
首先通过声明系统,定义基类
from sqlalchemy.ext.declarative import declarative_base
Base=declarative_base() #声明基类
创建映射类
一旦创建了基类,就可以创建自定义映射类了
from sqlalchemy import Column,Integer,String
class Departments(Base):
tablename='departments'
dep_id=Column(Integer,primary_key=True)
dep_name=Column(String(20))
def repr(self):
return "<Department(dep_name='%s')>"% self.dep_name
#repr是可选项 输出类的信息,可print(Base)查看
创建架构
类构建完成后,表的信息将被写入到表的元数据(metadata)
print(Departments.tablename) #查看
创建表
if name == 'main':
Base.metadata.create_all(engine)
创建映射类的实例
创建实例时,并不会真正在表中添加记录
dep_dev=Departments(dep_name='developments') #创建会话后才插入数据
print(dep_dev.dep_name)
print(dep_dev.dep_id)
创建会话类
ORM访问数据库的句柄被称做Session
from sqlalchemy.orm import sessionmaker
Session=sessionmaker(bind=engine)
如果在创建session前还未创建engine,操作如下
Session=sessionmaker()
Session.configure(bind=engine) #创建engine后执行
添加新对象
会话类的实例对象用于绑定到数据库
实例化类的对象,并不打开任何连接
当实例初次使用,它将从Engine维护的连接池中获得一个连接
当所有的事务均被commit或会话对象被关闭时,连接结束
session=Session()
session.add(dep_dev)
session.commit()
print(str(dep_dev.dep_id))
session.close()
添加新对象
。可以创建多个实例,批量添加记录
。如果有中文,注意engine的参数
engine=create_engine('mysql+pymysql://root:123456@localhost/dbtest?charset=utf8',encoding='utf8',echo=True)
Base.metadata.create_all(engine)dep_hr=Departments(dep_name='hr')dep_op = Departments(dep_name='op')dep_finance = Departments(dep_name='财务')dep_xz = Departments(dep_name='行政')Session=sessionmaker(bind=engine)session=Session()session.add_all([dep_hr,dep_op,dep_xz]) #多行用[]session.commit()session.close()
ORM映射关系也可用于表间创建外键约束
from sqlalchemy import Column,Integer,String,ForeignKey
class Employees(Base):
tablename='employees'
emp_id=Column(Integer,primary_key=True)name=Column(String(20))genda = Column(String(10))phone = Column(String(11))dep_id=Column(Integer,ForeignKey('departments.dep_id'))def __repr__(self): return "<Employees(name='%s')>" % self.name
日期
from sqlalchemy import Column,Integer,String,ForeignKey,Date
class salary(Base):
tablename='salary'
id=Column(Integer,primary_key=True)date=Column(Date) #日期应用emp_id=Column(Integer,ForeignKey('employees.emp_id'))basic=Column(Integer)extra = Column(Integer)
日期插数据
from datetime import date
date1=date(2017,1,1)
bob1=Salary(date=date1,emp_id=4,basic=1000,extra=3000)
基本查询
通过作用于session的query()函数创建查询对象
query()函数可以接收多种参数
Session=sessionmaker(bind=engine)
session=Session()
for instance in session.query(Departments).order_by(Departments.dep_id):
print(instance.dep_id,instance.dep_name)
使用ORM描述符进行查询
返回值是元组
for name,phone in session.query(Employees.name,Employees.phone ): #多字段
print(name,phone)
使用命名元组(即为元组下标命名,方便引用)
查询对象返回的是一个命名元组
名称是类的名字,或是类中属性的名字
for row in session.query(Departments,Departments.dep_name)
print(row.Departments,row.dep_name)
修改显示字段名显示的字段名可以通过label()函数进行修改for row in session.query(Departments.dep_name.label('部门')): print(row.部门)使用别名可以为经常使用的类定义别名from sqlalchemy.orm import sessionmaker,aliasednew_emp=aliased(Employees)for row in session.query(new_emp,new_emp.name,new_emp.phone).all(): print(row.name,row.phone)排序通过order_by()函数可以实现按指定字段排序 for instance in session.query(Departments).order_by(Departments.dep_id): print(instance.dep_id,instance.dep_name)提取部分数据通过“切片”的方式,实现部分数据的提取 new_emp=aliased(Employees) for row in session.query(new_emp,new_emp.name,new_emp.phone).order_by(new_emp.emp_id)[2:4]: print(row.name,row.phone)结果过滤通过filter()函数实现结果过滤new_emp=aliased(Employees)for row in session.query(new_emp,new_emp.name,new_emp.phone).filter(new_emp.name=='bob'): print(row.name,row.phone)filter()函数可以叠加使用new_sal=aliased(Salary)for row in session.query(new_sal,new_sal.emp_id,new_sal.basic,new_sal.extra).filter(new_sal.extra >=2000).filter(new_sal.extra<10000): print(row.emp_id) 常用过滤操作符 相等 query.filter(Employees.name=='john') 不相等 query.filter(Employees.name!='john') 模糊查询 query.filter(Employees.name.like('j%')) in query.filter(Employees.name.in_(['j','b'])) not in query.filter(~Employees.name.in_(['j','b'])) 字段为空 query.filter(Employees.name.is_(None)) 字段不为空 query.filter(Employees.name.isnot(None)) 多重条件AND from sqlalchemy import and_ query.filter(and_(new_sal.basic>=10000,new_sal.extra>=2000)) 多重条件or from sqlalchemy import or_ query.filter(or_(new_sal.basic>=10000,new_sal.extra>=2000)) 查询对象返回值 all()返回列表 first()返回结果中的第一条记录 one()取出所有记录,如果不是一条记录则抛出异常 scalar()调用one(),返回第一列的值 new_sal=aliased(Salary) query= session.query(new_sal) print(query.all()) 聚合 通过count()方法,统计行数 new_sal=aliased(Salary) query= session.query(new_sal).filter(new_sal.extra<10000) print(query.count()) 多表查询 通过join() 方法实现多表查询 new_emp=aliased(Employees) new_dep=aliased(Departments) query=session.query(new_emp.name,new_dep.dep_name).join(new_dep,new_emp.dep_id==new_dep.dep_id) result=query.all() print(result) 通过会话的update()方法更新 query=session.query(Departments).filter(Departments.dep_id==8) query.update({Departments.dep_name:'运营'}) session.commit() 通过会话的字段赋值更新 dep_yy=session.query(Departments).get(8) #get主键 dep_yy.dep_name='运营' session.commit() 删除记录 通过会话的delete()方法进行记录删除 dep_yy=session.query(Departments).get(8) #get主键 session.delete(dep_yy) session.commit()session.close()
共同学习,写下你的评论
评论加载中...
作者其他优质文章