- 运行python程序的三种方式
- input
- 变量
- 占位符
- 注释
- 语句块
- 运算符
- python3的标准数据类型
- 将字符串转换为列表
- [‘h’, ‘e’, ‘l’, ‘l’, ‘o’]
- 将列表转换为字符串
- hello
- 快速生成1到10之间的list
- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- 快速生成0到4之间的list
- [0, 1, 2, 3, 4]
- python控制结构
- 函数
- 输出内容:
- 参数为:[1,2,3,4]
- 输出以下内容
- 参数为:1
- 参数为:2
- 参数为:3
- 参数为:4
- 匿名函数
- 全局变量与局部变量
- python模块
- 面向对象
- init方法会在初始化类的实例的时候,被自动调用
- self表示是实例方法,只能有类的实例来调用
- @classmethod注解,方法的第一个参数必须是cls, 该方法就是类方法
- @property注解,表明该方法是一个属性方法,提供属性的访问。这里是提供money的这个实例属性的访问 通过实例名.money就能访问
- 创建一个对象:Student类的实例
- 实例方法的访问
- 实例属性的访问
- 类方法的访问
- 类属性的访问
- 通过属性方法访问属性,不能修改属性
- 如果函数名加了括号,则代表执行函数,如果没有加括号,则代表函数的引用地址
- 这里a指向了hello函数的引用
- 这里相当于执行函数hello
- 多线程
- 日志
编程语言一般要学的内容:
- 输入输出
- 数据类型
- 控制结构
- 函数定义
- 对象定义
- 文件读写
- 异常处理
运行python程序的三种方式
- 交互式解析器直接运行python代码
- 命令行的方式运行。 python xx.py的命令运行
- 使用开发工具运行
input
input接受用户输入,python3以后,input返回的数据类型是字符串
a=input(“输入提示:”)
a = input("请输入一个数字:")print("用户输入的数字:", a+"10")print(type(a))# 强制转换成int型,才能进行数字运算a = int(input("请输入一个数字:"))print("用户输入的数字:", a+10)print(type(a))
print()打印输出,可以用’,’分隔参数,默认带回车(换行显示)
使用print( , end=’’)表示不换行输出
变量
python中变量是不需要声明类型的,他的类型由赋值给它的数据的类型决定。
每个变量在使用前必须被赋值,赋值后变量才会被创建
每次执行赋值语句的时候,系统会开辟一块内存区域,来保存这个变量的类型、值、内存地址的信息。
命名规则
- 第一个字符必须是字母或者下划线,其他的部分由字母、数字、下划线组成。py文件不能以-和数字开头
- 变量名对大小写敏感
- 变量名不能用关键字(保留字)
- 变量名尽量能够表达含义
占位符
占位符是先占住一个固定的位置,等着往里面添加内容的符号
# %d表明可以添加一个整数的占位符a = int(input("请输入您的岁数"))print("用户输入的年龄是%d岁" % (a))# %f 浮点数b = 3.1415926print("π的值是%.2f" % (b))# %s 字符串# %% %本身# format占位符b=100/3a="xiaohua"print("b的值是{:.2f},学生姓名:{}".format(b,a))# 有多少个大括号,format里面就有多少个变量,变量与大括号按顺序一一对应print(f"b的值是{a},学生姓名:{b}")
注释
- 单行注释用#
- 多行注释用三个单引号’’’或者三个双引号”””
语句块
python以缩进来表示代码块(语句块)
同一块代码块中缩进相同
代码块可以嵌套代码块
运算符
- 算术运算符 +、 - 、、 / 、//(*向下取整)、 %(取余)
- 比较运算符 >、 < 、>= 、<=、 ==、 !=
- 逻辑运算符 or、 and 、not
- 赋值运算符 =、 +=、 /= 、-= 、*=
- 成员运算符 in、 not in
python3的标准数据类型
- 不可变数据类型:Number数字、str字符串、元祖
- 可变的数据类型:List列表、set集合、dictionary字典
每个变量的id值是唯一的,代表内存中的地址,如果变量两次打印出不同的id,表明数据类型是不可变的,对变量进行操作,实际上是生成一个新的对象,并将新对象的引用赋值给变量,这就说明数据类型不能在原来的内存地址上直接修改值,说明数据类型是不可变的。
- 可变数据类型:改变数据的值不会产生一个新的对象,变量仍指向原来的对象,
- 不可变数据类型:指凡是改变了数据的值之后,这个值就将变成另外一个对象的数据类型,变量指向新的对象
Number数值类型
- int 整型
- float 浮点型
- complex 复数
强制类型转换
int(13.4)
float(8)
整除
// 这个的结果得出来是整数,向下取整。
次方
a**b 表示a的b次方
math模块中常用的方法
import math# math.ceil(x),取大于等于x的最小整数# 结果为5print(math.ceil(4.5))# 结果为-2print(math.ceil(-2.1))# math.fabs(x)取x的绝对值# 结果为2.1print(math.fabs(-2.1))# math.floor(x) 取小于等于x的最大值# 结果是5print(math.floor(5.4))# math.pow(a,b) a的b次方# 结果是8.0print(math.pow(2, 3))# math.sqrt(x) x的开根# 结果是4.0print(math.sqrt(16))
random模块
import random# random.random() 生成[0.0,1.0)之间的浮点数,可以为0.0,不可以为1.0print(random.random())# random.randint(a,b) 生成[a,b]之间的随机整数print(random.randint(1, 10))# random.randrange(a,b) 生成[a,b)之间的随机整数,包含a,但不包含bprint(random.randrange(1, 10))# random.uniform(a,b) 生成[a,b]之间的随机浮点数print(random.uniform(1, 2))# random.choice([1,2,34,5]) 从列表中随机取一个元素print(random.choice([1, 2, 34, 5]))a = [1, 2, 3, 4]# random.shuffle(列表) 打乱列表中的顺序random.shuffle(a)print(a)# random.sample([],n) 从序列中随机取n个元素print(random.sample(a, 2))
字符串类型
单引号、双引号、三引号
在python中,凡是有单引号’’,双引号””和三引号’’’ ‘’’括起来的值都属于字符串类型
字符串中的单引号、双引号、三引号不可混用。单引号和双引号是可以嵌套使用的。
三引号一般用于代码注释或保持样式的长字符串输出
s = 'hello'b = "merry"c = '''hello aa'''print(s, b, c)o = "it's my cat"p = 'he say:"hello"'print(o)print(p)'''三引号一般作为函数的注释说明:这个函数的作用是,返回两个加数之和'''q = '''三引号也可作为多行字符串,按原格式输出按原格式输出'''print(q)
字符串切片
切片操作(slice)可以从一个字符串中获取子字符串(字符串的一部分)。我们使用一对方括号、起始偏移量start,终止偏移量end,以及可选的步长step来定义一个切片
格式:[start:end:step]
正向的递增下标序号:0,1,2,3,4,5,6……
反向的递减下标序号:-1,-2,-3,-4,-5,-6…….
哪个方向取数方便,使用哪个方向作为下标序号
s = "你好啊,我很好"# 结果是啊print(s[2])# 结果是很print(s[-2])
- [:]提取从开头到结尾的整个字符串
- [start:] 从start提取到结尾
- [:end] 从开头提取到end-1
- [start:end] 从start提取到end-1
- [start:end:step] 从start提取到end-1,每step个字符提取一个
step为正,表示正序切片,为负表示逆序切片,默认为正1
正序切片时,要求start必须从字符串开头处进行计数,逆序切片时,要求start必须从字符串尾部开始计数
无论正序和逆序,start要求在end之前,否则无法获得内容
t = "小兔与乌龟赛跑,乌龟赢了"# 结果是 小兔与乌龟赛跑,乌龟赢了print(t[:])# 结果是 兔与乌龟赛跑,乌龟赢了print(t[1:])# 结果是 小兔与乌龟赛跑,乌龟赢print(t[:-1])# 结果是 与乌龟print(t[2:5])# 结果是 与龟跑乌print(t[2:9:2])# 龟赢print(t[-3:-1])# 乌龟赛跑,乌龟赢print(t[3:-1])# 步长为-1,表示倒序取出:了赢龟乌,跑赛龟乌与兔小print(t[::-1])# 乌跑print(t[-4:5:-2])
字符串常见操作
原始字符串
在python中如果遇到字符串中需要大量使用转义字符时,可以使用python提供的原始字符串的功能,即在要转义的字符串前面加r.
s = "D:\wrok_soft_install\JetBrains\PyCharm Community Edition 2021.2.1\bin"# 结果D:\wrok_soft_install\JetBrains\PyCharm Community Edition 2021.2.inprint(s)# 使用r就可以避免转义m = r"D:\wrok_soft_install\JetBrains\PyCharm Community Edition 2021.2.1\bin"# 结果 D:\wrok_soft_install\JetBrains\PyCharm Community Edition 2021.2.1\binprint(m)
字符串的常用方法
- len(string) 返回字符串的长度
- count(str,beg=0,end=len(string)) 返回str在string里面出现的次数,如果beg或者end指定则返回指定范围内str出现的次数
- capitalize() 将字符串中的第一个字符转换为大写
- find(str,beg=0,end=len(string)) 检测str是否包含在字符串string中,如果beg和end指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1
- replace(old,new) 把字符串中的old替换成new
- split(str=””) 以str为分隔符拆分字符串,返回的是字符串拆分后的列表
- index(str,beg=0,end=len(string)) 跟find() 方法一样,只不过,如果str不在字符串中会报一个异常
- ‘指定符号 如,’.join([‘a’,’b’,’c’]) 以指定符号连接后面列表中的字符串元素,以字符串形式返回
- isdigit() 如果字符串只包含数字,则返回true,否则返回false
- isalpha() 判断字符串中是否只包含字母
- islower() 如果字符串中至少包含一个区分大小写的字符,并且所有这些(区分大小写的)字符,都是小写,则返回true,否则返回false
- isspace() 如果字符串只包含空格 返回true 否则返回false
- istitle() 判断字符串是否是标题化的
- lower() 转换字符串中所有大写字符为小写
- startWith(str,beg=0,end=len(string)) 检查字符串是否以指定的str开头,是则返回true, 否则返回false。如果beg和end指定值,则在指定范围内检查
- strip(str) 删除字符串两边的str代表的字符,如果不指定str,则删除字符串两边的空白字符
- rstrip(str)和lstrip(str) 删除字符串右边或者左边的str指定的字符
列表类型list
列表的表现方式是:一个方括号内,以逗号分隔数据项。
列表中的数据项的类型可以是不一样的。
列表也可以嵌套列表
基本操作
mylist = [1, 2, 3]# [1, 2, 3]print(mylist)# 取元素# 2print(mylist[1])# 修改元素的值mylist[1] = "hello"# # [1, 'hello', 3]print(mylist)# 删除元素del mylist[1]# [1, 3]print(mylist)# 列表情况mylist.clear()# []print(mylist)
两个list之间的赋值
list1 = [1, 2, 3]# 这个意思是将list1内存地址赋值给list2,所以list1的修改也会影响到list2的修改list2 = list1# [1, 2, 3]print(list1)# [1, 2, 3]print(list2)list1[1] = 'hello'# [1, 'hello', 3]print(list1)# [1, 'hello', 3]print(list2)# 这个意思是将list1中的内容赋值给list2,所以list1的修改不会影响到list2的修改list2 = list1[:]list1[1] = 'aa'# [1, 'aa', 3]print(list1)# [1, 'hello', 3]print(list2)# 这个会达到和list2 = list1[:]同样的效果list2 = list1.copy()list1[1] = 'bb'# [1, 'bb', 3]print(list1)# [1, 'aa', 3]print(list2)
嵌套列表的取值
list3 = [1, 2, [3, 4, 5, 6], 3]# 4print(list3[2][1])
列表的常用方法
- list.append(obj) 在列表末尾添加新的对象
- list.count(obj) 统计某个元素在列表中出现的次数
- list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
- list.index(obj) 从列表中找出某个值第一个匹配项的索引位置,索引从0开始
- list.insert(index,obj) 将对象插入列表的指定位置3
- list.pop(index) 移除列表中指定位置的一个元素(默认是最后一个元素),并且返回该元素的值
- list.remove(obj) 移除列表中某个值的第一个匹配项
- list.reverse() 翻转列表
- list.sort() 对原列表进行排序,无返回值 默认是升序。list.sort(reverse=true),按降序排序
- max(list) 列表的最大值
- min(list) 列表的最小值
- sum(list) 列表求和
- len(list) 列表中元素的个数
- list(str) 将字符串强制转换为列表
- list(range(start,end=None)) 快速生成指定范围内的数字列表时
```python
ss = “hello”
将字符串转换为列表
l = list(ss)[‘h’, ‘e’, ‘l’, ‘l’, ‘o’]
print(l)将列表转换为字符串
oo = “”.join(l)hello
print(oo)
快速生成1到10之间的list
list4 = list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(list4)
快速生成0到4之间的list
list5 = list(range(5))
[0, 1, 2, 3, 4]
print(list5)
<a name="uJe4c"></a>### 元组类型- python的元祖与列表类似,不同之处在于元祖的数据一旦初始化就不能做修改,增加,删除等操作,元组使用小括号(),列表使用中括号[]- 元组的创建比较简单,只需要在小括号中添加元素,并使用逗号,分隔开即可- 如果元组的元素只有1个的话,必须在元素的后面加一个逗号,才会认为是元组<a name="voDzx"></a>#### 元组的常用方法- len(tuple) 计算元组的个数- max(tuple) 元组中元素的最大值- min(tuple) 最小值- tuple(seq) 将列表转换为元组<a name="lwq8r"></a>### 集合类型set- 是一个无序不重复的元素集,主要用于消除重复元素- 集合是用大括号{}包含元素,元素之间使用逗号,分隔- 通过set([1,2,3,4]) 可以将[12,3,4] 强制转换为集合<br />set("hello") 就可以将“hello”强制转换为集合<a name="YTvNF"></a>#### set 常见操作1. 添加一个元素s.add(12)2. 删除一个元素s.remove(12)3. 删除整个集合,连变量一起删除del(s)4. 清空集合s.clear()5. 长度计算len(s)6. 判断元素在不在集合中1. 元素 in 集合,返回值为true或false 例如: "hello" in s.判断集合s中是否有元素hello7. 遍历集合1. for item in s item表示集合中的每一个元素,s表示集合<a name="Hn6Sw"></a>### 字典数据类型- 字典是无序的对象集合。字典中的元素是通过键来存取的。- 字典的每个键:值用冒号:分隔,每对键值对之间用逗号,分隔。整个字典包括在花括号{}中,格式如下所示 d={key1:value1,key2:value2}- 字典的键不可重复,可以通过键获取值```pythondic1 = {"name": "xj", "age": 26}# {'name': 'xj', 'age': 26}print(dic1)# xjprint(dic1["name"])
字典常用方法
- clear() 删除字典中的所有元素
- copy() 返回一个字典的深复制,复制内容。即两个字典指向不同一个内存地址
- formkeys([]) 创建一个序列seq中的元素作为键的新字典
- get(key,defalut=None) 返回指定键的值,如果key不在字典中返回default值
- dict.update(dict2) 把字典dict2的键值对更新到dict中
- keys() 返回字典中所有的键的列表
- values() 返回字典中所有的值的列表
- items() 返回字典中的所有的键值对的列表
- popitem() 随即删除字典中的任意一个键值对
- pop(key) 删除指定的键值对
python控制结构
- 顺序结构
- 分支结构
- 循环结构
顺序结构
程序按照从上到下的顺序依次执行
分支结构
普通的分支结构
if 条件A:代码Aelif 条件B:代码belse:最后代码age = int(input("请输入您的年龄:"))if age < 0:print("胚胎")elif age >= 0 and age < 12:print("儿童")elif age >= 12 and age <= 18:print('少年')else:print("成年人")
嵌套的分支结构
if 表达式1:语句if 表达式2:语句elif 表达式3:语句else:语句elif 表达式4:语句else:语句
分支结构-比较运算符
if语句中常用的比较运算符的书写方式:
if a>bif a<=bif a==bif a!=bif a # 当a为真时,条件成立,等价于a==Trueif not a # 当a为假时,条件成立,等价于a==False# 在python中,会被认为为False的值有:None,[],'',0,{},()
循环结构
- while循环
- for循环
- for循环一般用在一个已知的集合里面进行循环的时候,比如列表里面循环、range数字范围内循环、集合循环、字典循环等
- while循环一般用于明确知道循环条件,比如大于某个值,或者某个值为真或假时。
while循环
while 循环条件循环体
for循环
for item in 变量
break
continue
循环后面加入else
不管是for循环还是while循环,当循环后面写了else语句时,只有当循环正常结束后才会执行else语句,如果循环中执行了break,else就不会执行。
for item in 变量:循环体else:语句while 循环条件循环体else:语句
占位关键字pass
当循环体中没有内容时,可以使用pass进行占位,而不报语法错误,仅仅为了保持语法的完整性
函数
函数用于将相关功能打包,并参数化
python中有4种不同类型的函数
- 内置函数:python内置的已经写好的函数,如print()
- 模板函数:从python的一个模板导入的函数
- 自定义函数
- 嵌套函数
函数的定义
python定义函数必须使用def关键字,函数名为用户自定义名称,参数列表为此函数使用的参数,下面是函数体
def 函数名(参数列表):函数体
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
- 函数的参数必须放在圆括号中
- 函数的第一行语句可以选择性地使用文档字符串,用于存放函数的注释说明
- 函数内容以冒号开始,并且缩进。return [表达式]结束函数,选择性地返回一个值给调用方
- 不带return语句,相当于返回None
函数参数
形参
在函数定义时,跟在函数名后面的括号内定义的参数,形参的主要作用是用于占位,形参的实际值,是由调用函数时传递的实际参数决定的
实参
函数调用时,在对应的形参位置传入的实际参数值
形参和实参的相互影响
- 如果参数是不可变数据类型,则改变形参的值并不会改变实参的值
- 如果参数是可变数据类型,则改变形参的值,同时也会改变实参的值
关键字参数
可以使用形参的参数名=值来调用函数,这样可以不按顺序传参,这种一般不用。一般按顺序传参就行
形参默认值
当定义函数时,可以为形参指定默认值,当设置了默认值的形参没有传入实参时,就使用默认值
def add(a,b=10):return a+b# 结果为3print(add(1, 2))# 结果为11print(add(1))
不定长参数
- 在形参前加星号,表明这个形参是不定长参数,不定长参数的类型是元组
```python
def printinf(args):
for item in args:
print("参数为:",item)
printinf(a,b,1,2)
- 在形参前加两个星号**,表明这个形参是字典类型的不定长参数。```pythondef printinf(**kwargs):for k,v in kwargs.items():print("参数名为:",k)print("参数值为:",v)printinf(name="xj",age="26",sex ="0")
- 在具体调用方法时,如果需要将传入的一个类似列表的参数不作为实际参数,而是将列表中的每个元素作为实际参数传进去,需要在调用时,需要解包的list1前使用星号 。 如:方法名(实参1,list1)
```python
def printinf(*args):
for item in args:
print("参数为:",item)
list1=[1,2,3,4]
输出内容:
参数为:[1,2,3,4]
printinf(list1)
输出以下内容
参数为:1
参数为:2
参数为:3
参数为:4
printinf(*list1)
<a name="Z2UAc"></a>### 函数变量的作用域- 函数中的变量只能在函数内使用- 在函数中,定义了一个与全局变量同名的局部变量,并不会影响到全局变量的值- 要修改全局变量,需要使用global表明当前使用的变量是一个全局的变量,不是新创建的局部变量```pythonb=1def pring():a=0b=30 # 在函数中,定义了一个与全局变量同名的局部变量,并不会影响到全局变量的值print(b)print(a)pring()print(b )b=1def pring():a=0global b # 使用global表明当前使用的变量是一个全局的变量,不是新创建的局部变量b=30 # 此时对b的修改,就是对全局变量的修改print(b)print(a)pring()print(b )
变量使用规则
- 当在一个函数中创建一个变量时,默认情况下它是局部变量,只在当前的函数生效
- 当在一个函数之外定义一个变量时,默认情况下它是全局变量,不必使用global关键字
- 在函数里面读取一个全局变量时,不需要加global,但如果要给全局变量重新复制,则必须要使用global。注意,如果调用该变量的方法不算重新赋值,比如list.append()这种,可以不用使用global
- 如果函数内部有与全局变量名字相同的局部变量,则全局变量必须使用global来进行标识
- 在一个函数外使用global关键字没有效果
匿名函数
使用lambda声明的函数,它的函数体只能有一行内容,返回值是这行内容
# 匿名函数func = lambda a, b: a + b# 3print(func(1, 2))
全局变量与局部变量
- 全局变量:定义在函数外的变量
- 局部变量:定义在函数内的变量
python模块
任意一个python文件就是一个模块。模块是一个包含定义的函数和变量的文件,其后缀名为.py
使用import导入模块
# 导入自定义的模块时,指定模块的路径(包名.模块名)# import moduleimport demo.file2# 通过demo.file2.方法名/变量名进行访问demo.file2.test1();# 从demo.file2中导入test1方法from demo.file2 import test1# 通过test1访问test1()# 从demo.file2中导入test1,test2from demo.file2 import test1,test2# 通过test1访问test1()# 通过test2访问test2()# 从demo.file2中导入a变量from demo.file2 import a# 通过a访问print(a)# 导入demo.file2中的所有包名和变量名from demo.file2 import *# 通过test1访问test1()# 通过test2访问test2()# 通过a访问print(a)
规范
- import module
- from module import func
- from module import fa,fb,fc
- from module import *
- 如果要经常访问模块的属性和方法,可以使用from module import *
- 如果想要有选择地导入某些属性和方法,而不想要其他的,使用from module import xx
- 如果文件包含的属性和方法与模块中的同名,必须使用import module 来显示的避免名字冲突
- 尽量少用from module import *,因为判定一个特殊的函数或属性是从哪来的有些困难,并且会造成测试和重构都更困难
if name == “main“:
name属性是每个py文件的一个内置属性,当这个文件被直接执行时,name属性的值为main。如果被作为一个模块导入到别的文件中使用时,name属性的值会变为文件名。所以可以利用这个特性来判断当前文件的使用方式,从而执行特定的代码。
比如不想导入的时候,就执行导入模块中的方法,可以这样使用:
# a.py文件def test1():print(1)returnif __name__ == "__main__":test1()# b.py文件improt 包名.a# 这样就会在a导入的时候,test1()方法不会自动执行
面向对象
- 类: 具有相同属性和方法的总称
-
类
定义
# 定义一个aa类class Aa:
类的使用
实例方法:self用在方法的第一个参数,表明该方法是一个实例方法,只能通过实例对象调用,在调用时,不用传入self,只传入方法中定义的其他参数。跟具体的实例有关的方法,可以定义成实例方法
类方法:使用‘@classmethod’注解,方法的第一个参数必须是cls, 该方法就是类方法,可以通过类名来访问。 跟具体的某个实例没有关系的方法,可以定义为类方法。 ```python class Student: a = 1
init方法会在初始化类的实例的时候,被自动调用
def init(self, name, age, sid):
# 定义实例属性self.name = nameself.age = ageself.sid = sid
self表示是实例方法,只能有类的实例来调用
def study(self):
print("{}在学习".format(self.name))
@classmethod注解,方法的第一个参数必须是cls, 该方法就是类方法
@classmethod def running(cls):
print("学生在跑步")
@property注解,表明该方法是一个属性方法,提供属性的访问。这里是提供money的这个实例属性的访问 通过实例名.money就能访问
@property def money(self):
return 10000000
创建一个对象:Student类的实例
stu = Student(“xj”, 26, “s001”)
实例方法的访问
stu.study()
实例属性的访问
print(stu.name)
类方法的访问
Student.running()
类属性的访问
print(stu.a) print(Student.a)
通过属性方法访问属性,不能修改属性
print(stu.money)
<a name="aKM9d"></a>#### 继承- 如果子类没有定义初始化函数,父类的初始化函数会显示的被调用。- 如果子类定义了初始化函数,那么在子类的初始化函数体中,必须要首先显示调用父类的初始化函数- 子类可以覆盖父类的方法,实现不同的逻辑- 子类可以有自己独有的属性和方法```pythonclass RichMan:def __init__(self, money, company):self.money = moneyself.company = companydef earnMoney(self, number):self.money += numberdef spendMoney(self, number):self.money -= numberdef showMoney(self):print("i have :", self.money)# 括号内表明继承于RichManclass RichChild(RichMan):def __init__(self, money, company):# 显示调用父类的init方法,确保父类初始化成功super().__init__(money, company)self.myMoney = 0# 覆盖父类的方法def earnMoney(self, number):self.myMoney += number# 子类独有的方法def ownMoney(self):print("我有{}".format(self.myMoney))rc = RichChild(200000000, 8)# 富二代有200000000print("富二代有{}".format(rc.money))# 富二代有8个公司print("富二代有{}个公司".format(rc.company))rc.earnMoney(10000)# 继承了200000000print("继承了{}".format(rc.money))# 自己挣了10000print("自己挣了{}".format(rc.myMoney))
python文件操作
操作文件的基本语法
with open(r'文件路径',mode='文件操作模式',encoding='utf-8') as f:文件具体操作代码
- 变量名f是指向打开w文件的句柄
- 文件路径可以是相对路径,也可以是绝对路径
- open方法只能用于读取txt/csv等文本文件,不能读取Word、Excel等第三方文件,第三方文件必须用专门的库才能操作
- encoding指定中文的编码
常用文本文件读写模式
- r 读模式,只能进行读操作,不能进行写操作,而且文件必须存在,否则会报找不到文件的异常,默认就是r模式。
- w 写模式,只能进行写操作,不能进行读操作。如果用w模式打开一个已经存在的文件,会立即清空以前的文件内容,如果要打开的文件不存在,则会自动创建对应的文件。
- a 追加写模式,也不能读操作,但是在文件尾部追加写入新的内容,文件可以不存在。
常用的文件读写的方法
f.read() # 一次性读取所有文件内容f.read(100) # 读取参数指定的字符长度f.readline() # 读取一行内容,如果指定数字则只读取一行中指定的字符数f.readlines() # 按行读取全部内容到一个列表中for line in f: # 通过循环来读取文件# 以写模式打开文件。写入的内容需要自己手动加入\n进行换行f.write('要写入的字符串\n') # 以字符串的形式写入f.writelines(list1) # 以列表的形式写入
python异常处理
语法
try:可能出现异常的代码except 异常类型1:异常类型1的处理代码except 异常类2 as e:异常类型2的处理代码except 异常类型n:异常类型n的处理代码except:其他位置异常的处理代码finally:异常处理结束后要执行的代码
异常处理代码的原则
- except语句不是必须的,finally语句也不是必须的,但是二者必须要有一个,否则try就没有意义了
- except语句可以有多个,python会按except语句的顺序依次匹配你指定的异常,如果异常已经处理就不会在进入后面的except语句
- except语句可以以元组形式同时指定多个异常
- except语句后面如果不指定异常类型,则默认捕获所有的异常
- 只要有finally语句,不管有没有异常,finally里面的代码都会执行
python装饰器
用来装饰其他函数的函数,为其他函数添加特定功能或约束的函数,在python中装饰器都是以@符号开头的
装饰器的原则
- 不能修改被装饰函数的源代码
- 不能修改被装饰函数的调用方式
学习装饰器前必须掌握的概念
- 函数即变量
- 高阶函数
- 嵌套函数
-
函数即变量
如果函数名加了括号,则代表执行函数,如果没有加括号,则代表函数的引用地址
函数名跟变量名一样,只是一个变量的标识符,它执行函数调用的内存地址
- 在函数定义中去调用其他函数时,并不会立即调用其他函数
- 在执行一个调用了其他函数的函数时,如果在内存中还没有找到被调用函数的定义,则程序会报错 ```python def hello(): print(“hello”)
如果函数名加了括号,则代表执行函数,如果没有加括号,则代表函数的引用地址
这里a指向了hello函数的引用
a=hello
这里相当于执行函数hello
a();
<a name="Yksbp"></a>#### 高阶函数符合以下条件之一的函数就是高阶函数- 接收函数名作为形参- 返回值中包含函数名<a name="GyDcf"></a>#### 嵌套函数通过def关键字定义在另一个函数中的函数叫做嵌套函数```pythondef foo():print('in foo')def boo():print('in boo')
实现装饰器
def foo():sum = 0for i in range(1000000):sum += iprint(sum)import timedef timer(func):def gf():# 记录当前时间start_time = time.time()# 调用传入的函数func()# 记录结束的时间end_time = time.time()print("函数运行的时间:", end_time - start_time)return gffoo = timer(foo)foo()
或者使用下面的简洁方式:
import timedef timer(func):def gf():# 记录当前时间start_time = time.time()# 调用传入的函数func()# 记录结束的时间end_time = time.time()print("函数运行的时间:", end_time - start_time)return gf@timerdef foo():sum = 0for i in range(1000000):sum += iprint(sum)# foo = timer(foo)foo()
装饰器编写的基本步骤
- 定义一个接受函数名作为参数的高阶函数
- 在高阶函数中定义一个嵌套函数,在该嵌套函数中
- 封装想要的功能代码
- 调用作为参数传入函数名
- 高阶函数中返回嵌套函数的函数名
多线程
进程是资源分配的最小单位,线程是CPU调度的最小单位
- join方法:用于阻塞主线程,等子线程运行完后再运行主线程
- setDeamon方法:守护线程,将子线程设置为守护线程,主线程结束,子线程必须跟着结束
```python import threading import timet.setDaemon(daemonic=True)
nameList = [‘xiaohong’, ‘xiaohua’, ‘xiaolan’]
def dothing(content): for item in content: print(threading.current_thread().getName() + item) time.sleep(1)
threadlist = [] for i in range(1, 4):
# 参数必须以元组形式传入,如果只有一个参数,必须打逗号t = threading.Thread(target=dothing, args=(nameList,))t.start()threadlist.append(t)
for item in threadlist:
# 用于阻塞主线程,等子线程运行完成后再运行主线程item.join()
print(‘主线程结束’)
<a name="MHgN8"></a>## python反射<a name="fnv5O"></a>### 反射的概念通过字符串的形式,在运行时动态修改程序的变量、方法及属性的操作。注意,对于反射操作中所有的修改都会在内存中进行,所以它并不会实际修改代码,主要目的是提高代码在运行时的灵活性<a name="gTAGo"></a>### 常用的方法- hasattr:判断对象有没有这个方法或属性- getattr:获取对象属性值或方法的引用。如果是方法,则返回方法的引用,如果是属性,直接返回属性值。如果该属性或方法不存在,则抛出异常- setattr:动态添加一个方法或属性- delattr:动态删除一个方法或属性<a name="gl4Ce"></a>### 举例子```pythonclass Dog:def __init__(self, name):self.name = namedef eat(self):print('{}正在吃东西...'.format(self.name))def sleep(self):print('{}正在睡觉觉...'.format(self.name))dog = Dog('二哈')func = input('请输入您要执行的方法名:')if hasattr(dog, func):try:# getattr假如返回方法名,执行方法getattr(dog, func)()except TypeError:# 不是方法,就是属性,打印属性print(getattr(dog, func))else:print('没有这个属性或方法')# 在绑定前先查询dog对象默认的属性和方法名print(dir(dog))attr_name = input('请输入一个属性名:')attr_value = input('请输入一个属性值:')setattr(dog, attr_name, attr_value)# 在绑定后查询dog对象的属性和方法print(dir(dog))print("二哈的年龄为:", getattr(dog, attr_name))def talk(content):print('二哈说:{}'.format(content))method = input('请输入要绑定的方法名:')# 给dog绑定一个方法,方法的实现是talk()方法的实现,方法名由用户定setattr(dog, method, talk)print(dir(dog))getattr(dog, method)('今天天气不错')
输出为:
请输入您要执行的方法名:二哈正在吃东西...['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'eat', 'name', 'sleep']请输入一个属性名:请输入一个属性值:['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'eat', 'name', 'sleep']二哈的年龄为: 1请输入要绑定的方法名:['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'eat', 'name', 'say', 'sleep']二哈说:今天天气不错
日志
- 使用import logging导入日志模块
- 日志级别有:DEBUG/INFO/WARNNING/ERROR/CRITICAL
- handler处理器:将日志记录发送到合适的路径
- StreamHandler:控制台
- FileHandler:文件。使用logging.basicConfig(level=logging.INFO,filename=’run.log’)
- NullHandler: 不做任何格式化输出
- Format: 日志格式
- %(levelno)s:打印日志级别的数值
- %(levelnames)s:打印日志级别名称
- %(pathname)s: 打印当前执行程序的路径
- %(filename)s:打印当前执行程序名称
- %(funcName)s:打印日志的当前函数
- %(lineno)d:打印日志的当期行号
- %(asctime)s:打印日志的时间
- %(thread)d:打印线程id
- %(threadName):打印线程名称
- %(process)d: 打印进程ID
- %(message)s:打印日志信息
- logging.basicConfig(level=logging.INFO, filename=’run.log’,
format=’%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s’)
也可以使用配置文件的方式,保证得到统一的日志配置:
logger.conf
[loggers]keys=root,infoLogger[logger_root]level=INFOhandlers=consoleHandler,fileHandler[logger_infoLogger]handlers=consoleHandler,fileHandlerqualname=infoLoggerpropagate=0[handlers]keys=consoleHandler,fileHandler[handler_consoleHandler]class=StreamHandlerlevel=INFOformatter=form01args=(sys.stdout,)[handler_fileHandler]class=FileHandlerlevel=INFOformatter=form01args=('../logging-demo/run2.log','a')[formatters]keys=form01[formatter_form01]format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
logger_config.py
conf_file='logger.conf'logging.config.fileConfig(conf_file)logger = logging.getLogger()
logger使用:
from logging_demo.loggin_conf.logger_config import loggerlogger.info('测试日志')
