注释
- 单行注释用 #
- 多行注释用 '''xxx'''
打印print
# 定义变量a = 100# 输出a的类型print(type(a))# 格式化输出aprint("a=%d"%a)print("a=%x"%a) #16进制# 输出字符串b="xiaobai"print("name=%s"%b)#换行输出print("hello world \n good morning") #输出多个参数a = 1b = "str"c = 3.12print("a = %d b = %s c = %.2f"%(a, b, c))#输出数据后不换行i = 1while i <= 5: j = 1 while i >= j: print("* ", end="") j += 1 i += 1 print("\n") pass输出: * * * * * * * * * * * * * * *
输入input
python2:raw_input()python3:input()//将输入的文字保存到namename = input("请输入名字")print("你的名字%s"%name)//通过input输入的数据是以字符串的形式存在的,如果需要计算,需要转成对应的类型userName = input("请输入用户名")print(userName)age = input("请输入年龄")age = int(age) + 1print(age)
运算符
//:取整除,去掉小数部分
print(10//3)a = 10a += 10//3print(a)
类型转换
int(x [,base ]) 将x转换为一个整数long(x [,base ]) 将x转换为一个长整数float(x ) 将x转换到一个浮点数complex(real [,imag ]) 创建一个复数str(x ) 将对象 x 转换为字符串repr(x ) 将对象 x 转换为表达式字符串eval(str ) 用来计算在字符串中的有效Python表达式,并返回一个对象tuple(s ) 将序列 s 转换为一个元组list(s ) 将序列 s 转换为一个列表chr(x ) 将一个整数转换为一个字符unichr(x ) 将一个整数转换为Unicode字符ord(x ) 将一个字符转换为它的整数值hex(x ) 将一个整数转换为一个十六进制字符串oct(x ) 将一个整数转换为一个八进制字符串
if else
- python的if和else语句后要跟":",pass是占位符,不执行任何操作。
- if 和 else 代码块内如果要执行多条语句,这多条语句前都要有TAB的空格,即都要缩进相同的程度;
a = 1if a > 10: print("a > 10")else: print("a < 10") print("a < 10") print("a < 10") passprint("end")
while
while a < 10: print(a) a += 1 pass
for
for i in range(1,10): print(i) passfor i in "xiaobai": print(i) pass
字符串
定义字符串使用单引号或双引号都可以
str = 'xiaobai'str = "xiaobai"
下标,通过下标访问字符串中的字符
print(str[0])print(str[1])
字符串拼接
//使用 + 号a = "xiao"b = "bai"print(a+b) //xiaobaic = "%s%s"%(a,b)//使用格式字符串c = "%s%s"%(a,b)print(c)d = "%s"%(a+b)print(d)
字符串长度
a = "xiaobai"len(a)
切片
截取对象一部分数据,语法:[起始:结束:步长] 选取的区间属于左闭右开型,即从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身)。
str = "xiaobai"print(str[2:5]) //输出aob,从下标2开始,截取到下标5的前一位,也就是下标4print(str[2:]) //下标2开始,直到字符串结束print(str[1:-2]) //下标1开始,到最后第3个之间的字符print(str[:3]) //下标0开始,到下标3之前的字符print(str[::3]) //步长为3,从下标0开始,截取 0 3 6 9...,直到字符串结束,print(str[1:6:2]) //从下标1开始,到下标5结束,步长为2
字符串逆序
a = "xiaobai"print(a[-1::-1]) //从最后一个元素开始,步长为-1,print(a[::-1]) //从下标0开始,直到字符串结束,步长为-1,系统会自动颠倒起始位置和结束位置
find 字符串查找
如果字符串存在,返回首字符下标,否则返回-1
a = "xiaobai"a.find("a") //返回2a.rfind("a") //从右向左查找
index:功能和find相同,如果查找失败,会返回系统错误
count 查找的字符串出现的个数
a = "xiaobai"print(a.count("a")) //2,查找字符“a” 在字符串中出现的次数
replace 替换
a = "xiaobai"print(a.replace("a", "xxx")) //替换字符串中所有的"a"字符print(a.replace("a", "xxx", 1)) //替换字符串中的第一个“a”字符
split 分割字符串
a = "xiao bai"print(a.split(" ")) //['xiao', 'bai'],通过空格分割字符串
capitalize 首字母大写
a = "xiao bai"print(a.capitalize())
title 每个单词首字母大写
a = "xiao bai"print(a.title())
startsWith/endswith
a = "xiao bai"print(a.startswith("xi"))print(a.endswith("ai"))
lower upper 全部字符大小写
a = "xiao bai"print(a.upper())print(a.lower())
左对齐、右对齐、居中
a = "xiao bai"//返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串print(a.ljust(20))//返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串print(a.rjust(20))//返回一个原字符串居中,并使用空格填充至长度 width 的新字符串print(a.center(20))
删除空白字符
a = " xiao bai "# //删除左边空格print(a.lstrip()) # 删除右边空格print(a.rstrip())# 删除两边空格print(a.strip())
分割字符串 partition rpartition
//从左到右,以字符串“new"为界,将字符串a分割成3部分a = "happy new year"print(a.partition("new")) //('happy ', 'new', ' year')//从右到左print(a.rpartition("new")) //('happy ', 'new', ' year')
分割字符串 splitlines
a = "happy\n new\n year"//按照行分隔,返回一个包含各行作为元素的列表print(a.splitlines())
isalpha 检查是否全是字母
a = "xiaobai1"print(a.isalpha()) //Falseb = "xiaobai" //Trueprint(b.isalpha())
isdigit 检查是否全是数字
a = "1234"print(a.isdigit()) //Truea = "1234a"print(a.isdigit()) //False
isalnum 检查是否是字母或数字
a = "1234"print(a.isalnum()) //Truea = "123 4a"print(a.isalnum()) //False 有空格
isspace 检查是否是空格
a = "12 34"print(a.isspace()) //falsea = " "print(a.isspace()) true
join 合并字符串
str = "_"arr = ["aaa", "bbb", "ccc"]//arr 中每个字符后面插入str,构造出一个新的字符串print(str.join(arr)) //aaa_bbb_ccc
列表
Python的列表就是数组,与其他语言不同的是,Python列表可以存不同类型的数据。
定义
arr = [1, 1.23, "xiaobai"]print(arr) #[1, 1.23, 'xiaobai']print(arr[0])print(arr[1])//遍历列表for item in arr: print(item)
添加元素
append 列表末尾追加元素
arr = [1, 1.23, "xiaobai"]arr.append("xiaohei")print(arr)
extend 将一个列表的元素添加到另外一个列表中
a = [1, 2, 3]b = ["a", "b", "c"]a.extend(b)print(a)
insert 在指定位置插入元素
a = [1, 2, 3]//在位置1添加元素xiaobaia.insert(1, "xiaobai")print(a)
修改元素
a = [1, 2, 3]a[1] = "xiaobai"print(a) //[1, "xiaobai", 3]
查找元素
in notin
a = [1, 2, 3]print("xiaobai" in a) //Falseprint("xiaobai" not in a) //True
index
a = [1, 2, 3, 1, 2, 3]print(a.index(3)) //查找元素3在列表a中的位置print(a.index(3, 3, 6)) //在列表a中,从第3个元素开始,第6个元素结束,查找元素3
count
a = [1, 2, 3, 1, 2, 3]print(a.count(1)) //元素1出现的次数print(len(a)) //字符串长度
删除元素
a = [1, 2, 3, 1, 2, 3]del a[2] #删除第二个元素print(a)a.pop() #删除最后一个元素print(a)a.remove(1) #删除指定元素print(a)
排序(sort, reverse)
a = [1, 2, 3, 1, 2, 3]a.reverse() #逆序 [3, 2, 1, 3, 2, 1]print(a)a.sort()print(a) #从小到大排列 [1, 1, 2, 2, 3, 3]a.sort(reverse = True) #从大到小 [3, 3, 2, 2, 1, 1]print(a)
字典
定义字典
info = {"name":"xiaobai", "age":20, "address":"beijing"}print(info)print(info["name"])print(info["age"])height = info.get("height") #通过get方法从字典取值,如果对应的值不存在,会返回NONEprint(height)height = info.get("height", 175) ##通过get方法从字典取值,可以设置默认值,如果对应的值不存在,会返回设置的默认值print(height)height = info["height"]print(height) # info中不存在 height键,会报错
元素操作
info = {"name":"xiaobai", "age":20}info["name"] = "xiaohei" #修改元素的值print(info["name"])info["address"] = "beijing" #添加元素print(info)del info["name"] #删除元素print(info)del info #删除字典print(info)info.clear() #清空字典print(info)
其他操作
info = {"name":"xiaobai", "age":20}print(len(info)) #字典长度print(info.keys()) #获取字典的所有键print(info.values()) #获取字典所有值print(info.items()) #获取所有键值的元组# print(info.has_key("name")) #Python3删除了这个方法if "name" in info: print(info["name"])
遍历字典
info = {"name":"xiaobai", "age":"20"}for (key, value) in info.items(): print("%s %s"%(key, value))//name xiaobai//age 20for item in info.items(): print(item)//('name', 'xiaobai')//('age', '20')
元组
Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。index和count与字符串和列表中的用法相同
_tuple = ("xiaobai", 20)print(_tuple[0])print(_tuple[1])print(len(_tuple))print(_tuple.index(20))
公共方法
运算符
+ 合并 字符串、列表、元组* 复制 字符串、列表、元组in 元素是否存在 字符串、列表、元组、字典not in 元素是否不存在 字符串、列表、元组、字典
内置函数
len(item) 计算容器中元素个数max(item) 返回容器中元素最大值min(item) 返回容器中元素最小值del(item) 删除变量id(item) 输出item的内存地址
函数
函数定义
# 不带参数不带返回值def test(): print("xiaobai") print("ni hao")test()# 带参数 没有返回值def test1(a, b): print("a=%d, b=%d"%(a, b))test1(1, 2)# 不带参数,有返回值def test2(): return 20print(test2())# 带参数 带返回值def test4(name, age): info = ("name = %s, age = %d"%(name, age)) return infoprint(test4("xiaobai", 20))infp = test4(age = 20, name = "xiaobai")infp = test4(name = "xiaobai", age = 20)
全局变量
- 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
- 对于可变类型的全局变量,比如列表、字典,在函数内修改时可以不用加global
c = 100 //定义全局变量cdef test(): a = 10 b = 20 print(a + b) global c //引用全局变量C c = 30 //修改全局变量test()print(c)//可变类型全局变量arr = [1, 2]def test(): arr.append(3)test()print(arr)
元组作为返回值
def test(): return(1, "xiaobai")a ,b = test()print("a=%d, b=%s"%(a, b))
默认参数
- 默认参数必须放在参数列表的最后
def test(name, age=30): //age有默认参数30 print("name=%s, age=%d"%(name, age))//只传入name,age取默认值test("xiaobai") //name=xiaobai, age=30test("xiaobai", 20) //name=xiaobai, age=20
可变参数
- 以 “*” 开头的形参,用来存放所有未命名的参数,args是元组;
- 以 “**” 开头的形参,用来存放命名参数,kwargs是字典
- args、kwargs只是形参名,可以任意改变
def test(a, b, *args, **kwargs): print("a=%d, b=%d"%(a, b)) print(args) print(kwargs)test(1, 2, 3, 4, k = 5, w = 6)输出:a=1, b=2(3, 4){'k': 5, 'w': 6}
拆包
def test(a, b, *c, **d): print("a=%d, b=%d"%(a, b)) print(c) print(d)test(1, 2, (3, 4), {"k":5, "w":6})输出:a=1, b=2((3, 4), {'k': 5, 'w': 6}){}元组和字典被当做一个参数,传递给了未命名的变量,如果需要将元组和字典的值取出来,分别传递给未命名参数和命名参数,需要将元组和字典进行解包。def test(a, b, *c, **d): print("a=%d, b=%d"%(a, b)) print(c) print(d)test(1, 2, *(3, 4), **{"k":5, "w":6})输出a=1, b=2(3, 4){'k': 5, 'w': 6}“*”、“**”如果放在参数前面,表示解包;
可变类型、不可变类型
- 可变类型:列表、字典
- 不可变类型:数字、字符串、元组
a = 100 //定义数字a,值为100,其实质是内存分配空间存储数值100,然后将内存地址赋给变量a,变量a只存的是内存地址b = a //b 和 a指向相同的内存地址 a = 200 //变量a指向存放200的内存地址id(a) //查看a指向的内存地址
引用传参
- Python中函数参数都是引用传递
def test(a): a = a + 10a = 10test(a)print(a)//因为变量a是数值类型,是不可变类型,所以调用参数不会影响变量本身;def test(a): a.append(3)a = [1, 2]test(a)print(a)//列表是可变类型,函数调用会影响变量本身;
匿名函数
- 匿名函数使用lambda声明
- 匿名函数可以接收任意数量的参数,但是只能返回一个表达式的值
sum = lambda a, b: a + bprint(sum(1, 2)) //3//匿名函数做参数def test(a, b, opt): return opt(a, b)print(1, 2, lambda a, b: a + b)
使用匿名函数为列表排序
stus = [ {"name":"zhangsan", "age":18}, {"name":"lisi", "age":19}, {"name":"wangwu", "age":17}]//按照“name”先后顺序重新排序列表stus.sort(key = lambda x: x["name"])print(stus)
从终端输入函数作为参数
def test(a, b, func): return func(a, b)func_new = input("请输入函数") //让用户输入匿名函数func_new = eval(func_new) //Python3 去掉字符串的引号,使输入的数据成为函数num = test(11, 22, func_new)print(num)
交换数据
python中都是地址引用,直接交换两个变量即可
a = 4b = 5c = aa = bb = c//使用元组(a, b) = (b ,a)a, b = b, a
文件操作
打开、关闭文件
f = open("text.txt", "a+")print(f)f.close()
文件读写模式
- r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
- w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
- a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
- rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
- wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
- ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
- r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
- w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
- a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
- rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
- wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
- ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
写数据
f = open("test.txt", "w")f.write("hello world")
读数据 read
- read(num) :读取指定长度的数据
- read(): 读取所有数据
- 执行一次读取数据操作后,文件指针会移动到对应长度数据后边,再执行一次读数据操作,会从上次读取的位置继续读取;
f = open("test.txt")content = f.read(5) #读取指定长度的数据print(content)content1 = f.read() //从位置5开始读取剩下的所有数据print(content1)
读数据 readlines
- readlines(): 一次性读完所有数据,返回的结果是列表,每一行数据是列表的一个元素;
f = open("test.txt")content = f.readlines()for item in content: print item
读数据 readline
- readline:一次读取一行数据
f = open("test.txt")content = f.readline()print(content)content = f.readline()print(content)content = f.readline()print(content)
获取当前读写位置 tell()
f = open("test.txt")content = f.read(3)print(content)pos = f.tell()print(pos) # 3content = f.read(10)print(content)pos = f.tell()print(pos) #13
定位 seek()
- 第一个参数:偏移的位置
- 第二个参数:0:文件开头, 1:当前位置, 2:文件末尾
- 在文本文件中,没有使用b模式选项打开的文件,只允许从文件头开始计算相对位置,从文件尾计算时就会引发异常,打开文件模式需要设置为 rb+。
f = open("test.txt","rb+")f.seek(3, 0) #定位到 开头 3个字节pos = f.tell()print(pos)f.seek(3, 2)pos = f.tell()print(pos)
文件夹操作
#导入 os 模块import os#切换目录os.chdir("/Users/xxx/Desktop")#获取当前目录下所有文件列表dirlist = os.listdir()print(dirlist)#获取当前路径pwd = os.getcwd()print(pwd)#创建文件夹os.mkdir("xiaobai")#删除文件夹os.rmdir("xiaobai")
类
创建对象
- 定义对象的方法时,第一个参数必须是self,代表调用方法的对象本身;
class Person: #__init__ 是初始化方法 def __init__(self, name, age): self.name = name self.age = age #打印输出对象时,会调用__str__方法 def __str__(self): return "name = %s, age = %d"%(self.name, self.age) #定义方法, def run(self): print("run")#创建对象person = Person("xiaobai", 20)print(person.name)print(person.age)#修改对象的属性person.name = "xiaogei"#新增对象属性person.height = 180print(person.height)#调用对象方法person.run()
隐藏数据
通过调用方法实现属性的读写的好处是可以对数据进行判断
class Person: def setage(self, age): if age < 0: self.age = 0 return self.age = age def getage(self): return self.ageperson = Person()person.setage(10)print(person.getage())person.setage(-10)print(person.getage())
通过方法读写属性虽然可以做到隐藏数据的功能,但是属性还是可以通过person.age获取到,要做到完全隐藏属性,需要将属性定义为私有属性.
class Person: def __init__(self, age): self.__age = age def setage(self, age): if age < 0: self.__age = 0 return self.__age = age def getage(self): return self.__ageperson = Person(20)person.setage(10)print(person.getage())person.setage(-10)print(person.getage())
此时通过 person.age 或 person.age 是无法访问到属性的。在Python中定义私有属性,需要在属性前面加“";
私有方法
定义私有方法,在方法前加"__"
class Person: def test1(self): print("test1") def __test2(self): #私有方法 print("test2")person = Person()person.test1()person.test2() //访问私有方法,报错
__ del __ 类析构方法
__ del __ 是在对象被删除的时候调用
class Person: def test1(self): print("test1") def __test2(self): print("test2") def __del__(self): print("del ---")person = Person()person.test1()del person #删除person对象,会调用__ del __方法
sys.getrefcount(T) 获取引用计数
import sysclass Person:person = Person()#获取对象引用个数,会比实际的个数多1print(sys.getrefcount(person)) del person#删除对象之后再获取引用计数会崩溃print(sys.getrefcount(person))
继承
class Cat(object): def __init__(self, name, color="白色"): self.name = name def run(self): print("%s 在跑"%self.name)class Bosi(Cat): def setname(self, name): self.name = namebosi = Bosi("xiaobai")print(bosi.name)bosi.run()
继承不能访问父类的私有属性和方法
class Cat(object): def __init__(self, name, color="白色"): self.__name = name def __run(self): print("%s is running"%self.__name) def eat(self): print("%s is eating"%self.__name) def getname(self): print(self.__name)class Bosi(Cat): pass bosi = Bosi("xiaobai")print(self.__name) #报错,不能访问父类的私有属性bosi.getname()bosi.__run() #报错,不能访问父类的私有方法
多继承
python支持继承多个类
class A(object): def test(self): print("a print")class B(object): def test(self): print("b print")class C(B, A): pass c = C()c.test()print(C.__mro__) #打印C类搜索方法时的先后顺序
重写父类方法
class Cat(object): def __init__(self, name): self.name = name def eat(self): print("cat eat fish")class Bosi(Cat): def __init__(self, name): #调用父类的初始化方法 super(Bosi, self).__init__(name) #重写父类方法 def eat(self): print("bosi eat fish") bosi = Bosi("bosi")print(bosi.name)bosi.eat()
多态
class Dog(object): def show(self): print("dog show self") class Xiaobai(Dog): def show(self): print("xiaobai show self")class Xiaohei(Dog): def show(self): print("xiaohei show self")xiaobai = Xiaobai()xiaobai.show() #xiaobai show selfxiaohei = Xiaohei()xiaohei.show() #xiaohei show self
类属性
- 类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,
- 对于公有的类属性,在类外可以通过类对象和实例对象访问
- 不能在类外通过类对象或实例对象访问私有的类属性
class People(object): name = "xiaobai" __age = 20print(People.name)print(People.__age)xiaoming = People()print(xiaoming.name)print(xiaoming.__age)
修改类属性
- 必须通过类对象在类外修改类属性。
- 如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
class People(object): name = "xiaobai"print(People.name)people = People()print(people.name)#通过类对象修改类属性People.name = "xiaohei"print(People.name) #xiaobaiprint(people.name) #xiaobai# 通过实例对象修改类属性people.name = "xiaohei"print(people.name) #xiaoheiprint(People.name) #xiaobaidel people.nameprint(people.name) #xiaobai
类方法
- 类方法前面必须加 @classMethod修饰
- 类方法的第一个参数必须是类对象,通常用cls作为第一个参数
- 实例对象和类对象都可以访问类方法
class Person(object): name = "xiaobai" @classmethod def getname(cls): return cls.name @classmethod def setname(cls, name): cls.name = name#通过类调用类方法print(Person.getname()) #xiaobaiPerson.setname("xiaohei")print(Person.getname()) #xiaohei#通过实例对象调用类方法person = Person()print(person.getname()) #xiaoheiperson.setname("xiaobai")print(person.getname()) #xiaobai
静态方法
- 实例方法需要加 @staticmethod修饰
- 实例方法不需要添加额外的参数
- 实例方法中可以调用类属性及方法、实例属性及方法
class Person(object): name = "xiaobai" def setage(self, age): self.age = age @staticmethod def showinfo(): print("*" * 10) print("hello world") print("*" * 10) #访问类属性 print("name = %s"%Person.name) #调用实例 person = Person() person.setage(20) print("age = %d"%person.age)#通过类调用静态方法Person.showinfo()#通过实例对象调用静态方法person = Person()person.showinfo()
__new__方法
- __new__方法是在创建对象实例时调用
- __new__方法中必须调用父类的__new__方法方法
class Dog(object): def __init__(self): print("____init_____") def __del__(self): print("________del_______") #__new__方法的第一个参数是类对象 def __new__(cls): print("______new________") #调用object的__new__方法 return object.__new__(cls)dog = Dog()输出:______new____________init_____________del_______
单例模式
class Dog(object): __instance = None def __new__(cls): #如果类的实例对象不存在,调用父类的new方法创建实例 if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instancedog = Dog()print(id(dog))dog1 = Dog()print(id(dog1))输出:43215679124321567912
创建单例 只执行一次__init__方法
class Dog(object): __instance = None __First_init = False def __init__(self, name): #如果执行过__init__方法,不再执行 if not self.__First_init: print("____-init_____") self.name = name Dog.__First_init = True def __new__(cls, name): if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instancedog = Dog("xiaobai")print(id(dog))print(dog.name)dog1 = Dog("xiaohei")print(id(dog1))print(dog1.name)//因为只执行了一次init方法,所有第二次创建对象时返回的是上一次创建的对象输出____-init_____4322616936xiaobai4322616936xiaobai
捕获异常
try: print("rrrrrrrr") print(a) #变量a没有定义,会产生NameError print("rrrrrrrr")//捕获错误except (NameError): print("errror")
捕获多个异常:多个异常使用元组表示
try: print("rrrrrrrr") open("", "w") print(a) print("rrrrrrrr")except (FileNotFoundError, NameError): print("errror")else: passfinally: pass
获取异常的信息描述
try: print("rrrrrrrr") open("", "w") print(a) print("rrrrrrrr")#将FileNotFoundError, NameError异常信息存储到 error中except (FileNotFoundError, NameError) as error: print(error)else: passfinally: pass
捕获所有异常
try: print("rrrrrrrr") open("", "w") print(a) print("rrrrrrrr")except Exception as errror: print(errror) #如果没有捕获到异常,会执行else的语句else: pass #无论是否捕获到异常,都会执行的语句finally: pass
自定义异常
- 抛出自定义异常使用raise关键字,异常必须是Error或Exception的子类
class ShortInputException(Exception): def __init__(self, length, atleast): super(ShortInputException, self).__init__() self.length = length self.atleast = atleastdef main(): try: content = input("请输入") if len(content) < 3: raise ShortInputException(len(content), 3) except ShortInputException as result: print("输出内容长度%d, 最少长度%d"%(len(content), 3)) else: print("输入内容长度正确") finally: passmain()
模块
import 模块
- 调用模块内的方法必须加上模块名,因为有可能存在同名的函数
import math #导入math模块#调用math模块内的sqrt方法print(math.sqrt(4))
from ... import...
- 从模块中导入指定的方法,调用模块的方法不需要加模块名
from math import sqrtprint(sqrt(4))
import * from...
- 将模块中的内容全部导入当前命名空间
import ... as ...
- 给导入的模块起别名
import math as ttprint(tt.sqrt(4))#如果调用math.sqrt(4) 会报找不到方法的错误print(math.sqrt(4))
自定义模块
//test.py, 自定义文件
def add(): return 1 + 2
//1.py, 导入test.py,调用test.py中的add方法
import testprint(test.add())
__name__
- __name__ 表示当前模块的名称,可以根据name变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,从而能够有选择性的执行测试代码
def add(): return 1 + 2# 根据当前模块的名称,是否需要输出测试信息或日志if (__name__ == "main"): print("test msg")
__all__
- 模块中如果定义了__all__,那只有__all__中的方法或类可以被访问
- 引入模块的文件必须使用 form ... import * 这种方式导入模块
//test.py# 当其他文件导入test模块时,只能使用Test类 和 test1方法__all__ = ["Test", "test1"]class Test(object): def test(self): print("function test")def test1(): print("function test1")def test2(): print("function test2") //main.py#导入test模块from test import *a = Test()a.test()test1()test2() #test模块不允许使用test2()方法,会报错输出:NameError: name 'test2' is not defined
包
包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py 文件,那么这个文件夹就称之为包
main.py 和 test.py都在Python目录下//main.pydef sendmsg(): print("send msg") //test.pydef getmsg(): print("get msg") //1.py#导入main 和 test模块,并调用其中的方法,需要给出模块完整的路径import python.mainimport python.testpython.main.sendmsg()python.test.getmsg()
通过导入文件夹下所有文件的方式导入模块,只会导入文件夹,文件夹下的模块不会导入
from python import *python.main.sendmsg() #报错python.test.getmsg() #报错
解决办法:
- 在模块文件夹下创建__init__.py文件,
- 定义一个all变量,控制着 from 包名 import *时导入的模块
//main.pydef sendmsg(): print("send msg") //test.pydef getmsg(): print("get msg") //__init__.py__all__ = ["main", "test"]//1.pyfrom python1 import *main.sendmsg()test.getmsg()
列表推导式
a = [x for x in range(4)]print(a)输出:[0, 1, 2, 3]等价于:a = []for x in range(4): a.append(x)print(a)
过滤数值
//取0-29,可以被3整除的数a = [x for x in range(30) if x % 3 is 0]print(a)
使用函数
def double(x): return x * xa = [double(x) for x in range(10) if x % 2 == 0]print(a)double(x):生成列表的函数for x in range(10):迭代表达式if x % 2 == 0: 过滤表达式
多个for循环
a = [(x, y) for x in range(3) for y in range(3, 5)]print(a)输出:[(0, 3), (0, 4), (1, 3), (1, 4), (2, 3), (2, 4)]a = [(x, y, z) for x in range(3) for y in range(3, 5) for z in range(5, 8)]print(a)输出:[(0, 3, 5), (0, 3, 6), (0, 3, 7), (0, 4, 5), (0, 4, 6), (0, 4, 7), (1, 3, 5), (1, 3, 6), (1, 3, 7), (1, 4, 5), (1, 4, 6), (1, 4, 7), (2, 3, 5), (2, 3, 6), (2, 3, 7), (2, 4, 5), (2, 4, 6), (2, 4, 7)]
//将列表a 分成3个子列表a = [1, 2, 3, 4, 5, 6, 7, 8 ,9]b = [a[x:x+3] for x in range(0, len(a), 3)]print(b)输出:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
dict
dic = {"xiaobai": 20, "xiaohei": 30, "xiaohong": 40}print(dic["xiaobai"])# 如果dic种不存在xiaohui,会返回get后面指定的数值a = dic.get("xiaohui", 50)print(a)#删除对象dic.pop("xiaobai")print(dic)
set
- set中没有重复的值
# 将列表转成set,set会自动过滤重复的值a = [1, 2, 3, 4, 4, 3 ,2]b = set(a)print(b) #{1, 2, 3, 4} #添加删除元素a.add(4) a.remove(4)
set list tuple转换
a = [1, 2, 3]//列表转元组b = tuple(a)print(b)//元组转setc = set(b)print(c)//set转列表d = list(c)print(d)
__main__
//test.pydef test(): print(__name__)test() 输出:__main__//1.pyfrom test import *test()输出:test test
如果我们是直接执行某个.py文件的时候,该文件中那么”__name__ == '__main__'“是True,但是我们如果从另外一个.py文件通过import导入该文件的时候,这时__name__的值就是我们这个py文件的名字而不是__main__。
这个功能还有一个用处:调试代码的时候,在”if __name__ == '__main__'“中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!