注释
- 单行注释用 #
- 多行注释用 '''xxx'''
打印print
# 定义变量
a = 100
# 输出a的类型
print(type(a))
# 格式化输出a
print("a=%d"%a)
print("a=%x"%a) #16进制
# 输出字符串
b="xiaobai"
print("name=%s"%b)
#换行输出
print("hello world \n good morning")
#输出多个参数
a = 1
b = "str"
c = 3.12
print("a = %d b = %s c = %.2f"%(a, b, c))
#输出数据后不换行
i = 1
while i <= 5:
j = 1
while i >= j:
print("* ", end="")
j += 1
i += 1
print("\n")
pass
输出:
*
* *
* * *
* * * *
* * * * *
输入input
python2:raw_input()
python3:input()
//将输入的文字保存到name
name = input("请输入名字")
print("你的名字%s"%name)
//通过input输入的数据是以字符串的形式存在的,如果需要计算,需要转成对应的类型
userName = input("请输入用户名")
print(userName)
age = input("请输入年龄")
age = int(age) + 1
print(age)
运算符
//:取整除,去掉小数部分
print(10//3)
a = 10
a += 10//3
print(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 = 1
if a > 10:
print("a > 10")
else:
print("a < 10")
print("a < 10")
print("a < 10")
pass
print("end")
while
while a < 10:
print(a)
a += 1
pass
for
for i in range(1,10):
print(i)
pass
for i in "xiaobai":
print(i)
pass
字符串
定义字符串使用单引号或双引号都可以
str = 'xiaobai'
str = "xiaobai"
下标,通过下标访问字符串中的字符
print(str[0])
print(str[1])
字符串拼接
//使用 + 号
a = "xiao"
b = "bai"
print(a+b) //xiaobai
c = "%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的前一位,也就是下标4
print(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") //返回2
a.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()) //False
b = "xiaobai" //True
print(b.isalpha())
isdigit 检查是否全是数字
a = "1234"
print(a.isdigit()) //True
a = "1234a"
print(a.isdigit()) //False
isalnum 检查是否是字母或数字
a = "1234"
print(a.isalnum()) //True
a = "123 4a"
print(a.isalnum()) //False 有空格
isspace 检查是否是空格
a = "12 34"
print(a.isspace()) //false
a = " "
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添加元素xiaobai
a.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) //False
print("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方法从字典取值,如果对应的值不存在,会返回NONE
print(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 20
for 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 20
print(test2())
# 带参数 带返回值
def test4(name, age):
info = ("name = %s, age = %d"%(name, age))
return info
print(test4("xiaobai", 20))
infp = test4(age = 20, name = "xiaobai")
infp = test4(name = "xiaobai", age = 20)
全局变量
- 如果在函数中修改全局变量,那么就需要使用global进行声明,否则出错
- 对于可变类型的全局变量,比如列表、字典,在函数内修改时可以不用加global
c = 100 //定义全局变量c
def 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=30
test("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 + 10
a = 10
test(a)
print(a)
//因为变量a是数值类型,是不可变类型,所以调用参数不会影响变量本身;
def test(a):
a.append(3)
a = [1, 2]
test(a)
print(a)
//列表是可变类型,函数调用会影响变量本身;
匿名函数
- 匿名函数使用lambda声明
- 匿名函数可以接收任意数量的参数,但是只能返回一个表达式的值
sum = lambda a, b: a + b
print(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 = 4
b = 5
c = a
a = b
b = 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) # 3
content = 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 = 180
print(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.age
person = 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.__age
person = 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 sys
class Person:
person = Person()
#获取对象引用个数,会比实际的个数多1
print(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 = name
bosi = 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 self
xiaohei = Xiaohei()
xiaohei.show() #xiaohei show self
类属性
- 类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,
- 对于公有的类属性,在类外可以通过类对象和实例对象访问
- 不能在类外通过类对象或实例对象访问私有的类属性
class People(object):
name = "xiaobai"
__age = 20
print(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) #xiaobai
print(people.name) #xiaobai
# 通过实例对象修改类属性
people.name = "xiaohei"
print(people.name) #xiaohei
print(People.name) #xiaobai
del people.name
print(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()) #xiaobai
Person.setname("xiaohei")
print(Person.getname()) #xiaohei
#通过实例对象调用类方法
person = Person()
print(person.getname()) #xiaohei
person.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.__instance
dog = Dog()
print(id(dog))
dog1 = Dog()
print(id(dog1))
输出:
4321567912
4321567912
创建单例 只执行一次__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.__instance
dog = Dog("xiaobai")
print(id(dog))
print(dog.name)
dog1 = Dog("xiaohei")
print(id(dog1))
print(dog1.name)
//因为只执行了一次init方法,所有第二次创建对象时返回的是上一次创建的对象
输出
____-init_____
4322616936
xiaobai
4322616936
xiaobai
捕获异常
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:
pass
finally:
pass
获取异常的信息描述
try:
print("rrrrrrrr")
open("", "w")
print(a)
print("rrrrrrrr")
#将FileNotFoundError, NameError异常信息存储到 error中
except (FileNotFoundError, NameError) as error:
print(error)
else:
pass
finally:
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 = atleast
def 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:
pass
main()
模块
import 模块
- 调用模块内的方法必须加上模块名,因为有可能存在同名的函数
import math #导入math模块
#调用math模块内的sqrt方法
print(math.sqrt(4))
from ... import...
- 从模块中导入指定的方法,调用模块的方法不需要加模块名
from math import sqrt
print(sqrt(4))
import * from...
- 将模块中的内容全部导入当前命名空间
import ... as ...
- 给导入的模块起别名
import math as tt
print(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 test
print(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.py
def sendmsg():
print("send msg")
//test.py
def getmsg():
print("get msg")
//1.py
#导入main 和 test模块,并调用其中的方法,需要给出模块完整的路径
import python.main
import python.test
python.main.sendmsg()
python.test.getmsg()
通过导入文件夹下所有文件的方式导入模块,只会导入文件夹,文件夹下的模块不会导入
from python import *
python.main.sendmsg() #报错
python.test.getmsg() #报错
解决办法:
- 在模块文件夹下创建__init__.py文件,
- 定义一个all变量,控制着 from 包名 import *时导入的模块
//main.py
def sendmsg():
print("send msg")
//test.py
def getmsg():
print("get msg")
//__init__.py
__all__ = ["main", "test"]
//1.py
from 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 * x
a = [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)
//元组转set
c = set(b)
print(c)
//set转列表
d = list(c)
print(d)
__main__
//test.py
def test():
print(__name__)
test()
输出:__main__
//1.py
from test import *
test()
输出:test test
如果我们是直接执行某个.py文件的时候,该文件中那么”__name__ == '__main__'“是True,但是我们如果从另外一个.py文件通过import导入该文件的时候,这时__name__的值就是我们这个py文件的名字而不是__main__。
这个功能还有一个用处:调试代码的时候,在”if __name__ == '__main__'“中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!