Python3学习笔记

本问适合有编程基础的人,通篇敲完,能够达到快速上手python的目的.

一.hello world

print("hello world")

二.变量

1.定义与初始化

counter = 100  # 赋值整型变量
miles = 1000.0  # 浮点型
name = "Tom"  # 字符串

print (counter)
print (miles)
print (name)

2.交换两个变量的值

#方法一:
a=1
b=2
tmp=0
tmp=a
a=b
b=tmp
print(a,b)#2,1

#方法二:
a=1
b=2
b,a=a,b
print(a,b)#适用于python   2,1

#方法三:
a=1
b=2
a=a+b
b=a-b
a=a-b#加减法方式交换两个变量值

三.python中的单引号,双引号和三引号(三个单引号)

  元组python中定义变量的时候字符串都用引号引起来,此时单引号和双引号没有区别。但是如果字符串中有单引号的话,外面就得用双引号;如果里面有双引号,外面就用单引号;如果既有单引号又有双引号,那么用三引号,三引号也可以多行注释代码,单行注释,使用

#单行注释
''' 
    这是
    多行注释
'''
"""
    这是
    多行注释
"""

name = '小明'
name1 = "小红"
names = '''李妈妈说:"小明,你一小时内写不完作业,就别想出去玩了!".
        小明说:'哦...'.
        小明沮丧的回了书房.'''
names2 = """李妈妈说:"小明,你一小时内写不完作业,就别想出去玩了!".
        小明说:'哦...'.
        小明沮丧的回了书房."""
print(names)
print(names2)

四.输入输出

name=input('请输入你的名字:')
print(name)

五.条件语句

score = int(input('请输入你的成绩:'))
if score>=80:
    print('优秀')
elif score >=60:
    print('及格')
else:
    print('不及格')

六.循环语句

# while循环,体会continue,break的用法
count = 0
while count<10:
    count += 1
    if count==3:
        continue
    elif count==5:
        break
    print(count)
# for循环,注意Python的代码层次是依靠缩进控制的
names=['Lily','Tom','Lilei']
for name in names:
    if name=='Lily':
        continue
    print(name)
else:
    print('over')

七.格式化输出

name=input('请输入你的名字:')
print('你的名字是'+name)#使用加号连接
print('你的名字是%s' %name)#使用占位符
#使用format格式化输#出,{}里面的名字可以随便写但是要和后面的format中的名字保持一致,然后再把你前面定义的变量写到等号后面就可以了。
print('你的名字是{your_name}'.format(your_name=name))

#这种是里面有多个格式化内容的,前面那个是字符串,后面这个是整数,多个变量的后面跟值得时候必须要加上括号
age=18
print('我的名字是%s,年龄是%d岁.'%(name,age))

八.列表操作

1.定义和取值

list1 = [1,2,3,4]#一个普通数组
list2 = ['marry','Lily',[50,'money']]#二维数组
list3 = ['name','sex',['lily',124,['aaaa','bbb']]]#三维数组

print(list2[2][1])#money
print(list3[2][2][0])#aaaa
msg='你好'
name=['jeck','tom','niuniu']

2.添加元素

name.append('小明')#在list末尾增加一个元素
print(name)#['jeck', 'tom', 'niuniu', '小明']
name.insert(1,'小红')#从指定位置插入,这个1代表下标
print(name)#['jeck', '小红', 'tom', 'niuniu', '小明']
name.insert(10,"小花")#如果指定下标不存在,那么就是在末尾添加
print(name)#['jeck', '小红', 'tom', 'niuniu', '小明', '小花']
name.insert(-1,msg)#-1可以写,但是结果添加出来不对,所以一般不写
name.insert(-1,msg)#-1可以写,但是结果添加出来不对,所以一般不写
name.insert(-1,msg)#-1可以写,但是结果添加出来不对,所以一般不写
print(name)#['jeck', '小红', 'tom', 'niuniu', '小明', '你好', '你好', '你好', '小花']

3.修改元素

name[1]='hello'#修改指定位置的值,直接取下标进行修改即可
print(name)#['jeck', 'hello', 'tom', 'niuniu', '小明', '你好', '你好', '你好', '小花']

4.查询元素

print(name.count('你好'))#查看在list中某个元素的个数
print(name.count("world"))#查看在list中某个元素的个数,如果该元素不存在,那么返回0
print(name.index('你好'))#找到这个元素的下标,如果多个,返回第一个
#print(name.index('world'))#找到这个元素的下标;如果多个,返回第一个;如果找一个不存在的元素,会报错

5.删除元素

name.remove('hello')#删除指定的值
name.pop()#默认删除最后一个元素,如果指定下标,那么删除指定的元素
name.pop(2)
#name.pop(100)#如果删除不存在的元素,那么报错
del name[0]#删除指定位置的值
name.clear()#清空列表

6.列表合并

a = [1,2,3,4]
b = [5,6,7,8]
a.extend(b)#合并b到a
print(a)#[1,2,3,4,5,6,7,8]
print(b)#[5,6,7,8]只是把b列表里的内容合并到a中,b列表并不受影响

7.反转

a = [1,2,3,4,5,6,7,8]
a.reverse()
print(a)#[8, 7, 6, 5, 4, 3, 2, 1]

8.排序

c = [5,32,7,4,9,0]
c.sort()
print(c)#[0, 4, 5, 7, 9, 32]
c.sort(reverse=True)
print(c)#排序,默认排序是升序,如果指定了reverse=True就是按照降序排

9.切片

nums=[1,2,3,4,5,6,2,3,4,6,4,3,2,1,2,3,4]
print(nums[3:6])#[4,5,6]
print(nums[:6])#[1,2,3,4,5,6] 如果切片的前面一个值不写的话,从头开始数
print(nums[3:])#[4,5,6,2,3,4,6,4,3,2,1,2,3,4] 如果切片的后面一个值不写的话,取到末尾
print(nums[:])#如果切片的两个值都不写的话,从头取到尾
print(nums[::2])#步长为2,这个代表取所有的元素,然后每隔2个元素取一个
print(nums[::-1])#步长是正数的话从左往右取,步长是负数的话从右往左取,相当于倒序排列
print(nums[-1:-9:-1])
print(nums[16:8:-1])
#切片同样适用于字符串,字符串也有下标
title='今天发 苹果' #空格也算一个字符串
print(title[0]) #今
print(title[:4])#今天发
for t in title:
     print(t)#今天发 苹果
for i,t in enumerate(title):#enumerate可以同时循环索引下标和值
    print('%s:%s'%(i,t)) #0:今 1:天 2:发 3:  4:苹 5:果
#列表也适用enumerate:
names=['haha','hehe','heihei']
for index,name in enumerate(names):
    print('%s:%s'%(index,name))

10.列表推导

#列表推导式
nums=[0,1,3,4,5,6,7]
#将nums里int类型转化成字符串 ,方法一:
new_nums=[]
for n in nums:
    n=str(n)
    new_nums.append(n)
print(new_nums)     #['0', '1', '3', '4', '5', '6', '7']
#将nums里int类型转化成字符串 ,方法二:
new_nums=[str(n) for n in nums]#列表推导式转化,简化代码
print(new_nums)     #['0', '1', '3', '4', '5', '6', '7']

九.字典操作

  字典也是我们开发过程中最常用的一种数据类型;具有极快的查找速度;字典是一种key-value的数据类型,比如说要存每个人的信息,那么每个人的编号就是key,value就是每个人的信息,这样的话,一个字典就能存所有人的信息了。字典的定义使用{},大括号,每个值用“,”,key和value使用“:”分隔。字典:

1.定义和初始化

'''
字典是无序的,因为它没有下标,用key来当索引,所以是无序的
字典的key必须是唯一的,因为它是通过key来进行索引的,所以key不能重复,天生就去重
'''
#定义:key--value
person={'小明': [18,'男','北京',],
        '小红': [20, '女', '上海', ],
        '小刚': [19, '男', '北京', ],}
print(person['小红'])

# k:v
pp={
    'name':'李刚',
    'sex':'男',
    'hight':180,
    'addr':'北京'
}

2.查询元素

print(pp['name'])
#print(pp['haha'])#如果写了不存在的key,会报错
print(pp.get('name'))
print(pp.get('xeudh'))#get如果写了不存在的key,会返回None
print(pp.get('xheudh','找不到'))#get不到,返回默认值找不到

3.添加元素

#第一种方式
pp['phone']=18800000000
#第二种方式
pp.setdefault('weight',130)
print(pp)

4.删除元素

pp.pop('phone')#删除指定的key
del pp['weight']
pp.popitem()#随机删除一个
# pp.clear()#清空字典
print(pp)

5.遍历字典

print(pp.keys())#获取到字典的所有key
print(pp.values())#获取到字典的所value
if 'name' in pp:#判断key是否在字典里头,只查找字典里的key值
    print('name')
print(pp.items())#把字典的key和value转成一个二维数组,字典是无序的
# 打印结果dict_items([('name', '李刚'), ('sex', '男'), ('hight', 180)])
res=list(pp.items())
print(res[0])
#方式一:
for k,v in pp.items():#同时把key和value循环出来
    print(k,v)
#方式二:
for k in pp: #性能好
    print(k,pp[k])
    print(k,pp.get(k))

6.修改元素

#如果key存在的话,修改它的值;如果不存在,那么新增它的值
pp['hight']=200
print(pp)
#{'name': '李刚', 'sex': '男', 'hight': 200}

十.元组操作

元组操作:
  元组其实和字典一样,不一样的是,元组得到值不能改变,一旦创建,就不能改变了,比如说,要存数据库的连接信息,这个连接信息在程序运行中是不能改变的,如果变了那数据库连不上了,那程序就不好了,这样的就可以使用元组了,元组呢?也提示别人,看到是元组的话,就说明这个值是不能被改变的,元组的定义方式是(),小括号;元组只有两个方法,那就是count和index

#定义元组
mysql_conn=('192.168.40.10','root','123',3306,'mydb')
#通过索引查询
print(mysql_conn[0])

#count和index方法
print(mysql_conn.count('root'))#查看在list中某个元素的个数
print(mysql_conn.count("world"))#查看在list中某个元素的个数,如果该元素不存在,那么返回0
print(mysql_conn.index('root'))#找到这个元素的下标,如果多个,返回第一个
#print(mysql_conn.index('world'))#找到这个元素的下标;如果多个,返回第一个;如果找一个不存在的元素,会报错

十一.字符串操作

name='hello world'
print(name.capitalize())#首字母大写Hello world
print(name.center(50,'-'))#50个-,把name1放中间-------------------hello world--------------------
print(name.endswith('u'))#是否以x结尾 False
print(name.endswith('d'))#是否以x结尾 True
print('abA123'.isalnum())#是否包含数字和字母 True
print('abA'.isalpha())#是否有英文字母True
print(name.find('o'))#查找'o'在字符串中的索引并返回

name1 = 'my name is {name},age is {age}'
print(name1.format(name='niuniu',age=18))#这个是格式字符串
# 输出:my name is niuniu,age is 18
print(name1.format_map({'name':'niuniu','age':19}))#这个也是格式化字符串,后面跟的是一个字典
# 输出:my name is niuniu,age is 19
name = 'My \t name is {name},age is{age}.'
print(name)#My   name is {name},age is{age}.
#扩展\t的次数
print(name.expandtabs(30))#My                             name is {name},age is{age}.
print('122'.isdigit())#是否有数字True
print('aa'.isidentifier())#是否是一个合法的变量名True
print('aa'.islower())#是否是小写字母True
print('AA'.isupper())#是否是大写字母True
print('Loadrunner Book'.istitle())#是不是一个标题,判断首字母是否大写True
print('+'.join(['hehe','haha','ee']))#拼接字符串 hehe+haha+ee
print(name.lower())#变成小写my   name is {name},age is{age}.
print(name.upper())#变成大写MY   NAME IS {NAME},AGE IS{AGE}.
print('\nmysql \n'.lstrip())#默认去掉左边的空格和换行
print('\nmysql \n'.rstrip())#默认去掉右边的空格和换行
print('\nmysql \n'.strip())#默认去掉两边的空格和换行
p=str.maketrans('abcdefg','1234567')#前面的字符串和后面的字符串做映射
print('cc ae gg'.translate(p))#输出按照上面maketrans做映射后的字符串33 15 77
new_p=str.maketrans('1234567','abcdefg')
print('cc ae gg'.translate(new_p))#输出:cc ae gg
print('33 15 77'.translate(new_p))#输出:cc ae gg
print('mysql is db.'.replace('mysql','oracle',1))#替换字符串oracle is db.
print('mysql is db.mysql is db.mysql is db.'.replace('mysql','oracle',2))#替换字符串oracle is db.oracle is db.mysql is db.
print('mysql is is db'.rfind('is'))#返回最右边字符的下标 9
print('1+2+3+4'.split('+'))#切割字符串,返回一个list ['1', '2', '3', '4']
print('1+2+3\n1+2+3+4'.splitlines())#按照换行符分割['1+2+3', '1+2+3+4']
print('Abcdef'.swapcase())#大小写反转aBCDEF

十二.文件操作与集合

打开文件的模式有:
  f=open('file.txt','r')
  r:只读模式(默认)
  w:只写模式.不可读;不存在则创建;存在则删除以前的内容,然后写入新的内容
  a:追加模式.不可读;不存在则创建;存在则只追加内容
  “+”表示可以同时读写某个文件:
  r+:可读,可写;可追加,如果打开的文件不存在的话,会报错
  w+:写读模式,使用w+的话,已存在的文件内容会被清空,可以读到已经写的文件
  a+:追加读写模式,不存在则创建;存在则只追加内容

f=open()#打开文件
f.read()#读取文件里面所有的内容,返回的是字符串
f.readline()#只读取一行的内容,返回的是字符串
f.readlines()#读取文件里面所有的内容,返回的是一个list #list里每个元素是每行的数据
f.close()#关闭文件
f.write()#只能写字符串
f.writelines()#写可迭代对象

1.基本操作

f=open('file.txt','r')#以只读方式打开一个文件,获取文件的句柄,如果是读的话,r可以不写,默认就是只读;文件不存在时,会报错
first_line=f.readline()#获取文件的第一行内容,返回的是一个list
print(first_line)#打印第一行
f.seek(0)#seek移动指针的时候,只对读好使,对写不好使
res=f.readlines()#获取除了第一行剩下的所有文件内容
print(res)
print(f.tell())#查看当前文件指针的位置 44
print(f.read())#读取指针之后的所有内容,上次readlines()读完时指针后面没有数据了
f.seek(10)#重新调整指针位置,设置指针到10的位置
print(f.read())#读取指针之后的所有内容
f.close()

2.读取文件内容

#方式一:
fw=open('file.txt')
count=1
#直接循环文件对象的话,就是循环文件里面的每一行
for f in fw:
    print('第%s行'%count,f)
    count+=1
fw.close()

结果:文件内容中个的\n不会被解析
第1行 aaaaaa\n

第2行 bbbbbb

第3行 bbbbbbb

#方式二:
fw=open('file.txt')
for f in fw:
    f=f.strip()
    stu_lst=f.split(',')
    print(stu_lst)
fw.close()

结果:这里的\n会读取为\n,使用了转义字符\
[‘aaaaaa\n’]
[‘bbbbbb’]
[‘bbbbbbb’]

3.写文件内容

#方法一:write将list写入文件,write写入字符串
names=['a','b','c']
for name in names:
    f.write(name)
方法二:writelines直接写入,writelines传入可迭代对象,会先循环
names=['a','b','c']
f.writelines(names)#写入的时候,传入一个可迭代对象就行了

s='dingfei,123456'
f.write(s)#字符串类型,直接写入,效率高
f.writelines(s)#可迭代对象,先循环字符串,效率不高
import time
f=open('file.txt','w')
f.write('sdfggg')
f.flush()#立即把缓冲区里面的内容写到磁盘里面
f.write('sdfggg')
time.sleep(50)
f.close()#关闭时会把缓存中没有写入的内容写入到文件中

4.with用法

# with open('file.txt','w') as gy:
#     gy.write('hhh')#自动的当文件不在用时直接关掉

#操作多个文件
with open('file.txt','w') as gy,open('abc.txt','w') as gy2:
    gy.write('hhh')
    gy2.write('sdfs')

5.读取图片文件

f=open('1.png','rb')#bytes,以二进制模式打开
print(f.read())

6.替换文件内容

功能相当于ctrl+f,替换所有A–>B
文件内容

ABCDEFaa
AABCDEAA
bcdEdeab

方法一:将文件完全替换后,清空内容,再重新写入

with open('file.txt','a+',encoding='utf-8') as f:
    f.seek(0)
    all=f.read()
    new_all=all.replace('A','B')
    f.seek(0)
    f.truncate()#把文件内容清空
    f.write(new_all)
    f.flush()

方法二: 将文件内容替换后,写入新文件,将旧文件删除,新文件重命名为旧文件的名称

import os
with open('file.txt','a+',encoding='utf-8') as f,open('file.bak','w',encoding='utf-8') as f2:#直接打开两个文件
    f.seek(0)
    for line in f:
        new_line=line.replace('A','B')
        f2.write(new_line)#把文件file里修改的内容写入到文件file.bak
os.remove('file.txt')#删除第一个文件
os.rename('file.bak','file.txt')#将第二个文件的名字改为第一个

集合:

  集合也是一种数据类型,一个类似列表的东西,它的特点是无序的,不重复的,也就是说集合中是没有重复的数据。天生去重!
集合的作用:
  1.它可以把一个列表中重复的数据去掉,不需要再写判断
  2.可以做关系测试。取交集,并集,差集

1.定义集合:

s=set()#定义了一个空的集合
s2={'1','2','3'}#这种方式是直接定义一个集合;如果有冒号是字典,没有冒号就是集合
list=[2,3,1,2,3,4]
s_list=set(list)#这样就定义了一个集合
set1=set([1,3,4,5,6])#这种方式和上面的都是把list转换成一个集合

2.结合操作:

list1={1,2,3,4,5,6,9}
list2={2,3,4,6,1}
list3={1,2,3}
print(list1.intersection(list2))# 取交集,也就是取list1和list2中都有的
print(list1&list2)# 取交集,也就是取list1和list2中都有的
print(list1.union(list2))# 取并集,也就是把list1和list2合并了,然后去除重复的
print(list1 | list2)# 取并集
print(list1.difference(list2))#取差集 在list1中存在,在list2中没有的
print(list1 - list2)
list1.add(888)#添加元素
list1.update([777,666,666])#添加元素
list1.remove(777)#删除元素,如果元素不存在会报错
list1.pop()#删除一个随机的元素,并返回删除的元素
list1.discard('dddd')#如果删除的元素存在,删除,不存在不做处理
print(list1)

函数

1.函数

  定义:函数是指一组语句的集合通过一个名字(函数名)封装起来,只需调用函数名即可。

2.函数的好处:

  简化代码
  提高代码的复用性
  代码可扩展

3.python中函数的定义:

#定义函数使用def关键字,后面是函数名,函数名不能重复
def fun():#定义一个函数,后面是函数名
    print("Hello World")#函数体

4.函数的参数

  函数在调用的时候,可以传入参数,有形参和实参
  形参:
  形参变量只有在被调用时才被分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。
  实参:
  实参可以是常量,变量,表达式,函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。函数调用结束返回主调用函数后则不能再使用该形参变量。形参是函数接收的参数,而实参就是你实际传入的参数。

def calc(x,y):# 定义一个函数,参数有下x和y,x和y就是形参
    print(x * y)  # 输出x乘以y的值
calc(5,2)  # 调用上面定义的函数,5和2就是实参

  函数的四种形参类型:
  位置参数:
  位置参数,字面意思也就是按照参数的位置来进行传参,比如说上面的calc函数,x和y就是位置参数,位置参数是必传的,有几个位置参数在调用的时候就要传几个,否则就会报错了,那如果有多个位置参数的话,记不住哪个位置传哪个了,可以使用位置参数的名字来指定调用
比如说上面的calc函数也可以使用calc(y=1,x=2)这样来调用,这种调用方式叫做关键字传参
  默认参数:
  默认参数就是在定义形参的时候,给函数默认赋一个值,比如说数据库的端口这样的,默认给它一个值,这样就算你在调用的时候没传入这个参数,它也是有值的;因此,默认参数不是必填的,如果给默认参数传值的话,它就会使用传入的值。如果使用默认参数的话,必须放在位置参数后面定义。

def conn_mysql(user, passwd, port=3306):  # 定义一个连接mysql的方法,虽然这个方法并没有连接mysql,我只是举个默认值参数的例子,port就是一个默认值参数
    print(user,passwd,port)
conn_mysql('root', '123456')  # 没指定默认值root 123456 3306
conn_mysql('root', '123456', port=3307)  # 指定默认值参数的值root 123456 3307

  非固定参数:
  上面的两种位置参数和默认参数都是参数个数是固定的,如果说我一个函数,参数不是固定的,我也不知道以后这个函数会扩展成啥样,可能参数越来越多,这个时候如果再用固定的参数,那后面程序就不好扩展了,这个时候就可以用非固定参数了,非固定参数有两种,一种是可变参数,一种是关键字参数。
  可变参数:
  可变参数用*来接收,后面想传多少个参数就传多少个,如果位置参数,默认值参数,可变参数一起使用的话,可变参数必须在位置参数和默认值参数后面,可变参数也是非必传的。

def test (a, b=1 ,*args):
    print('a',a)
    print('b',b)
    print('args',args)

test('Tom')#a Tom  b 1  args ()
test(b=5,a=10)#关键字调用 a 10   b 5  args ()

结果:
a Tom
b 1
args ()
a 10
b 5
args ()

def test (a, b=1 ,*args):
    print('a',a)
    print('b',b)
    print('args',args)
    print(args[0])

test('Tom',2,'123','456','789')

结果:
a Tom
b 2
args (‘123’, ‘456’, ‘789’)
123

关键字参数:
  关键字参数使用**来接收,后面的参数也是不固定的,想写多少个写多少个,当然也可以和上面的几种一起来使用,如果要一起使用的话,关键字参数必须在最后面。
使用关键字参数的话,调用的时候必须使用关键字传参。关键字参数也是非必传的。

def test2(a,**kwargs):
    print(kwargs)#字典类型
    print(a,kwargs)
test2(a=1,name='Tom',sex='男')
#{'name': 'Tom', 'sex': '男'}
#1 {'name': 'Tom', 'sex': '男'}
test2(a=1)
#{}
#1 {}

5.函数的返回值

  每个函数都有返回值,如果没有在函数里面指定返回值的话,在python里面函数执行完之后,默认会返回一个None,函数也可以有多个返回值,如果有多个返回值的话,会把返回值都放到一个元组中,返回的是一个元组。为什么要有返回值呢,是因为在这个函数操作完之后,它的结果在后面的程序里面需要用到。函数中的返回值使用return,函数在遇到return就立即结束。

def calc(x,y):#这个就是定义了一个有返回值的函数
    c = x*y
    return c,x,y
res = calc(5,6)#把函数的返回结果赋值给res
print(res)

6.局部变量和全局变量

  局部变量意思就是在局部生效的,出了这个变量的作用域,这个变量就失效了,比如上面的c就是一个局部变量,出了这个函数之后,就没有c这个值了
  全局变量就是在整个程序里面都生效的,在程序最前面定义的都是全局变量,全局变量如果要在函数中修改的话,需要加global关键字声明,如果是list,字典和集合的话,则不需要加global关键字,直接就可以修改。

name='marry'#字符串全局变量
names=[]#list全局变量
print(name)
print(names)
def test():
    global name #修改name的值就需要用global关键字
    name='Sriba'
    names.append(name)#修改全局变量names的值
    return names
test()#调用函数
print('修改后',name)
print('修改后names',names)

结果:
marry
[]
修改后 Sriba
修改后names [‘Sriba’]

a=10#全局变量
b=100#全局变量
c=1000#全局变量
print('外部定义:')
print('a',a)
print('b',b)
print('c',c)
def test():
    print()
    print('内部访问:' )
    print('不存在同名局部变量,a',a)
    b = 5
    print('存在同名的局部变量,b', b)
    global c #声明全局变量
    c=11#修改全局变量,全局变量已经被修改了,即使在函数外面访问也是被修改后的值
    print('存在被global修饰的同名变量,并重新赋值,c',c)
test()#调用函数
print()
print('调用完成函数后外部访问:')
print('a',a)
print('内部定义的局部变量不影响全局变量,b',b)
print('内部声明的global修饰的同名变量,并重新赋值,c',c)

结果:
外部定义:
a 10
b 100
c 1000

内部访问:
不存在同名局部变量,a 10
存在同名的局部变量,b 5
存在被global修饰的同名变量,并重新赋值,c 11

调用完成函数后外部访问:
a 10
内部定义的局部变量不影响全局变量,b 100
内部声明的global修饰的同名变量,并重新赋值,c 11

7.递归调用

  在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。递归调用的意思就是,在这个函数内部自己调用自己,就有点循环的意思。
递归调用的特性:
  1.必须有一个明确的结束条件
  2.每次进入更深一层递归,问题规模相比上次递归都应有所减少
  3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧,由于栈的大小不是无限的,所有,递归调用的次数过多,会导致栈溢出)

def test1():
    num = int(input('please enter a number:'))
    if num%2==0:#判断输入的数字是不是偶数
       return True #如果是偶数的话,程序就退出了,返回true
    print('不是偶数请重新输入!')
    return test1()#如果不是偶数的话继续调用自己,输入值
print(test1())#调用test

8.高阶函数:

  一个函数的参数是一个函数,那么这个函数就是一个高阶函数。

def s_int(n):
    #这个函数的作用是把传入的参数类型转换成int类型
    return int(n)
def add(x,y,z):
    #这个函数的意思,接收3个参数,x,y,z,z是一个函数
    print(z(x)+z(y))#这个执行过程是这样的,z是一个函数,把x和y的值传给z,然后用z函数的返回值把两个值相加
add('8','9',s_int)#调用,传入x和y的值,再把上面的那个定义好的函数传进去

9.函数return多个值

#函数多个return值,那么会把这几个return的值都放在一个元组里面,然后返回
def hello(a,b,c,d):
    return a,b,c,d
res=hello('ybq','ede','rfv','deq')
print(res)      #('ybq', 'ede', 'dede', 'deq')

10.内置函数

print(all([1,2,3,4]))#判断可迭代的对象里面的值是否都为真  True
print(any([0,1,2,3,4]))#判断可迭代的对象里面的值是否有一个为真  True

print(bin(10))#十进制转二进制#0b1010
ejz=bin(100) #1100100
print(ejz.replace('0b',''))#1100100,去掉转换为二进制之后前面的0b


print(chr(65))#打印数字对应的ascii  A
print(ord('b'))#打印字符串对应的ascii  98

print(dict(a=1,b=2))#转换字典 {'a': 1, 'b': 2}
print(dir(1))#打印传入对象的可调用方法
l=[1,2,3]
print(dir(l))#会打印出list的一些可调用的方法

print(eval('[]'))#执行python代码,只能执行简单的,定义数据类型和运算
code='1+1'
print(eval(code))#2

#print(exec('def a() :pass'))#执行python代码None
code='''def a() :print('aa')'''
print(exec(code))#None
a()#aa

#zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后#返回由这些元组组成的列表。

#如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作#符,可以将元组解压为列表
ids=[1,2,3]
names=['小黑','小白','小黄']
for id,name in zip(ids,names):
    print(id,name)#1 小黑   2 小白   3 小黄
zipped=zip(ids,names)
print(list(zipped))#[(1, '小黑'), (2, '小白'), (3, '小黄')]

ids=[1,2,3]
names=['小黑','小白','小黄','小绿']
for id,name in zip(ids,names):
    print(id,name)#1 小黑   2 小白   3 小黄

ids=[1,2,3,4,7,8,0,-1]
print(sorted(ids))#升序 [-1, 0, 1, 2, 3, 4, 7, 8]
print(sorted(ids,reverse=True))#降序[8, 7, 4, 3, 2, 1, 0, -1]
print(sorted('0123450'))# ['0', '0', '1', '2', '3', '4', '5']

1.函数即变量:

def say(name):
    print(name)
ybq=say
ybq('元宝')

#代码示例:
def add():
    print('添加商品')
def view():
    print('查看商品')
def delete():
    print('删除商品')
choice=input('输入选择:1,2,3').strip()
menu={
    '1':add,
    '2':view,
    '3':delete
}
if choice in menu:
    menu[choice]()#相当于下面几行代码;适合用户函数没有参数,或者参数是一样的情况下,
else:
    print('输入错误')

'''if choice==1:
    add()
elif choice==2:
    view()
elif choice==3:
    delete()
else:
    print('输入错误')'''

2.map和filter:

#map
def func(a):
    if a%2==0:
        return a
    else:
        return False
nums=[x for x in range(11)]
all_res=[]
for num in nums:
    res=func(num)
    all_res.append(res)#map相当于这四行代码
res=map(func,nums)#循环调用函数,然后把每次函数处理的结果,放到一个list里面返回 此处func只是代表一个函数名,map知道了这个函数,所以就会执行调用的功能,自行去调用
print(list(res))#[0, False, 2, False, 4, False, 6, False, 8, False, 10]

#filter
def func(a):
    if a%2==0:
        return a#条件满足时返回满足条件的值
    else:
        return False
nums=[x for x in range(11)]

res=filter(func,nums)   #循环调用函数,filter只保存结果返回真的。[2, 4, 6, 8, 10],非空即真,非0即真,当a=0时,返回0,0是假,所以会把0筛选掉
print(list(res))


def func(a):
    if a%2==0:
        return True#条件满足时返回True真
    else:
        return False
nums=[x for x in range(11)]
res=filter(func,nums) #循环调用函数,filter只保存结果返回真的。[0, 2, 4, 6, 8, 10]连0一起保存下来
print(list(res))

模块

一个python文件就是一个模块
1.标准模块
python自带的,不需要你安装的
2.第三方模块
需要安装,别人提供的,例:pip install radis 如果提示没有pip,把python下script路径加到环境变量下
手动安装:找个第三方安装包.tar,gz,下载下来,在文件夹内,shift+右键,解压python setup.py install
手动安装
首先下载安装包
解压
在命令行里面进入到这个解压之后的目录(shift+右键)
执行python setup.py install
3.自己写的
自己写的python文件
import XX导入一个文件,导入文件的实质就是把这个python文件从头到尾运行一次

import在导入文件的时候,首先从当前目录下找这个文件,
然后从python的环境变量里面找
环境变量就是让一个命令,不管在哪个目录下都可以执行

import sys
print(sys.path)#查看当前系统的环境变量

function.py文件的内容如下:

def s_int(n):
    #这个函数的作用是把传入的参数类型转换成int类型
    return int(n)
def add(x,y,z):
    #这个函数的意思,接收3个参数,x,y,z,z是一个函数
    print(z(x)+z(y))#这个执行过程是这样的,z是一个函数,把x和y的值传给z,然后用z函数的返回值把两个值相加
add('8','9',s_int)#调用,传入x和y的值,再把上面的那个定义好的函数传进去
def sum(x):
    s = x*x
    return s
import function#导入 function.py文件,就是将 function.py文件内容执行一遍
function.add(8,9,sum)   #8*8+9*9=145

结果:
17
145

1.os模块  import os

import os
print(os.getcwd())#取当前工作目录,绝对路径
print(os.chdir("../"))#更改当前目录,.代表当前目录,..代表上一级目录
print(os.curdir)#当前目录,相对路径
print(os.pardir)#父目录,相对路径

print(os.mkdir("test1"))#在当前目录下创建文件夹
print(os.mkdir("c:/test1"))#在c盘下创建文件夹
print(os.rmdir("test1"))#删除当前目录下的文件夹test1


print(os.remove("abc.txt"))#删除文件,不能删除文件夹
print(os.remove("./file.txt"))#删除文件,不能删除文件夹,用相对路径指定

print(os.listdir('.'))#列出一个目录下的所有文件
print(os.listdir('c://'))#列出一个目录下的所有文件,指出路径

os.rename("abc.txt","aaa.txt")#重命名
print(os.stat("demo1.py"))#获取文件信息

print(__file__)#__file__就是当前这个文件的绝对路径,路径分隔符不正确G:/python/python_01/demo1/常用模块.py
print(os.path.abspath(__file__))#返回path规范化的绝对路径G:\python\python_01\demo1\常用模块.py

print(os.path.split("/usr/hehe/hehe.txt"))#分割路径和文件名,linux路径
print(os.path.split("c:\\usr\\hehe\\hehe.txt"))#分割路径和文件名,windows路径
# 语法:os.path.split('PATH')
# 参数说明:
# PATH指一个文件的全路径作为参数:
# 如果给出的是一个目录和文件名,则输出路径和文件名
# 如果给出的是一个目录名,则输出路径和为空文件名


print(os.path.dirname("c:\\usr\\hehe\\hehe.txt"))#c:\usr\hehe
print(os.path.dirname("/usr/local"))#获取父目录
print(os.path.basename("/usr/local"))#获取最后一级,如果是文件显示文件名,如果是目录显示目录名

print(os.path.exists("/usr/local"))#目录/文件是否存在
print(os.path.exists("c://test2"))#目录/文件是否存在 False

print(os.path.isfile("/usr/local"))#判断是否是一个文件
print(os.path.isfile("demo1.py"))#判断是否是一个文件 True
print(os.path.isfile("G:\python\python_01\demo1\demo1.py"))#判断是否是一个文件 True
print(os.path.isdir("G:\python\python_01\demo1"))#是否是一个文件夹 True

print(os.path.join('root','hehe','a.sql'))#拼接成一个路径:root\hehe\a.sql
print(os.path.getatime("demo1.py"))#返回最后一次进入此文件的时间。
print(os.path.getmtime("demo1.py"))#返回在此文件下最后一次修改的时间。

print(os.sep)#当前操作系统
print(os.linesep)#当前操作系统的换行符
print(os.pathsep)#当前系统的环境变量中每个路径的分隔符,linux是:,windows是;
print(os.environ)#当前系统的环境变量
print(os.name)#当前系统名称 nt

os.system('ipconfig')#用来执行操作系统命令,获取ip地址
os.system('calc')#用来执行操作系统命令,打开计算机
os.system('dir')#用来执行操作系统命令,获取当前目录下的内容,只能执行,获取不到结果

res=os.popen('ipconfig')#用来执行操作系统命令,并且获取到返回结果,使用.read()
print(res.read())

2.sys模块  import sys

import sys
print(sys.path)#环境变量
print(sys.platform)#win32 查看当前系统是什么
print(sys.version)#看python版本
print(sys.argv)#是获取运行python文件的时候,传入的参数['G:/python/python_01/demo1/常用模块.py']
                #python XX.py 运行python文件
print(sys.exit('程序退出'))
quit('程序退出')#退出程序

print(sys.argv)#是获取运行python文件的时候,传入的参数
                #python XX.py 运行python文件

3.json模块  import json

数据

{
    "OPPO": {
        "color": "red",
        "price": 3000,
        "count": 5000
    },
    "华为": {
        "color": "red",
        "price": 5000,
        "count": 10000
    },
    "iphoneX": {
        "color": "red",
        "price": 8000,
        "count": 2000
    }
}
#json串就是字符串,json串里必须是双引号
import json

data={'OPPO':{'color':'red','price':3000,'count':5000},
    '华为':{'color':'red','price':5000,'count':10000},
    'iphoneX':{'color':'red','price':8000,'count':2000}
   }
res=json.dumps(data,indent=4,ensure_ascii=False)#把字典,list转成json,indent缩进空格数,ensure_ascii=False可以显示中文
print(res)
f=open('file1','w',encoding='utf-8')
f.write(res)
f.close()

file1=open('file1',encoding='utf-8')
res=file1.read()
print(type(res))#
dict_res=json.loads(res)#把json串变成python的数据类型
print(type(dict_res))#
print(dict_res)

file2=open('file2','w',encoding='utf-8')
json.dump(data,file2,indent=4,ensure_ascii=False)#自动帮你写入文件,第一个参数是数据,第二个是文件对象

file2=open('file2',encoding='utf-8')
print(json.load(file2))#自动帮你读入文件

4.随机数模块  import random,string

import  random,string
print(random.randint(1,100))#1-100随机取一个整数,包含100
print(string.digits)#所有的数字0-9
print(string.ascii_lowercase)#所有的小写字母
print(string.ascii_uppercase)#所有的大写字母
print(string.ascii_letters)#所有的大写字母+所有的小写字母
print(string.punctuation)#所有特殊字符

s=random.choice(['ybq','mpp','zhx','df'])#随机取一个元素
print(s)

res=random.sample(string.digits,3)#随机取N个元素,随机取3个元素
print(res)#['7', '4', '3']
print(''.join(res))#743

res=random.uniform(1,9)#取随机小数1.734149826467167
print(res)
print(round(res,5))#保留几位小数1.73415

print(random.random())#取0-1之间随机小数0.46297156850072385

s=['a','b','c','d','e']
random.shuffle(s)#洗牌,打乱顺序,只能传list
print(s)#['e', 'c', 'b', 'a', 'd']

5.时间模块  import time

时间的三种表现方式:
  1.格式化好的时间 2018-1-14 16:12
  2.时间戳 是从unix元年到现在所有的秒数
  3.时间元组
想时间戳和格式化好的时间相互转换的话,需先转成时间元组,然后才能转
import time time.sleep(2)#等待几秒

import time
print(int(time.time()))#当前时间戳 1535274440
cur_time=time.strftime('%Y-%m-%d %H:%M:%S')#获取当前格式化时间
print(cur_time)#2018-08-26 17:07:20
print(time.gmtime())#默认取标准时区的时间元组,如果传入了一个时间戳,那么就把这个时间戳转换成时间元组
# time.struct_time(tm_year=2018, tm_mon=8, tm_mday=26, tm_hour=9, tm_min=7, tm_sec=20, tm_wday=6, tm_yday=238, tm_isdst=0)
print(time.gmtime(1535274440))#标准时区
print(time.timezone)#和标准时区差了几个小时 #-28800
print(time.localtime())#默认取当前时区的时间元组,如果传入了一个时间戳,那么就把这个时间戳转换成时间元组
# #time.struct_time(tm_year=2018, tm_mon=8, tm_mday=26, tm_hour=17, tm_min=10, tm_sec=7, tm_wday=6, tm_yday=238, tm_isdst=0)
print(time.localtime(1535274440))#time.struct_time(tm_year=2018, tm_mon=8, tm_mday=26, tm_hour=17, tm_min=7, tm_sec=20, tm_wday=6, tm_yday=238, tm_isdst=0)

cur_time=time.localtime(1535274440)
res=time.strftime('%Y-%m-%d %H:%M:%S',cur_time)
print(res)#2018-08-26 17:07:20

def timestampToStr(time_strmp,format='%Y%m%d%H%M%S'):
    cur_time=time.localtime(time_strmp)#把时间戳转成时间元组
    res=time.strftime(format,cur_time)#再把时间元组转成格式化好的时间
    return res
t=timestampToStr(1535274440,'%Y-%m-%d %H:%M:%S')
print(t)
#time.struct_time(tm_year=2018, tm_mon=8, tm_mday=26, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=238, tm_isdst=-1)

print(time.strptime('20180826','%Y%m%d'))#将格式化的时间转成时间元组
t=time.strptime('20180826','%Y%m%d')
print(time.mktime(t))#将时间元组转成时间戳1535212800.0

def strToimestamp(time_st,format='%Y%m%d%H%M%S'):
    #这个函是格式化好的时间,转时间戳
    t = time.strptime(time_st,format)#把格式化好的时间转成时间元组
    res=time.mktime(t)#把时间元组转成时间戳
    return res
t=strToimestamp('20180826171500')
print(t)#1535274900.0

6.加密模块   import hashlib

import hashlib
ybq_pwd='holleworld'
m=hashlib.md5()
bytes_ybq=ybq_pwd.encode()#把字符串转成bytes类型,中文字符在Python中是以unicode存在的,我们在进行hash前必须把数据转换成bytes类型
m.update(bytes_ybq)#加密,不能字符串,只能传byte类型,二进制
print(m.hexdigest())#加密后的结果

#md5加密是不可逆的,不能被解密的
#撞库
def md5_password(st:str):
    bytes_st=st.encode()#转成二进制类型
    m=hashlib.md5(bytes_st)#加密
    return m.hexdigest()#返回加密后的结果
res=md5_password('123456')
print(res)

sha256=hashlib.sha256(bytes_ybq)
print(sha256.hexdigest())

7.数据库mysql  import pymysql

1.连接mysql,ip,端口号,密码,账号,数据库
2.建立游标
3.执行sql
4.获取结果
5.关闭连接,关闭游标
游标打开仓库的大门:

import pymysql
conn=pymysql.connect(
    host='127.0.0.1',
    user='root',
    passwd='123',
    port=3306,
    db='mydb',
    charset='utf8' #charset必须写utf8,不能写utf-8
)
cur=conn.cursor(cursor=pymysql.cursors.DictCursor)#建立游标,游标你就认为是仓库管理员,设游标类型为字典类型
cur.execute('show tables;')#执行sql语句
res=cur.fetchall()#获取sql执行结果,它把结果放到一个元组里,每一条数据也是一个元组;若指定了游标类型,则按指定的类型输出
print(res)

cur=conn.cursor(cursor=pymysql.cursors.DictCursor)
cur.execute('select * from employee limit 5;')
res=cur.fetchall()
print(res)

cur=conn.cursor(cursor=pymysql.cursors.DictCursor)
cur.execute('select * from employee where emp_id=1')
res=cur.fetchall()
print(res)#[{'emp_id': 1, 'emp_name': '陈一飞', 'emp_wage': 8300.0, 'dept_id': 1}]

cur=conn.cursor(cursor=pymysql.cursors.DictCursor)
cur.execute('select * from employee;')
res=cur.fetchall()
print(res)

cur=conn.cursor()#没有指定游标类型
cur.execute('select * from employee;')
res=cur.fetchall()
print(res[0][2])

cur=conn.cursor(cursor=pymysql.cursors.DictCursor)
sql="INSERT INTO employee (emp_name,emp_wage,dept_id) VALUES('紫薇','2000000',2);"
cur.execute(sql)
conn.commit()#提交;插入或者更新都需要先提交一下
cur.close()#关闭游标
conn.close()#关闭连接

fetchall 和fetchone:


import pymysql
conn=pymysql.connect(
    host='127.0.0.1',
    user='root',
    passwd='123',
    port=3306,
    db='mydb',
    charset='utf8'
)
cur=conn.cursor()
cur.execute('select * from employee')
res=cur.fetchall()
print(res[0])#第一条数据
print(res)#所有的数据

cur=conn.cursor()
cur.execute('select * from employee')
res=cur.fetchone()#只获取一条结果,它的结果是一个一维的元组;只有一条数据,那么就用fetchone,超过一条数据就用fetchall
print(res)#(1, '陈一飞', 6300.0, 1)

#指针的存在
res=cur.fetchone()#下一行数据
print(res)
print('fetchall',cur.fetchall())#指针之后的所有数据
print('fetchone',cur.fetchone())#None 指针移到了最后,什么都读不到了

cur=conn.cursor()
cur.execute('select * from employee;')
res=cur.fetchone()#第一行数据
print(res)
print(cur.fetchall())#指针以后的所有数据
cur.scroll(0,mode='absolute')#移动游标到最前面
print(cur.fetchall())#所有的数据,包括第一行


cur=conn.cursor()
cur.execute('select * from employee;')
res=cur.fetchone()#第一行数据
print(res)
print(cur.fetchall())#指针以后的所有数据,这时指针到了最后一行
cur.scroll(-7,mode='relative')#相对当前位置向后移到7
print(cur.fetchall())#指针以后的所有数据

cur.close()
conn.close()

将操作数据库步骤封装成函数:mysqltools.py


import pymysql
def op_mysql(host,user,passwd,db,sql,port=3306,charset='utf8'):
    conn=pymysql.connect(
        host=host,
        user=user,
        passwd=passwd,
        db=db,
        port=port,
        charset=charset
    )
    cur=conn.cursor(cursor=pymysql.cursors.DictCursor)
    cur.execute(sql)
    sql_start=sql[:6].upper()#取sql前6个字符串,判断它是什么类型的sql语句
    if sql_start=='SELECT':
        res=cur.fetchall()
    else:
        conn.commit()
        res='OK'
    cur.close()
    conn.close()
    return res
sql2='select * from employee;'
res=op_mysql(
    host='127.0.0.1',
    user='root',
    passwd='123',
    db='mydb',
    sql=sql2,
    port=3306,
    charset='utf8'
)
print(res)

使用定义的mysql工具模块

import mysqltools
emp_name=input('plz enter emp_name:').strip()
dept_id=input('plz enter dept_id:').strip()
sql='select * from employee where emp_name="%s";'%emp_name
res=mysqltools.op_mysql(
    host='127.0.0.1',
    user='root',
    passwd='123',
    db='mydb',
    sql=sql,
    port=3306,
    charset='utf8'
    )
print(res)
print(res[0]['dept_id'])
if res:
    if dept_id==str(res[0]['dept_id']):
         print('正确')
    else:
        print('错误')
else:
     print('不存在')

备份数据库

8.数据库redis  import redis

Redis是一个key-value存储系统,它支持丰富的数据类型,如:string、list、set、zset(sorted set)、hash。
Redis特点
Redis以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。以设置和获取一个256字节字符串为例,它的读取速度可高达110000次/s,写速度高达81000次/s。
Redis跟memcache不同的是,储存在Redis中的数据是持久化的,断电或重启后,数据也不会丢失。因为Redis的存储分为内存存储、磁盘存储和log文件三部分,重启后,Redis可以从磁盘重新将数据加载到内存中,这些可以通过配置文件对其进行配置,正因为这样,Redis才能实现持久化。
Redis支持主从模式,可以配置集群,这样更利于支撑起大型的项目,这也是Redis的一大亮点。

需要给环境安装redis和redis.py

这里用的是:redis-2.4.5-win32-win64
window上redis服务端
redis-server.exe
window上redis客户端
redis-cli.exe
window上redis可视化管理工具
redis-desktop-manager.exe


import redis
#r=redis.Redis(host='211.149.218.16',port=6379,password='123456',db=2)#连接redis
r=redis.Redis(host='localhost',port=6379,db=2)#连接本地redis第三个数据库,总共16个数据库(db0-->db15)
r.set('hqg_session','2018012116')#插入值
print(r.get('hqg_session'))#取值  b'2018012116'
print(r.get('hqg_session').decode())#2018012116 redis里面取出来的数据都是bytes类型的,所以要用decode方法转成字符串

r.set('qaz','qwe')#插入值
print(r.get("qaz"))#取值  b'qwe'
r.delete('qaz')#删除
print(r.get('qaz'))#None

r.setex('edc','hahahh','20')#可以指定key的失效时间,单位是秒

hash类型

import redis
#连接
r=redis.Redis(host='localhost',port=6379,db=2)

#插入值
r.hset('230_session','qew','123')#hash类型插入数据
r.hset('230_session','asd','1234')
r.hset('230_session','zxc','12345')

#取值
print(r.hget('230_session','qew'))#b'123'
print(r.hget('230_session','qew').decode())#123
print(r.hgetall('230_session'))#{b'zxc': b'12345', b'qew': b'123', b'asd': b'1234'}

#遍历取值
redis_data=r.hgetall('230_session')
all_data={}
for k,v in redis_data.items():
    k=k.decode()
    v=v.decode()
    all_data[k]=v
print(redis_data)       #{b'qew': b'123', b'zxc': b'12345', b'asd': b'1234'}
print(all_data)         #{'qew': '123', 'zxc': '12345', 'asd': '1234'}

#hash类型没有过期时间
r.set('try:homework:er','白')#在db2/try/homework/目录下key:try:homework:er;value:'白'
r.set('try:homework:ty','黑')#在db2/try/homework/目录下key:try:homework:ty';value:''

print(r.keys())#获取所有的key            [b'hqg_session', b'230_session', b'try:homework:er', b'try:homework:ty']
print(r.keys('try*'))#以txz开头的key    [b'try:homework:er', b'try:homework:ty']
print(r.type('try:homework:er'))#获取key的类型   b'string'
print(r.type('hqg_session'))                    #b'string'

将redis连接封装成函数

def op_redis(host,passwd,k,v,port=6379,db=0):
    if passwd!='':
        r=redis.Redis(host=host,passwd=passwd,port=port,db=db)
    else:
        r = redis.Redis(host=host,port=port, db=db)
    if v:
        r.set(k,v)
        res='ok'
    else:
        res=r.get(k)
        if res:#这里是判断有没有get到数据
            res.decode()
        else:
            res=None
        return res
#op_redis(host='localhost',passwd='',k='hqg_session',v='2018012119',db=2)

redis数据迁移小程序:

import redis
src_redis = redis.Redis(host='127.0.0.1',port=6379,db=14)#连上redis
target_redis = redis.Redis(host='127.0.0.1',port=6379,db=2)#连上redis
for key in src_redis.keys():
    if src_redis.type(key) == b'string':  #判断key的类型,因为redis数据取出来都是二进制的,所以这里也用bytes
        v = src_redis.get(key)              #先获取到原来的数据
        target_redis.set(key,v)             #再set到新的里面
    else:
        all_hash_data = src_redis.hgetall(key)   #先获取到hash类型里面所有的数据
        for k,v in all_hash_data.items():       #因为hash类型的获取到之后是一个字典,所以这里循环字典
            target_redis.hset(key,k,v)           #key是外面的大key,k是里面的小k,v就是小k对应的value

9.flask模块写接口  import flask,json

注:拼写sql时,即使是其他数据类型也需要用%s来格式化
例如:
http://127.0.0.1:8080/add_user?emp_name=“Tom”&emp_wage=100000&dept_id=2
其中在数据库emp_wage为double;dept_id为int
合法SQL如下:
sql = ‘INSERT INTO employee (emp_name,emp_wage,dept_id) VALUES(%s,%s,%s);’%(emp_name,emp_wage,dept_id)

import flask,json
from mysqltools import op_mysql  #op_mysql()
# 接口,后台服务
server = flask.Flask(__name__) #把咱们这个app这个python文件当做一个server

@server.route('/')
def helloworld():
    return "helloworld"

@server.route('/get_user',methods=['get','post'])
def get_all_user():
    sql = 'select * from employee;'
    res = op_mysql(
        host='127.0.0.1',
        user='root', passwd='123',  # port这里一定要写int类型
        port=3306, db='mydb', charset='utf8', sql=sql)
    response = json.dumps(res,ensure_ascii=False) #把list转成json
    return response #return 的时候只能return字符串

@server.route('/add_user',methods=['get','post'])
def add_user():
    #emp_id = flask.request.values.get('emp_id')  #这里的参数就是调用接口的时候传入的参数
    emp_name = flask.request.values.get('emp_name') #
    emp_wage = flask.request.values.get('emp_wage') #
    dept_id = flask.request.values.get('dept_id') #
    if emp_name and emp_wage and dept_id:
        sql = 'INSERT INTO employee (emp_name,emp_wage,dept_id) VALUES(%s,%s,%s);'%(emp_name,emp_wage,dept_id)
        res = op_mysql(
            host='127.0.0.1',
            user='root', passwd='123',  # port这里一定要写int类型
            port=3306, db='mydb', charset='utf8', sql=sql)
        response = {'code':200,'msg':'添加成功'}
    else:
        response = {'code':503,'msg':'必填参数未填!'}
    return json.dumps(response,ensure_ascii=False)
server.run(port=8080,debug=True)

#访问:    http://127.0.0.1:8080/

#访问:    http://127.0.0.1:8080/get_user

#该方法允许get或post请求方式
#访问:    http://127.0.0.1:8080/add_user?emp_name="Tom"&emp_wage=100000&dept_id=2

面向对象编程,类

属性:属性就是里面的一个变量,有类变量和实例变量,类变量是类在定义的时候就有的,实例变量是在实例化的时候才产生的变量。这个可以理解为,人是一个类,他的名字,年龄,性别就是它的属性

方法:方法就是类的功能,也就是定义在类里面的函数,它实现了某个功能,比如说人有睡觉的功能。

构造函数:就是类在实例化的时候做的某些初始化操作

析构函数:就是这个实例在销毁的时候做的一些操作

1.定义类

# 定义类使用class关键字,类名一般首字母大写。
class Car():#模型,模板
    def __del__(self):
        #析构函数,这个实例被销毁的执行的。
        print('over..')

    def my_self(self):
        print(
            '我是一个汽车 我的颜色是【%s】,我有【%s】个窗户'%(self.color,self.window)
        )
        self.price = 10002
    def run(self):
        print(self.color)
        print(self.window)
        print(self.price)
        print('汽车在跑。。。')

    def __init__(self,color,window):
        #
        #构造函数,是类在初始化的时候会执行它
        #如果你的类在实例化的时候要传入一些参数,那么你就要在__init__这个函数里写参数了
        self.color = color  #绑定属性
        self.window = window
        print('执行我了。。')

#把模型做成实际的一个汽车,这个过程叫做实例化。
bus = Car('黄色','3开门') #实例化
bus2 = Car('黑色','4开门') #实例化
bus3 = Car('粉色','2开门') #实例化
bus.my_self()   #
bus2.my_self()
bus3.my_self()
#实例就是指具体造出来的东西,通过类实例化处理的东西,就是实例
#对象,就是实例

结果
执行我了。。
执行我了。。
执行我了。。
我是一个汽车 我的颜色是【黄色】,我有【3开门】个窗户
我是一个汽车 我的颜色是【黑色】,我有【4开门】个窗户
我是一个汽车 我的颜色是【粉色】,我有【2开门】个窗户
over..
over..
over..

2.继承

class WssFather(object):
    @property
    def money(self):
        return 10000000
    def smoke(self):
        self.yan = '玉溪'
        print('抽烟')
    def drink(self):
        print('喝酒')
    def tangtou(self):
        print('烫头')

class Wss(WssFather):
    def driver(self):
        print('开车')

class Animal(object):
    def eat(self,name):
        print('吃')

class Brid(Animal):
    pass

3.实例变量

class Person(object):
    country = 'China' #类变量
    def __init__(self,name,age,sex):
        self.name=name #实例变量,必须实例化之后才能用,成员变量
        self.age=age
        self.sex=sex

    def say_my_country(self):
        print(self.country)

print(Person.country)
dsx = Person('小师妹',23,'女')
print(dsx.name)
print(dsx.age)
print(dsx.sex)
print(dsx.country)

结果
China
小师妹
23

China

4.静态方法,类方法

#准备数据
import redis
r=redis.Redis(host='localhost',password='',port=6379,db=0)#连接本地redis数据库
r.set('hqg_session','2018012116')
import redis
class MyRedis():
    xiaohei = '哈哈哈'
    def __init__(self,host,password='',port=6379,db=0):
        self.__host = host #私有属性
        self.passwd = password
        self.port = port
        self.db = db
        self.__coon_redis()
        print('__init__')
    def __coon_redis(self): #私有方法,默认连接redis的db0数据库
        self.coon = redis.Redis(host=self.__host,password=self.passwd,port=self.port,db=self.db)
        print('__coon_redis')
    def get(self,k):
        print('__host...',self.__host)
        return self.coon.get(k).decode()

    @staticmethod   #类方法,属于类
    def other():
        print('我是other')
    @classmethod
    def class_fun(cls):
        print(cls.xiaohei)
        cls.class_fun2()
    @classmethod
    def class_fun2(cls):
        print('我是类方法2')
# 通过实例对象方法私有方法
r = MyRedis('127.0.0.1','')
print(r.get('hqg_session'))
#通过类名调用类方法
MyRedis.class_fun()

结果:

__coon_redis
__init__
__host... 127.0.0.1
2018012116
哈哈哈
我是类方法2

5.小练习

#签名,作用为了作弊
#sign :82B20DE4-40C2-4859-9DBC-C93B0FBFD09C
#1.先取用户的设备号码,md5 加密一次
#2.再取加密之后前10位
#3.再加盐,再给md5一次
#4.最后生成一个字符串
from hashlib import md5
class GetSign(object):
    slat='SDF234_&#$_12'#加盐
    def __init__(self,device_id):
        self.device_id=device_id
    def md5(self,str):
        #md5加密的
        s=str.encode()
        m=md5(s)
        return m.hexdigest()
    @property #把这个函数变成一个属性方法 ,如果这个方法没有入参,那就可以给变成一个属性方法
    def get_res(self):
        first_md5 = self.md5(self.device_id)
        tmp = first_md5[:10] #取前10位
        after_salt = tmp+self.slat
        self.sign = self.md5(after_salt)
        return self.sign
res = GetSign('82B20DE4-40C2-4859-9DBC-C93B0FBFD09C')
print(res.device_id)
print(res.get_res)
# 82B20DE4-40C2-4859-9DBC-C93B0FBFD09C
# bba2a4fc0016e0ed3a329f1d078964bf

6.写日志

import logging
from logging import handlers

class Logger(object):
    level_relations = {
        'debug': logging.DEBUG,
        'info': logging.INFO,
        'warning': logging.WARN,
        'error': logging.ERROR,
        'crit': logging.CRITICAL
    }  # 日志级别关系映射

    def __init__(self, fp, level='debug', when='midnight', interval=1, backCount=5, encoding='utf-8'):
        '''

        :param fp:日志文件路径
        :param level: 日志级别 默认是debug
        :param when: 分割日志的单位 S 秒、M 分、 H 小时、 D 天、 W 每星期(interval==0时代表星期一)、midnight 每天凌晨
        :param interval: 时间间隔 默认每天凌晨
        :param backCount: 备份文件个数 默认5个
        :param encoding: 日志文件编码
        '''
        self.level = self.level_relations.get(level)
        self.logger = logging.getLogger(fp)
        self.logger.setLevel(self.level)
        fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
        sh = logging.StreamHandler()
        sh.setFormatter(fmt)
        sh.setLevel(self.level)
        th = handlers.TimedRotatingFileHandler(fp, when=when, interval=interval, backupCount=backCount,
                                               encoding=encoding)
        th.setFormatter(fmt)
        th.setLevel(self.level)
        self.logger.addHandler(th)
        self.logger.addHandler(sh)

    def debug(self, msg):
        self.logger.debug(msg)

    def info(self, msg):
        self.logger.info(msg)

    def warning(self, msg):
        self.logger.warning(msg)

    def error(self, msg):
        self.logger.error(msg)

    def crit(self, msg):
        self.logger.critical(msg)

if __name__ == '__main__':
    l = Logger('a.log')  # 实例化
    l.info('hehehe')  # 调用
    l.debug('哈哈哈')
    l.error('xxx')

a.log文件内容:
2018-08-27 17:06:38,119 - G:/python/python_01/demo1/使用flask.py[line:204] - INFO: hehehe
2018-08-27 17:06:38,120 - G:/python/python_01/demo1/使用flask.py[line:201] - DEBUG: 哈哈哈
2018-08-27 17:06:38,120 - G:/python/python_01/demo1/使用flask.py[line:210] - ERROR: xxx

7.练习

class My():
    def __init__(self,name):
        self.name = name
        self.cry()
    def cry(self): #实例方法,必须得实例化后才可以调用
        print('%s在哭。。。'%self.name)
    def learn(self):
        self.skill = ['开车']
    def my_self(self):
        print('我的名字【%s】 我会%s'%(self.name,self.skill))

wsl = My('小黑黑') #    self = wsl
wsl.skill = '黑'
wsl.learn()
wsl.skill.append('花')
wsl.skill.append('话')
wsl.skill.append('滑')
wsl.my_self()
wsl.learn()
wsl.my_self()
td = My('蘑菇')

小黑黑在哭。。。
我的名字【小黑黑】 我会[‘开车’, ‘花’, ‘话’, ‘滑’]
我的名字【小黑黑】 我会[‘开车’]
蘑菇在哭。。。

8.连接数据库


import pymysql
class OpMySql1:  #经典类
    pass

class OpMySql(object):#新式类
    def __init__(self,host,user,password,db,port=3306,charset='utf8'):
        schema = {
            'user':user,
            'host':host,
            'password':password,
            'db':db,
            'port':port,
            'charset':charset
        }
        try:
            self.coon = pymysql.connect(**schema)
        except Exception as e:
            print('数据库连接异常!%s'%e)
            quit('数据库连接异常!%s'%e)
        else:#没有出异常的情况下,建立游标
            self.cur = self.coon.cursor(cursor=pymysql.cursors.DictCursor)

    def execute(self,sql):
        try:
            self.cur.execute(sql)
        except Exception as e:
            print('sql有错误%s'%e)
            return e
        if sql[:6].upper()=='SELECT':
            return self.cur.fetchall()
        else:#其他sql语句的话
            self.coon.commit()
            return 'ok'

    def __del__(self):
        self.cur.close()
        self.coon.close()

ybq = OpMySql('127.0.0.1','root','123',db='mydb')  #实例化
print(ybq.execute('select * from employee;'))

9.url编码

import urllib.parse
s='besttest 自动化测试'
print(urllib.parse.quote(s)) #url编码
print(urllib.parse.quote_plus(s)) #url编码,
print(urllib.parse.unquote('besttest%20%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95')) #url解码
print(urllib.parse.unquote_plus('besttest+%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95')) #url解码
# besttest%20%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95
# besttest+%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95
# besttest 自动化测试
# besttest 自动化测试

10. self代表本类对象

修改父类的方法:
重写父类的方法的目的是为了给他扩展一些功能
核心思想就一句话,先调用一下你要重写的父类方法,然后再加新的代码就好了。

class Coon(object):
    #基类
    def __init__(self,host,passwd,port):
        self.host=host
        self.passwd=passwd
        self.port=port
class CoonMySql(Coon):
    def __init__(self,host,passwd,port,username,db,charset='utf8'):
        Coon.__init__(self,host,passwd,port)#在调用父类的构造方法,咱们自己手动调用父类的方法
        self.username=username
        self.db=db
        self.charset=charset
    def coon_mysql(self):
        print(self.host)


class Coon(object):
    #基类
    def __init__(self,host,passwd,port):
        self.host=host
        self.passwd=passwd
        self.port=port
class CoonMySql(Coon):
    def __init__(self,host,passwd,port,username,db,charset='utf8'):
        super(CoonMySql,self).__init__(host,passwd,port)#super自动帮忙找到父类,然后调用
        self.username=username
        self.db=db
        self.charset=charset
    def coon_mysql(self):
        print(self.host)

异常处理

import pymysql
def main2(sql):
    try:
        conn=pymysql.connect(host='127.0.0.1',user='root',password='123',db='mydb')
    except Exception as e:
        print('数据库连接不了,%S'%e)
    else:
        cur=conn.cursor()
        try:
            cur.execute(sql)
        except Exception as e:
            print('sql语句有错误!%s是%s'%(e,sql))
        else:
            res=cur.fetchall()
            return res
        finally:#不管有没有捕捉到异常,都会走这里
            cur.close()
            conn.close()

res = main2("select * from employee;")
print(res)

列表,元组,集合,字典,json互相转换


#1.字典
dict = {'id':'001','name':'Tom','age':18,'sex':'male'}
# 1.1字典-->字符串
print(type(str(dict)),str(dict))
#1.2字典-->元组
print(tuple(dict))
print(dict.values)
#1.3字典-->列表
print(list(dict))
print(dict.values)

#2.元组
tup = (1,2,3,4,5)
#2.1元组-->字符串
print(tup.__str__())
#2.2元组-->列表
print(list(tup))
#2.3元组不可以转为字典

#3.列表
nums = [1,3,5,13,15,20]
#3.1列表-->字符串
print(str(nums))
#3.2列表-->元组
print(tuple(nums))
#3.3列表不可以转为字典

#4.字符串
#4.1字符串-->元组
print(tuple(eval("(1,2,3)")))
#4.2字符串-->列表
print(list(eval("(1,2,3)")))
#4.3字符串-->字典
print(eval("{'id':'001','name':'Tom','age':18,'sex':'male'}"))

#5.json
#loads():将json数据转换成dict数据
#dumps():将dict数据转换成json数据
#load():读取json文件数据,转成dict数据
#dump():将dict数据转换成json数据后写入json文件
#5.1字典转json
def dict2json():
    dict = {}
    dict['id'] = '001'
    dict['name'] = 'Tom'
    dict['age'] = 18
    dict['sex'] = 'male'
    print(dict)
    j = json.dumps(dict)
    print(j)

#5.2json转字典
def json2dict():
    j = {'id':'001','name':'Tom','age':18,'sex':'male'}
    dict = json.loads(s=j)
    print(dict)
#5.3对象转json
class Student(object):
    def __init__(self,id,name,age,sex):
        self.id=id
        self.name=name
        self.age=age
        self.sex=sex

def obj2json():
    stu = Student('001','Tom',18,'male')
    #对象转字典
    stu = stu.__dict__
    #字典转json
    j = json.dumps(obj=stu)
    print(j)
#5.4json转对象
def json2obj():
    j = {'id':'001','name':'Tom','age':18,'sex':'male'}
    dict = json.loads(s=j)
    stu  = Student()
    stu.__dict__ = dict
    print('id:'+stu.id+'name:'+stu.name+'age:'+str(stu.age)+'sex:'+stu.sex)
#5.5写dict-->json文件
import json
def dict2jsonfile():
    dict = {}
    dict['id'] = '001'
    dict['name'] = 'Tom'
    dict['age'] = 18
    dict['sex'] = 'male'
    print(dict)
    with open('1.json','w') as f:
        json.dump(dict,f)
#5.读json文件-->dict
def jsonfile2dict():
    with open('1.json','r') as f:
        dict = json.load(fp=f)
        print(dict)


#列表
list1 = [1,3,4,3,2,5]
#元组
tuple1 = (1,3,4,5,7)
#集合(去重)
set1 = {1,3,4,3,2,5}    #{1, 2, 3, 4, 5}
#字典
dict1 = {1: 'a', 2: 'b', 3: 'c'}
s = '17789'
print(tuple(s))#('1', '7', '7', '8', '9')
print(type(tuple(s)))#
print(list(s))#['1', '7', '7', '8', '9']
print(type(list(s)))#

#----------------------------------------------------------
#字符串转元组
def str2tuple1(str):
    return tuple(eval(str))

str1 = "(1,2,3)"
res = str2tuple1(str1)
print(res)#(1, 2, 3)
print(type(res))#
#----------------------------------------------------------
#字符串转列表
def str2list1(str):
    return list(eval(str))

str1 = "(1,2,3)"
res = str2list1(str1)
print(res)#[1, 2, 3]
print(type(res))#
#----------------------------------------------------------
#字符串转字典
def str2dict1(str):
    return (eval(str))

str1 = "{1:'a',2:'b',3:'c'}"
res = str2dict1(str1)
print(res)#{1: 'a', 2: 'b', 3: 'c'}
print(type(res))#



#----------------------------------------------------------
#元组转字符串
def tuple2str(tuple):
    return tuple.__str__()
res = tuple2str(tuple1)
print(res)#(1, 3, 4, 5, 7)
print(type(res))#
#----------------------------------------------------------
#列表,元组转字符串
def listortuple2str(listortuple):
    return "".join(listortuple)

res = listortuple2str("('1', '7', '7', '8', '9')")
print(res)#[1, 3, 4, 3, 2, 5]
print(type(res))#
res = listortuple2str("['1', '7', '7', '8', '9']")
print(res)#[1, 3, 4, 3, 2, 5]
print(type(res))#
#----------------------------------------------------------
#其他转字符串
def other2str(other):
    return str(other)

res = other2str(dict1)
print(res)#[1, 3, 4, 3, 2, 5]
print(type(res))#



#----------------------------------------------------------
#字符串转列表
def str2list(str):
    return list(str)

str1 = '1314'
res = str2list(str1)
print(res)#['1', '3', '1', '4']
print(type(res))#
#----------------------------------------------------------
#字符串转集合
def str2set(str):
    return set(str)

str1 = '1314'
res = str2set(str1)
print(res)#{'1', '4', '3'}
print(type(res))#
#----------------------------------------------------------
#字符串转元组
def str2tuple(str):
    return tuple(str)

str1 = "17789"
res = str2tuple(str1)
print(res)#('1', '7', '7', '8', '9')
print(type(res))#
#----------------------------------------------------------
#字符串转字典
def str2dict(str):
    return eval(str)

str1 = "{1: 'a', 2: 'b', 3: 'c'}"
res = str2dict(str1)
print(res)#{1: 'a', 2: 'b', 3: 'c'}
print(type(res))#



#----------------------------------------------------------
#字典转元组
def dict2tuple1(dict):
    #return tuple(dict)
    return tuple(dict.values())

res = dict2tuple1(dict1)
print(res)#(1, 2, 3)
print(type(res))#

def dict2tuple2(dict):
    return tuple(dict.values())
res = dict2tuple2(dict1)
print(res)#('a', 'b', 'c')
print(type(res))#
#----------------------------------------------------------
#字典转列表
def dict2list1(dict):
    return list(dict)
res = dict2list1(dict1)
print(res)#[1, 2, 3]
print(type(res))#

def dict2list2(dict):
    return dict.values()
res = dict2list2(dict1)
print(res)#dict_values(['a', 'b', 'c'])
print(type(res))#


#----------------------------------------------------------
#元组转列表
def tuple2list(tuple):
    return list(tuple)
res = tuple2list(tuple1)
print(res)#[1, 3, 4, 5, 7]
print(type(res))#

#----------------------------------------------------------
#元组不能转字典

#----------------------------------------------------------
#元组转列表
def list2tuple(list):
    return tuple(list)
res = list2tuple(tuple1)
print(res)#(1, 3, 4, 5, 7)
print(type(res))#
#----------------------------------------------------------
#列表不能转字典

部分引用自:https://www.cnblogs.com/wxcx/

你可能感兴趣的:(python)