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] #去掉输入的空格并获取第一个值 cmdschoice #用字典匹配获取对应的值得调用函数

元组 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'])) 输出: {'age':23,'name':bob,'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_dicti 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=email

def get_email(self):
    return self.email

if name == 'main': tom=EmplAddrBook('tom','13666','tom@de.cn') print tom.get_phone() print tom.get_email() 父类和子类有同名方法时,会调用子类


组合:

class UserInfo(object): def init(self,phone,email): self.phone=phone self.email=email

def get_phone(self):
    return self.phone

def updata_phone(self,newphone):
    self.phone=newphone
    return self.phone

    def get_email(self):
    return self.email

def updata_email(self,newemail):
    self.email=newemail
    return self.email

class AddrBook(object): def init(self,name,phone,email): self.name=name self.info=UserInfo(phone,email) #引用上一个类定义的属性

if name == 'main': bob=AddrBook('bob','1231332','bob@tt') print bob.info.get_phone() bob.info.updata_email('bob@udif')


多重继承 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()

================================== 爬取图片

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  #获取字典的值,没有则用0
return 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 a
print 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 python
import paramiko
import os
import sys
import threading
def 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,aliased
new_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()