一 python基础
1.Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
字符串的截取的语法格式如下:变量[头下标:尾下标:步长] 尾下标不可取
str= ' chenrui '
print(str[1:-1]) 输出 henru
print(str*2) 输出chenruichenrui
print(str+'你好') 连接字符串 输出chenrui你好
2. print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end='':
print('chen', end='')
print('rui')
输出chenrui
3.
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
比如str='chen'
str[1]='m' 是错误的,不能重新复制
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
4.list列表 可变元素,写在[ ]内
可以存放不同类型元素,可以切片,分割。与字符串不同的是,列表可以更改元素
a=[123 , 'cccc' , 2.7 , 19 , 'a' ]
(1)切片
c=a[1:4:2] #c=['cccc' , 19]
(2)判断元素在不在里面
>>> 123 in a
True
(3)长度
>>> len(a)
5
(4) list.append(x) 在列表尾部插入x
(5) list.insert(x,y) 在list[x]处插入y
(6) list.count(x) 统计列表中元素x出现次数
(7)list.remove(x) 移除列表中指定值
(8)list.reverse() 反转列表
(9)list.extend(b) 将列表b添加到尾部
(10)list.sort() 列表由小到大排序
(11)del list[1] 删除该元素
(12)栈与队列
list.pop([index=-1]) pop函数默认弹出最后一个元素 且list也会减少一个元素
现有列表a[1,2,3,4,5,6]
要实现栈 就一直用 a.pop() , a.apend(x)
要实现队列 就一直用 a.pop(0) , a.apend(x)
(13)列表推导式由包含一个表达式的中括号组成,表达式后面跟随一个 for 子句,之后可以有零或多个 for 或 if 子句。结果是一个列表,由表达式依据其后面的 for 和 if 子句上下文计算而来的结果构成。
>>> list = [x**2 for x in range(10)] # list = [0, 1, 4, 9, .....81]
x ** 2就是表达式 将表达式后面的语句的计算结果依次带入表达式,生成一个列表
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
(x,y)是表达式
5.tuple 元组 不可变元素 写在()内 用逗号分隔
a=(123 , 'chen' , 'aa' )
a[1: ] # ('chen' , 'aa')
a=(123) # type(a)==int
a=(123,) # type(a) == tuple
6. set 集合 无序 无重复元素 {}或set()创建
(1)消除重复
>>> a = {1,3,4,1,3,2}
>>> print(a)
{1,3,4,2} 重复元素被消除
或者用set()函数创建
>>> a = set('chenrui') # a={'c', 'h', 'e', 'n', 'r', 'u', 'i'}
>>> a = set( ['chen', 'rui', 123,789] ) # a={'chen', 'rui', 123,789}
(2)交 并 差 对称差集
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # a 去重后的字母{'a', 'r', 'b', 'c', 'd'}
>>> a - b # 差 {'r', 'd', 'b'}
>>> a | b # 联合 {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b #交{'a', 'c'}
>>> a ^ b # 对称差集 存在于 a 或 b 但不同时存在的字母{'r', 'd', 'b', 'm', 'z', 'l'}
(3)集合推导式
a = { x for x in 'abcdefg' if x not in 'abcd'}
# a = {'e', 'f', 'g'}
(4)各种方法
http://www.runoob.com/python3/python3-set.html
7.字典 键唯一 但一个键可以有多个值 (通过列表实现)
a = {'chen' : 'rui' , 'asc':' asd', 'cccc':'wqe'}
a= {'chen':['asd', 'asdqwq', '123'], 'rui':'ee', 'man':'bbb'}
(1)用dict()从包含键值对的元组中创建
a = dict( ( ('chen', 'rui'), ('asd', 'cx'),('asdqqq','wqezz') ) )
则a = {'chen':'rui', 'asd':'cx', 'asdqqq':'wqezz'}
(2) del删除
del a['chen']
(3) 遍历一个字典,使用字典的 items() 方法。
>>> data
{'Kushal': 'Fedora', 'Jace': 'Mac', 'kart_': 'Debian', 'parthan': 'Ubuntu'}
>>> for x, y in data.items():
print("{} uses {}".format(x, y))
(4)setdefault(key, default) 与 get(key, default)
a.setdefault('name', 0) #如果a没有'name'这个键,则创建该键,并且值为0. 否则返回name键的值
a.get('name', 0) #有name键 返回对应的值。否则返回0
(5)zip() 函数
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
我们可以使用 list() 转换来输出列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 返回一个对象
>>> zipped
>>> list(zipped) # list() 转换为列表[(1, 4), (2, 5), (3, 6)]
>>> list(zip(a,c)) # 元素个数与最短的列表一致[(1, 4), (2, 5), (3, 6)]
>>> list(zip(a,b,c)) # [(1,4,4), (2,5,5), (3,6,6)]
>>> a1, a2 = zip(*zip(a,b)) # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式
>>> list(a1)
[1, 2, 3]
>>> list(a2)
[4, 5, 6]
需要同时遍历两个序列类型,你可以使用 zip() 函数。
>>>a= ['Pradeepto','Kushal']
>>>b= ['OpenSUSE','Fedora']
>>>for x, y in zip(a, b):
print("{} uses {}".format(x, y))
输出 Pradeepto uses OpenSUSE
Kushal uses Fedora
8. *用于赋值
利用 * 表达式获取单个变量中的多个元素,只要它的解释没有歧义即可。* 获取的值默认为 list
>>> a, b, *c =0,1,2,3
>>> a
0
>>> b
1
>>> c
[2,3]
9. str.format() 利用{}和:
数字格式化
print( ' {:7.2f } '.format(3.141595) ) #3.14 后面3个空格 注:小数点也占一位
print( ' {this is a {:x>4d}} '.format(10) ') # this is a xx10
print( ' {this is a {:x<4d}} '.format(10) ' ) # this is a 10xx
可以传入参数
day,name=12,'chen'
print(' today is {} , my name is {} '.format(day,name) )
也可以不格式化
print( ' x= ' , x)
10.逻辑运算符 and or not
逻辑运算符 and 和 or 也称作短路运算符:它们的参数从左向右解析,一旦结果可以确定就停止。例如,如果 A 和 C 为真而 B 为假,A and B and C 不会解析 C 。作用于一个普通的非逻辑值时,短路运算符的返回值通常是能够最先确定结果的那个操作数。
5 or 4 返回5
3 and 0 and 1 返回0
not 具有最高的优先级,or 优先级最低,所以 A and not B or C 等于 (A and (notB)) or C
11. if for while
(1) if
if :
pass
elif:
pass
else:
(2)for 与 range()与for else
a=[123 , 'asd' , 456]
for x in a:
print (x)
range(5)产生一个0-4的对象,不是列表
>>> a = range(5)
>>> a
range(5)
>>> b = list(a)
>>> b
[0,1,2,3,4]
range(1,5,2)产生一个1-4的数列且步长为2 即1 , 3
for x in range(len(a)) :
print(a[x])
在循环后面使用可选的 else 语句。它将会在循环完毕后执行,除非有 break 语句终止了循环。可以用来检测for循环是否正常执行完
for i in range(0, 5):
print(i)
else:
print("Bye bye")
0
1
2
3
4
Bye Bye
(3)while
while n<10:
pass
while ...else ...用法与for相同
12.字符串
(1)str.split(str,num) 返回字符串被分割后的列表
str --分割依据,默认为空格 num --分割次数
txt = "Google#Runoob#Taobao#Facebook"
x = txt.split("#", 1) # 第二个参数为 1,返回两个参数列表 ['Google', 'Runoob#Taobao#Facebook']
(2)str.strip(char) 剥离字符串中的指定字符 默认为首尾的空格和换行符
a = 'abcdefg...'
a.strip('bcd.') #剥离字符串中的 'b', 'c', 'd', '.'字符
a = 'aefg'
(3)str.find(char) 找到第一个匹配的子字符串,没有找到则返回 -1。
s = "faulty for a reason"
s.find("for")
7
s.find("fora")
-1
(4)%格式化操作符 与c类似 多了括号和%
name = 'chen'
print('my name is %s and my age is %d' % (name,16))
13.函数
(1)def函数名(参数):
语句1
语句2
(2)global 关键字告诉编译器后面的变量是全局的 即使在内部改动也会影响外部的值
def change():
global a
a = 90
print(a)
a = 9
print("Before the function call ", a) #a=9
print("inside change function", end=' ')
change() # a=90
print("After the function call ", a) # a= 90
如果没有global 函数内的a是局部变量,与外面的a没有关系
(3)默认参数值
def f(a , b=-99):
pass
注:1. 具有默认值的参数后面不能再有普通参数,比如 f(a,b=90,c) 就是错误的
2. 默认值只被赋值一次,因此如果默认值是任何可变对象时会有所不同,比如列表、字典或大多数类的实例。例如,下面的函数在后续调用过程中会累积(前面)传给它的参数:
deff(a, data=[]): #默认参数是列表 可变的。
data.append(a)
return data
print(f(1))
[1]
print(f(2)) #此时调用f(), data的默认值为[1]
[1, 2]
print(f(3))
[1, 2, 3]
要避免这个问题,你可以像下面这样:
def f(a, data=None): #None不是可变对象,所以作为默认值时,data的值不会积累。
#即下次调用f时,data值还是None。设置为data=123也是一样的效果。123是字面量,不 #可变,值不会积累
if data is None:
data = []
data.append(a)
return data
print(f(1)) # [1]
print(f(2)) # [2]
(4)关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple,而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
def person(name, age, **kw):
print('name:', name,'age:', age,'other:', kw)
函数person除了必选参数name和age外,还接受关键字参数kw,前面两个**。在调用该函数时,可以只传入必选参数:
>>> person('Michael',30)
输出 name:Michaelage:30other:{}
也可以传入任意个数的关键字参数:
>>> person('Bob',35, city='Beijing') # key=value 调用时若key,value均为字符串key不能加引号,value要加
name:Bob age:35 other:{'city':'Beijing'}
>>> person('Adam',45, gender='M', job='Engineer')
name:Adam age:45 other:{'gender':'M','job':'Engineer'}
关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
>>> extra = {'city':'Beijing','job':'Engineer'} #先组装一个dict
>>> person('Jack',24, city=extra['city'], job=extra['job'])
name:Jack age:24 other:{'city':'Beijing','job':'Engineer'}
当然,上面复杂的调用可以用简化的写法:
>>> extra = {'city':'Beijing','job':'Engineer'}
>>> person('Jack',24, **extra)
name:Jack age:24 other:{'city':'Beijing','job':'Engineer'}
**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
(5)可变参数(列表参数)
(7)强制关键字参数
defdog(name, host, *, age):
print(name, host, age)
参数中有一个 “*” 号,在该符号之后的所有参数(可一至多个)均被称为强制关键字参数,如果按照位置参数的方式对这些参数传值:
dog('dobi','xuzhoufeng',2)
TypeError: dog() takes 2 positional arguments but 3 were given
就会出现 TypeError,正确的传值形式为:
dog('dobi', 'xuzhoufeng', age =2)
dobi xuzhoufeng 2
也即这里的age 必须使用关键字参数的形式进行传值。
(8)map函数
map 是一个在 Python 里非常有用的高阶函数。它接受一个函数和一个序列(迭代器)作为输入,然后对序列(迭代器)的每一个值应用这个函数,返回一个迭代器,不是现成的列表,其包含应用函数后的结果。
举例:
>>> lst = [1,2,3,4,5]
>>> def square(num):
returnnum * num
>>> print(list(map(square, lst)))
[1,4,9,16,25]
又:
list(map(lambda x,y:x+y, [1,2,3,4], [1,2,3,4]))
结果是 [2,4,6,8]
(9) enumerate()函数
用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
list = ['Spring', 'Summer', 'Fall', 'Winter']
for i, x in enumerate(list):
print(i, x)
输出:
0 Spring
1 Summer
2 Fall
3 Winter
14.文件
(1)open() close()
r --只读
r+ --打开一个文件用于读写。文件指针将会放在文件的开头
w --以写入模式打开,如果文件存在将会删除里面的所有内容,然后打开这个文件进行写入
w+ --打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该 文件不存在,创建新文件
a --以追加模式打开,写入到文件中的任何数据将自动添加到末尾
a+ --打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如 果该文件不存在,创建新文件用于读写。
file_object = open('filename'[,'r/w/a']) #open()返回一个对象,第一个参数为文件名,第二个默认为r。
file_object.close() #用完一定要关闭
(2)读取
file_object.read([size]) #默认读完整个文件 返回的是字符串
file_object.readline() #读一行
file_object.readlines() #读所有行 以列表形式保存
比如 file_object = open('sample.txt')
>>> file_object.readlines()
['I love Python\n', 'I love shiyanlou\n']
也可以循环的方式读
for x in file_object:
print(x, end='')
输出 :
I love Python
I love shiyanlou
注:可以把读的结果给一变量 s = file_object.read() print(s)
for i in file_object : # i 此时是一行一行的字符串
pass
for i in file_object.read() : # i 此时是一个一个的字符
pass
(3)write() 写入
file_object = open('test.txt','w')
file_object.write('this is a test\n') # 'w'模式下会清空文件再写
(4) sys模块中的argv sys.argv[]
用于在命令行模式中获取参数
假设sample.py 文件用于文件的拷贝
```
import sys
file1 = open(sys.argv[1]) #sys.argv[1]具体是什么要取决于命令传入的参数
s = file1.read()
file2 = open(sys.argv[2], 'w')
file2.write(s)
```
$ python3 sample.py newfile.py #此处即为命令行命令 第一个参数永远是文件路径及文件名第二个参数是 #sample.py 第三个是newfile.py
则sys.argv[0] = 文件路径及文件名
sys.argv[1] = sample.py
sys.argv[2] = newfile.py
(5)with语句
with 语句处理文件对象,它会在文件用完后会自动关闭,就算发生异常也没关系。它是 try-finally 块的简写:
>>>
with open('sample.txt') as fobj:
for line in fobj:
print(line, end ='')
输出:
I love PythonI
love shiyanlou
15.异常 一定要看这篇博客https://www.cnblogs.com/wj-1314/p/8707804.html
注:博客中没有提到的如下
(1)try语句执行遇到错误会抛出给except捕获并保存当前pc,若捕获失败,则程序终止。捕获成功,执行该except下的语句,执行完后从原pc继续执行try语句
异常处理是为了在程序运行发生错误时不让程序终止运行,而是抛出一个自定义的语句来提醒用户发生了错误,
except用来捕捉程序运行时发生的错误。如果发生的错误没被except捕捉,则程序会直接结束,这样不好。
while True:
try:
num =int(input('输入一个数:'))
num =5/num
print(num)
except ZeroDivisionError:
print('输入数字不能为0')
#当用户输入0,自然会产生异常,即ZeroDivisionError,若不用except捕捉,则直接回结束程序,不会给用户第二次输入的机会
(2)else语句
如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。例如:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。
(3)Exception是所有 NameError的基类
try :
.....
except Exception: 捕捉Exception时,会捕捉所有的异常 等同于只写except
.....
(4) raise
try:
raise TypeError('类型错误') #主动抛出一个TypeError型异常,是Exception的子类
except Exception as e: #由于是Exception是基类异常,所以会捕获所有try抛出的异常
print(e)
输出:
'类型错误'
(5) except NameError as e:
......
e是NameError类的实例,与 except NameError: .... 有区别
(6)自定义异常类
class MyError(Exception):
def __init__(self,value):
self.value = value
def __str__(self): #__str__魔法方法 会在实例被要求print()的时候被调用
return self.value
try:
raise MyError('my error') #self.value = 'my error'
except MyError as e: # e是MyError类的实例
print(e) #此处print()调用了e的__str__魔法方法
(7)在真实场景的应用程序中,finally 子句用于释放外部资源(文件或网络连接之类的),无论它们的使用过程中是否出错。
16.类
(1)语法
class nameoftheclass(parent_class):
statement1
statement2
statement3
(2)__init__(self[,v1[,v2...])
类的实例化操作会自动为新创建的类实例调用 __init__() 方法
classComplex:
def__init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
(3)self
self代表类的实例,即当前对象的地址,而非类。类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
(4) 子类调用父类的方法的两种形式
如下代码中的???处进行父类方法调用
class Person:
def __init__(self, name):
self.name = name
def ps(self):
print('my name is {}'.format(self.name))
class Student(Person):
def __init__(self,name,age,sex):
???
self.age = age
self.sex = sex
def ps1(self):
print('my name is {} , my age is {}, my sex is {}'.format(self.name,self.age,self.sex))
第一种是直接法。使用父类名称直接调用,形如 parent_class.parent_attribute(self),对应例程即语句:
Person.__init__(self,name) #一定要有self
第二种是通过super函数,形如 super(child_class, child_object).parent_attribute(arg)。第一个参数表示调用父类的起始处,第二个参数表示类实例(一般使用self),父类方法的参数只有self时,参数args不用写。此外,类内部使用时,child_class, child_object也可省略。对应例程:
super(Student,self).__init__(name)
或者:
super().__init__(name)
在类外面也可使用super函数,但是要有child_class, child_object两个参数。
(5)装饰器 https://www.zhihu.com/question/26930016
首先明确 func与func()
函数只写函数名表示函数对象本身,加上括号表示执行这个函数
很多时候,你需要对一段代码加上权限认证,加上各种功能;但是又不想,或者不方便破坏原有代码,则可以用装饰器去扩展它。比如play()函数默认播放动画片,现在规定年龄范围内的才能看,可以不用改动play()函数,使用装饰器
userAge=40
def canYou(func):
def decorator(*args,**kwargs):
if userAge > 1 and userAge < 10:
return func(*args,**kwargs) #func加了括号,说明返回的是对这个函数的执行
print('你的年龄不符合要求,不能看')
return decorator #返回的是函数对象decorator,相当于一个变量,没有执行这个函数
@canYou # @为语法糖 实际为 play = canYou(play),在函数定义后执行。 执行后,play指向了decorator这个对
#象。此时的play不再是原来的单一功能的函数,而是一个有了年龄判断功能的新函数
def play():
print('开始播放动画片 《喜洋洋和灰太狼》')
play()
# 输出
# 你的年龄不符合要求,不能看
# 你可以修改上面的 userAge 为9 试试
Python连接数据库的步骤
1)建立数据库连接 (db = pymysql.connect(......))
2)创建游标对象 (c = db.cursor())
3)游标方法 (c.execute(sql语句))
4)提交到数据库 (db.commit())
5)关闭游标对象 (c.close())
6)关闭数据库 (db.close())
connect对象
1)db=pymysql.connect(参数列表)
参数列表有:
1. host : 主机地址,本地地址 localhost
2. port : 端口号 ,默认为3306
3. user : 用户名
4. password : 密码
5. database : 要连接到的库
6. charset : 编码方式,推荐使用 utf8
2)数据库连接对象(db)的方法
1.db.close() 关闭连接
2.db.commit() 提交到数据库执行
3.db.rollback() 回滚
4.db.cursor() 返回游标对象,用于具体执行
SQL命令
3)游标对象(cur)的方法
1.cur.execute(SQL命令,[列表]) 执行SQL命令
2.cur.close() 关闭游标对象
3.cur.fetchone() 获取查询结果集的第一条数据
【获取结果为一个元组】
4.cur.fetchmany(n) 获取查询结果集的第n条数据
【获取结果为一个元组 如:((记录1),(记录2))】
5.cur.fetchall() 获取所有记录(结果为元组)
注意:
fetchone , fetchmany , fetchall 均获取一条记录少一条记录