基本语法:
- 类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。
- 实例名和模块名都采用小写格式,并在单词之间加上下划线。
注释:
# 单行注释:行内注释
""" 多行注释:Python文件、类或方法进行解释 """
制表符:\t
print("\tPython")
换行符:\n
print("\nPython")
'\ ': 续行
行尾输入一个反斜杠加一个空格(’\ ‘),再换行。如果行尾语法明显未完成(比如以逗号结尾),可以直接续行。
print:打印
// 字符串
print("abc")
// 常数
print(123)
// 变量
text = 'abc'
print(text)
a = {
"aa": {
"aaa": "aaa"
},
"bb": {
"bbb": "bbb"
}
}
print(a)
# f 内嵌字符串
print(f"输出:{a}")
变量
# 变量无类型,存储的数据有
# 声明变量a
a = 123
# 删除变量:del()
# 复制变量:直接将变量a赋值给b,有时仅仅复制了一个“引用”。此后 b 与 a 的改动仍会互相影响。必要时使用 a is b 来判断是否同址。
a = [1, 2]
b = a
# id()计算地址差为 0,表示实质是同址的
print(id(a) - id(b))
# a is b True:来判断是否同址
print(a is b)
# b 添加元素
b.append(3)
# 只改动了 b,但 a 也跟着变动了
print(a)
print(a is b)
数据结构
整数(int)与浮点数(float)两种
四则运算:+, -, , /
乘方: *
平方:**
整除: 5 / 2 = 2,取余:5 % 2 = 1
自运算: a += 1 (四则与乘方均可类似自运算)
细节:
- 运算两数中只要有一个浮点数,结果就是浮点数;
- 整数相除,即使能除尽,结果也是浮点数;
- Python 内部的机制解决了整数溢出的问题,不用担心。
布尔
首字母大写 True / False
查看变量类型
# 数字:
# type(被查看类型的数据)
type_1 = type("我是字符串")
print(type_1)
type_2 = type(123)
print(type_2)
type_3 = type(11.345)
print(type_3)
序列
字符串(str)、列表(list)与元祖(tuple)
- 序列索引规则:
- 索引从0开始,到 N-1 结束。
- 切片:切片的索引是左闭右开的。
- seq[0:2](从 0 到 1)
- seq[2:](从 2 到尾)
- seq[:3] (从头到 2)
- seq[:](全部)
- seq[:10:2](从头到9,每两个取一个)
- seq[::2](全部,每两个取一个)
- 索引允许负数:seq(-1) 与 seq(N - 1) 等同,seq(-3:-1)与 seq(N-3:N-1) 等同。
- 序列通用函数:
- len():返回序列长度。
- +/* :加号用于连接两个序列,乘号重复排列若干次再连接。
- seq1 in seq2:如果 seq1 这个片段可以在 seq2 中被找到,返回 True.
- index:在 seq1 in seq2 为 True 时使用,seq2.index(seq1) 表示 seq1 首次出现于 seq2 中的位置。
- max()/min():返回序列中的最值。如果不是数字,则按 ASCII 码顺序返回。
- cmp(seq1, seq2):比较大小。结果为负,则表示 seq1 较小。
字符串
函数
str()
:强制转换为字符串
转义:反斜杠。如果强制不解释字符串,在左引号前加字母 r 即可:r "D:\new"
分割:xx.split()
连接:xx.join()
紧切:xx.strip()
去掉字符串首尾两端的空格。方法lstrip() / rstrip()
则只切除首端/尾端的空格。
格式化:xx.format()
成员函数完成。
大小写转换:
- 首字母大写:
xx.title()
- 全大写:
xx.upper()
- 全小写:
xx.lower()
- 句首大写:
xx.capitalize()
xx.replace(old, new[, times])
:将字符串中前 times 个 old 子串替换为 new。Times 不指定时默认替换全部xx.isdigit()
:判断字符串是否每一位都是数字,返回 True 或者 False。
text='单引号'
text="双引号"
text="""三引号"""
text="""
在三个引号的包维权
"""
# 首位是空格
s = " I love Python"
# 按照空格分割
lst = s.split(' ') # 输出:['', 'I', 'love', 'Python']
# 使用 - 拼接
lst1 = '-'.join(lst)
# 输出lst 换行输出 lst1
print(lst, '\n', lst1) #输出: -I-love-Python
s.strip()
print(s) # 输出:'I love Python'
# {}占位, {0}:取第1个参数
# 按顺序引用
s1='I like {} and {}'.format('第1位', '第2位')
print(s1)
# 按编号引用
s2='{0} + {2} = {1}'.format ('第1位', '第2位', '第3位')
print(s2)
# 编号反复引用
s3='{0} * {1} = {0}'.format ('第1位', '第2位')
print(s3)
# 总宽 7 位小数点后 2 位,左侧补零
s4="{:0>7.2f}".format(123.4)
print(s4) # 0123.40
例子 | 含义 |
---|---|
:c/s | 单个字符 、 字符串 |
:f | 浮点数 |
:.2f | 两位小数 |
: .2f (有个空格) | 正数前补空格的两位小数 |
:+.2f | 带符号位两位小数 |
:.2% | 百分比两位小数 |
:e | 科学计数法 |
:.2e | 科学计数法两位小数 |
:, | 逗号分隔符 |
:b/o/x/d | 二进制数、八进制数 、十六进制数 、十进制数 |
:^4d | 总宽四位居中对齐 |
:0>4d | 总宽四位左侧补零 |
:>4d | 总宽四位左对齐 |
:<4d | 总宽四位右对齐 |
列表:[ ]
list() 用于强制转换类型,有序集合,索引从0开始,索引指定为-1返回最后一个元素
lst = [1, 2, 3]
print('lst数组:', lst) # 输出:[1, 2, 3]
print('获取第一个元素:', lst[0]) # 输出:1
print('获取最一个元素:', lst[-1]) # 输出:3
# 判断列表是否为空
if lst:
print('列表不为空')
else:
print('列表为空')
# 【长度】
print('计算数组长度:', len(lst)) # 输出:3
# 【反转】:
# 第一种:将元素反转,给赋值给新数组,原数组不变
lst1 = list(reversed(lst))
print('lst1数组:', lst1, 'lst数组:', lst) # 输出:[3, 2, 1] [1, 2, 3]
# 第二种:原数组反转
lst.reverse()
print('lst数组反转:', lst) # 输出:[3, 2, 1]
# 【添加】
# 添加一个元素,到列表末尾
lst.append(4)
print('lst追加元素:', lst) # 输出:[3, 2, 1, 4]
# 将lst1全部追加到lst
lst.extend(lst1)
print('lst追加list:', lst) # 输出:[3, 2, 1, 4, 3, 2, 1]
# 【插入】:lst.insert(idx, obj) 会在 lst[idx] 处插入 obj,然后依次后移原有项
lst.insert(1, 100)
print('lst在idx插入obj:', lst) # 输出:[3, 100, 2, 1, 4, 3, 2, 1]
# 【删除】
del lst[0]
print(lst) # 输出 [100, 2, 1, 4, 3, 2, 1]
# 根据值删除首个匹配值,若无匹配会报错;
lst.remove(2)
print('lst删除首个匹配值:', lst) # 输出:[100, 1, 4, 3, 2, 1]
# lst.pop(idx) 会返回 lst[idx],并将其删除。
# 如果不指定 idx,删除列表末尾的元素
tmp = lst.pop()
print('lst.pop(idx) 会返回 lst[idx],并将其删除。如果不指定 idx,默认为列表尾:', tmp) # 输出:1
# 【搜索】:使用序列通用函数即可。用 count(obj) 可以计算频数。
print('lst搜索匹配值的个数:', lst.count(3))
# 【排序】:sort() 方法。如果指定 reverse 参数,可降序排序。
lst.sort(reverse=True)
print('lst排序:', lst) # 输出:[100, 4, 3, 2, 1]
# 【临时排序】对列表进行临时排序
print('lst临时排序:', sorted(lst)) # 输出:[1, 2, 3, 4, 100]
print('lst临时排序:', sorted(lst,reverse=True)) # 输出:[100, 4, 3, 3, 2, 1]
# 【清空】:clear()
lst.clear()
print('lst清空数组:', lst)
# 最小值
print(min(lst))
# 最大值
print(max(lst))
# 求和
print(sum(lst))
切片:列表的一部分
numbers = list(range(1,6))
# 输出全部
print('输出全部: ' , numbers[:])
# 复制列表
numbers_copy = numbers [:]
print('复制列表: ' , numbers[:])
# 参数一:从第一个下标开始,参数二:到第二个下标前面的元素后停止
print('输出下标0、1、2: ' , numbers[0:3])
# 没有指定第一个索引,将自动从列表开头开始
print('从表头开始,到下标3前结束: ' , numbers[:3])
# 起始索引指定为2,片终止于列表末尾
print('从下标2开始,到表尾结束: ' , numbers[2:])
# 负数索引返回离列表末尾相应距离的元素
# 最后三个元素
print('最后三个元素: ' , numbers[-3:])
set 集合
- 增添:
add()
/update()
- 删除:
remove()
/discard()
,区别在于后者搜索无结果会报错- 从属:
a.issubset(b)
集合 a 是否是 b 的子集;a.issuperset(b)
集合 a 是否是 b 的父集。a == b
两集合是否全等。- 集合运算:集合运算不会改变参与运算的集合本身。
- 并集:
a | b
或者a.union(b)
- 交集:
a & b
或者a.intersection(b)
- 补集:
a - b
或者a.difference(b)
- 注意:在字符串强制转换为集合时,必要时使用中括号先转为列表(否则字符串会被拆分为单个字符后再进行转换)
ss = {"a", "b", "c"}
print(ss | set("de")) # 输出:{'d', 'a', 'b', 'c', 'e'}
print(ss | set(["de"])) # 输出:{'de', 'a', 'b', 'c'}
元组:不可变的列表 ( )
圆括号式的结构,是一种不可变序列。
# 空元组
tuple1=() # 输出:()
print(tuple1)
# 不是元组
tuple2=(1)
print(tuple2) # 输出:1
# 定义只有一个元组的元组,需要加,
tuple3=(1,)
print(tuple3) # 输出:(1,)
a = (1, 'string ', [1 ,2])
print(a) # 输出:(1, 'string ', [1, 2])
字典:内部无序,{ }
字典是一种类哈希表的数据结构,内部无序,通过键值对(key: value)的形式存储数据。
# 字典直接初始化赋值
d1 = {"name": "mm", "age": 18}
print(d1) # 输出:{'name': 'mm', 'age': 18}
# 复制字典给dd
dd = d1.copy()
# 【get】
print(dd.get("year", "Nothing")) # 如果键不存在,返回“Nothing”
# 【setdefault】
dd.setdefault("year", 2023) # 如果键不存在,就新建该键,并赋值
print(dd)
# 【更新】:update(ref_dict) 以 ref_dict 为准,更新当前字典
d4 = {"name": "Test", "Age": 3}
dd.update(d4)
print(dd) # 输出:{'name': 'Test', 'Age': 3}
# 声明一个空字典
d2 = {}
# 添加键值对
d2['name'] = 'mm'
print(d2) # 输出:{'name': 'mm'}
# 修改值
d2['name'] = 'MM'
print(d2) # 输出:{'name': 'MM'}
# 【弹出键值对,并删除】:pop(key)
tmp = d2.pop("name")
print(dd, tmp) # 输出: {}
# 【del】删除键值对
del d2['name'] # 方式一
del(d1['age']) # 方式二
print(d2) # 输出:{}
# 【fromkeys】一个值赋给多个键
d3 = {}.fromkeys(("name", "age"), "NA")
print(d3) # 输出:{'name': 'NA', 'gender': 'NA'}
# 强制格式转换
d4 = dict(name="mm", gender="male")
print(d4) # 输出:{'name': 'mm', 'gender': 'male'}
# 【items()】遍历 key-value
d1 = {
"name": "mm",
"age": 18,
"hight":18
}
# 【输出键值】:第一种
for key , value in d1.items():
print("key: ", key)
print("value: ", value)
# 【输出键值】:第二种
list(dd.items())
# 【keys()】遍历字典中的所有键
for key in d1.keys():
print(key.title())
# 判断是否存在key
if 'gener' not in d1.keys():
print("yes)
# 【values】遍历字典中的所有值
for value in d1.values():
print(value.title())
# 【sorted】按顺序遍历字典中的所有键
for name in sorted(d1.keys()):
print(name.title())
# 【set】去重
for value in set(d1.values()):
print(value.title())
# 嵌套-字典列表
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]
for alien in aliens:
print(alien)
基本语句:
逻辑
逻辑运算符:
- 与: A and B
- 或: A or B
- 非: not A
逻辑关系符:
- 等于: ==
- 不等于: !=
if 语句
# 【==】相等
cars = ['audi', 'bmw', 'subaru', 'toyota']
for car in cars:
if car == 'bmw':
print(car.upper())
else:
print(car.title())
# 【!=】 不相等
a = "python"
if a != "python":
print("not")
# 【and / or】多条件
age = 18
if age >= 1 and age <= 20:
print("yes")
# 【in】查特定值是否包含在列表中
nums=['1','3']
print('1' in nums)
# 特定值是否不包含在列表中
if '1' not in nums:
print("True")
# 【if-elif-else】
age = 12
if age < 4:
print("cost is $0.")
elif age < 18:
print("cost is $5.")
else: # 可以忽略
print("cost is $10.")
# 【判断列表是否为空】
lst = []
if lst:
print('列表不为空')
else:
print('列表为空')
a = 2
# 判断 a > 1 and a > 1.5
if 1 < a > 1.5:
a = 1
print(a) # 输出:1
# X = a if flag else b:flag为True,X=a,否则X=b
a = 1 if 2 < 1 else 2
print(a) # 输出:2
for 循环
- break:跳出循环体
- continue:循环步进
flag = 0
nums = [1, 2, 3, 4, 5]
for num in nums:
print(num)
if i > 3:
flag = 1
break
# 【for…else…】
for num in nums:
print(num)
if i > 10:
flag = 1
break
else:
flag = 2
print(flag ) # 输出:2
while 循环
num = 1
while num <= 5:
num += 1
else:
b = num
print(b, num) # 输出:6 6
# continue 跳过当前
num = 1
while True:
if num >= 5:
break
if num % 2 == 0:
print(num)
num += 1
# break 退出循环
num = 1
while True:
if num >= 5:
break
print(num)
num += 1
squares : 列表解析
squares = [value ** 2 for value in range(1, 11)]
print(squares) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 加入判断value值,满足条件输出
squares = [value ** 2 for value in range(1, 11) if 3 < value < 8]
print(squares) # 输出:100
函数
def 定义函数
def greet_user():
print("Hello!")
greet_user()
# 向函数传递信息
def greet_user(username, name='默认值'):
"""显示简单的问候语"""
print("Hello! ", username, " My name is ", name)
greet_user('A') # 输出:Hello! A My name is 默认值
# 关键字实参:传递给函数的名称—值对
greet_user(username='A') # 输出:Hello! A My name is 默认值
# 一只名为Harry的仓鼠
greet_user('B', 'C') # 输出:Hello! B My name is C
# 指定参数值
greet_user(username='B', name='C') # 输出:Hello! B My name is C
greet_user(name='C', username='B') # 输出:Hello! B My name is C
# 有返回值
def get_default_name(a, b=''):
if b:
# b 有值
return a.title()
return a.title()
default_name = get_default_name('我是返回值')
print(default_name)
# 直接操作原列表,会改变原列表
function_name(list_name)
# 复制一个数组,原列表不变
function_name(list_name[:])
函数 range(),随机生成随机数
函数 range(N, M=0, s=1) :是一个生成等差数列的函数,位于左闭右开区间[M,N)上且公差为 s
# 从你指定的第一个值开始数,并在到达你指定的第二个值后停止
nums = range(1,5)
for num in nums :
print(num)
# 使用函数list()将range()的结果直接转换为列表
numbers = list(range(1,6))
print(numbers)
# 打印1-10内的偶数
even_numbers = list(range(2,11,2))
print(even_numbers)
lambda 函数:一种匿名函数的声明方式
func = lambda x, y: x * y
z = func(12, 6)
print(z) # 输出:72
map 函数:能够对传入的序列进行依次操作,并将结果返回为一个可转换为列表的 map 对象
# range(5),依次传入值,进行x+1,并入列表中
lst = list(map(lambda x: x + 1, range(5)))
print(lst) # 输出:[1, 2, 3, 4, 5]
# lambda函数:x=x+1
func = lambda x: x + 1
# for x in range(5):输出 0 1 2 3 4
print([func(x) for x in range(5)]) # 输出:[1, 2, 3, 4, 5]
filter 函数:满足返回条件的值
# 将range(-3, 3)参数的值,过滤 x > 0满足条件的值,放入列表中
print(list(filter(lambda x: x > 0, range(-3, 3)))) # 输出:[1, 2]
reduce 函数
需要导入 functools 模块
from functools import reduce
# 0+1+2+3+4=10
print(reduce(lambda x, y: x + y, range(5))) # 输出:10
enumerate 函数 相当于 items()
nums = ['a', 'b', 3]
for index, value in enumerate(nums):
print("lst[{}] = {}".format(index, value))
# 输出:
# lst[0] = a
# lst[1] = b
# lst[2] = 3
callable(方法名):判断一个对象是否是一个可调用的函数
def greet_user():
print("Hello!")
greet_user()
print(callable(greet_user)) #输出:True
可变参数
序列(或元组)
:传入时需要加上一个星号
字典
:传入时需要加上两个星号
# 可变参数,创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中
def make_pizza(*toppings):
for topping in toppings:
print("- " + topping) # 元组
make_pizza('A')
make_pizza('B', 'C', 'D')
# 形参:空字典
# **user_info中的两个星号:创建一个名为user_info的空字典
def build_profile(key, value, **user_info):
user_info[key] = value
print(user_info) # 输出:{'name': 'jack'}
build_profile("name", "jack")
#
lst = [1, 3, 4]
d = {"a": 2, "b": 3, "c": 5}
print("{}+{}={}".format(*lst), "{a}+{b}={c}".format(**d)) # 输出:1+3=4 2+3=5
zip 函数:合并多个列表为一个
a = [1, 2, 3]
b = "abc"
c = list(zip(a, b))
print(c) # 输出:[(1, 'a'), (2, 'b'), (3, 'c')]
函数input():让程序暂停运行,等待用户输入一些文本
message = input("input: ")
print(message)
num = input('请输入你的数字:')
print('\n字符串数字是:',type(num)) # 输出的是字符串
print('\nint()转换是:',int(num)) # 转换的是数字
OrderedDict() 有序字典函数
# 导入模块collections 的OrderedDict类,实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序
from collections import OrderedDict
# 调用OrderedDict()来创建一个空的有序字典
f = OrderedDict()
print(f) # 输出:OrderedDict()
f['c']='3'
f['a']='1'
print(f) # 输出:OrderedDict({'c': '3', 'a': '1'})
装饰器:算子
装饰器是函数的函数——传入的参数是一个函数,返回的值也是一个函数。相当于一个函数集到另一个函数集的映射
def get_name(data="i am 算子"):
return data.upper()
f = get_name
print(f()) # 输出:I AM 算子
# 获取函数名
print(f.__name__) # 输出:get_name
import 导入模块
# 导入模块 文件名是os.py
import os
print('第一种:导入系统os模块')
# os.path.join() 是一个连接路径的函数:C:/Windows/System32
print(os.path.join('C:/Windows', 'System32'))
# 导入time模块中的特定函数sleep
from time import sleep
print('第二种:使用from xx import xx = 从time导入sleep')
# 这里会停5秒钟,time.sleep中的参数是停几秒。
sleep(5)
# 导入time函数
import time
print('第三种')
time.sleep(5)
# 导入time函数取别名
import time as t
print('第三种')
t.sleep(5)
# 导入tkinter模块中的 所有函数
from tkinter import *
print('第四种引入全部:from xx import * ')
# tkinter是Python的一个自带的库,是一个图形界面库
# 直接调用tkinter的TK()函数
root = Tk()
# 将窗口显示出来
root.mainloop()
# 用逗号分隔函数名,可根据需要从模块中导入任意数量的函数:from module_name import function_0, function_1, function_2
# 导入test.py文件
import test
# 调用test文件中的a方法
test.a()
os 模块
#导入模块
import os
# ----- 文件操作 -----
os.rename("a.py", "b.py") # 重命名
os.remove("b.py") # 删除
os.stat("a.py") # 查看文件属性
# ----- 路径操作 -----
os.getcwd() # 获取当前目录
os.chdir(r"d:\list") # 更改当前目录为
os.chdir(os.pardir) # 返回上一级目录
os.mkdir('newfolder ') # 在当前目录新建一个文件夹
os.listdir('d:\list') # 列出文件夹下所有文件的列表
os.removedirs('thefolder ') # 删除空文件夹
os.path.isfile("d:\list") # 检查路径是文件
os.path.ispath("d:\list") # 检查路径是目录
os.path.exists("d:\list") # 检查路径是否存在
# ----- 操作平台相关 -----
os.sep # 当前操作系统的路径分隔符
os.linesep # 当前操作系统的换行符
os.path.join(r"d:\abc", "d") # 连接字串成为路径
re 模块:正则表达式
collection 模块:
- 提供了一种双端列表 deque,可以用 appendleft, extendleft, popleft 等方法从 deque 的左侧(也就是lst[0])进行操作。注意,deque 的更新操作比 list 更快,但读取操作比 list 慢。
- 提供了一种缺省字典defaultdict,可以直接操作键值(即使这个键先前未定义);首次操作时会赋一个合理的初值,比如首次调用 d[“a”] += 1 而字典本身没有 “a” 键时,会自动初始化 “a” 键并赋初值 0。
calendar 模块:判断星期、闰年,输出日历等等。
itertools 模块:在本文“迭代器”小节已进行了简要介绍。
logging 模块:在调试中可能会使用。
urllib 模块:这是一个 HTML 请求模块,常用于爬虫。
import re
print(bool(re.match(r"\d", "1"))) # True
phone = re.compile(r'\d{3,4}-\d{7,8}')
print('匹配:', phone.match('010-9999999').group()) # 010-12345678
# 如果在正则表达式中添加了子组(小括号),那么会返回子组依顺序组成的一个元组
phone = re.compile(r'(\d{3,4})-(\d{7,8})')
print(phone.match('010-12345678').groups()) # ('010', '12345678')
phone = re.compile(r'\d{3,4}-\d{7,8}') # 寻找所有子串
phone_str = '010-66666666, 020-77777777 '
print(phone.findall(phone_str)) # ['010-12345678', '021-65439876']
s = 'a b c' # 用 re.split() 处理连续的空格
print(s.split(' ')) # ['a', 'b', '', '', 'c']
print(re.split(r"\s+", s)) # ['a', 'b', 'c']
class 类定义()
"""
类名:首字母大写
"""
class Dog():
"""
构造函数:__init__():开头和末尾各有两个下划线,
self必不可少,还必须位于其他形参的前面,会自动传递
"""
def __init__(self, name, age):
print(self) # 输出:<__main__.EgClass object at 0x000002531C0AF860>
print(self.__class__) # 输出:<class '__main__.Dog'>
self.name = name
self.age = age
self.gener = 'mm'
def update_gener(self, gener):
self.gener = gener
def to_string(self):
print("name: " + self.name.title() + ",age: " + str(self.age) + ",gener: ", self.gener)
# 初始化属性name,age
my_dog = Dog('willie', 6)
# 访问属性:对象.变量
print("My dog's name is " + my_dog.name.title())
# 调用方法
my_dog.to_string()
# 直接修改属性
my_dog.gener='gg'
my_dog.to_string()
# 通过方法修改属性的值
my_dog.update_gener('MM')
my_dog.to_string()
封装
只要把属性或方法的名称前缀设置为双下划线,__age只能在其内部修改或访问,不能从类的外部进行处理。
前后均添加了双下划线的属性,如 name ,表示特殊属性而不是私有属性,是可以从外部访问的。
class MyClass:
"""
构造函数,age默认值为3
"""
def __init__(self, name, age=3):
self.name = name
self.age = age
# 内部调用方法
self.__age()
"""
封装:内部修改变量
"""
def __age(self):
self.__age = 6
"""
打印方法
"""
def to_string(self):
print("输出__name__: ", self.name) # 输出__name__: dog
print("输出__age: ", self.__age) # 输出__age: 6
a = MyClass("dog", 1)
a.to_string()
@property :
用于限制类属性的读写行为。比如,一个普通的类,封装一个属性,却允许从外部读取它的值,一般我们要写实现的方法调用
class Person:
def __init__(self):
self.__name = "Py"
self.__age = 5
"""
编写获取方法获取内部属性
"""
def get_name(self):
return self.__name
"""
编写获取方法设置内部属性
"""
def set_age(self, age):
self.__age = age
"""
使用装饰器 @property 将一个方法伪装成同名的属性(装饰了 getter 函数后),调用时就不用加上尾部的括号了
"""
@property
def name(self):
return self.__name
"""
使用装饰器 @property 将一个方法伪装成同名的属性(装饰了 @age.setter 函数后),调用时就不用加上尾部的括号了
"""
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError("Age should be an integer.")
else:
self.__age = value
person = Person()
# 使用方法获取值
print(person.get_name())
# 使用装饰器后获取值
print(person.name)
# 使用装饰器后获取值
person.set_age(999)
print(person.age)
# 使用装饰器后赋值age
person.age = 99
print(person.age)
dict:类的特殊属性与方法
print(Person.__dict__) # 输出:{'__module__': '__main__', '__init__': <function Person.__init__ at 0x000001F67EEAB380>, 'get_name': <function Person.get_name at 0x000001F67EEAAE80>, 'set_age': <function Person.set_age at 0x000001F67EF0FBA0>, 'name': <property object at 0x000001F67EE33BF0>, 'age': <property object at 0x000001F67EE32700>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
print(person.__dict__) # 输出:{}
# 修改后的值
person.age = 99
print(person.__dict__) # 输出:{'_Person__age': 99}
# 与实例具有相同值
print(Person.__dict__["age"]) # 输出:<property object at 0x000001F67EE32700>
slots
未被slots修饰的,类的属性不能从外部进行更改、追加。它能够限制属性滥用,并在优化内存上也有意义
class Person:
__slots__ = ("phone")
def __init__(self):
# 外部修改后,
self.phone = '123456'
self.name = 'jack'
person = Person()
# 可以修改
person.phone = '0000'
# 不可以修改,会报错
person.name = 'python'
继承:
类也可以多继承:class A(B, C, D),写在左侧的类的属性与方法,在继承时会被优先采用
isinstance(子类,父类) 函数可以判断一个对象是否是某个类(或其子类)的实例
创建 animal.py 文件
"""
类名:首字母大写
"""
# 父类
class Animal():
"""
方法__init__():开头和末尾各有两个下划线,
self必不可少,还必须位于其他形参的前面,会自动传递
"""
def __init__(self, name, age):
self.name = name
self.age = age
self.gener = 'mm'
def update_gener(self, gener):
self.gener = gener
def to_string(self):
pass # 表示定义留空
创建 dog.py 文件
# 导入父类模块
from animal import Animal
class SleepTime():
def __init__(self, time=8):
self.time = time
def describe_time(self):
print("time: " + str(self.time))
"""
创建子类时,父类必须包含在当前文件中,且位于子类前面。
从Animal 继承
"""
class BigDog(Animal):
def __init__(self, name, age, color='yellow'):
"""初始化父类的属性,将父类和子类关联起来"""
super().__init__(name, age)
# 子类属性
self.color = color
# 子类对象属性
self.sleepTime = SleepTime()
def describe_color(self):
print("color: ", self.color)
"""
重写父类的方法
"""
def to_string(self):
print("name: " + self.name.title() + ",age: " + str(self.age) + ",gener: ", self.gener + ",color: ", self.color)
调用地方:
# 导入dog模块下的所有类
from dog import *
"""
父类
"""
# 初始化属性name,age
animal = Animal('jack', 36)
# 判断是否是子类
print(isinstance(animal , Animal)) # 输出True
# 访问属性:对象.变量
print("My dog's name is " + animal.name.title())
# 调用方法
animal.to_string()
# 直接修改属性
animal.gener = 'gg'
animal.to_string()
# 通过方法修改属性的值
animal.update_gener('MM')
animal.to_string()
"""
子类
"""
my_son = BigDog('xiaoming', 6)
# 子类重载父类的方法
my_son.to_string()
# 调用子类方法
my_son.describe_color()
my_son.sleepTime.describe_time()
iter() 与 next() :迭代器
1:迭代器,凡是定义了__iter__和__next__方法的类都是迭代器;
2:可迭代对象,定义了__iter__或者__getitem__方法的类,叫做可迭代对象。
迭代器一定是可迭代对象,但可迭代对象不一定是迭代器;
实现了__iter__方法的对象是可迭代的,实现了next()方法的对象是迭代器
使用迭代器,当用到了(也就是在调用了next)才会产生对应的数字,可以节约内存了,一种懒惰的加载方式
class MyClass:
def __init__(self, lst):
self.data = lst
self.__index = len(lst)
"""
调用iter函数的时候,生成了一个迭代对象,要求__iter__必须返回一个实现了__next__的对象
"""
def __iter__(self):
return self
def __next__(self):
if self.__index == 0:
# 不想继续有迭代的情况下抛出StopIteration的异常(for语句会捕获这个异常,并自动结束)
raise StopIteration
self.__index -= 1
return self.data[self.__index]
a = MyClass("Meow")
for char in a:
print(char)
try-except 异常
- ZeroDivisionError: 除数为 0.
- SyntaxError:语法错误。
- IndexError:索引超界。
- KeyError:字典键不存在。
- IOError:读写错误。
try:
print(5 / 0)
except ZeroDivisionError as e:
print("error:", e)
# 退出
exit()
else:
# 执行成功则这里,可以处理一些逻辑
print("success")
finally: # 不管有无错误均执行
print("-- End --")
try:
i = 1 / 0
except ZeroDivisionError as e:
print("ZeroDivisionError")
raise
finally:
# 不管有无错误均执行
print("-- End --")
try:
print(5 / 0)
except ZeroDivisionError:
# 什么都不要做,跳过
pass
else:
# 执行成功则这里,可以处理一些逻辑
print("success")
finally: # 不管有无错误均执行
print("-- End --")
# raise 向上抛异常
def makeerror(n):
if n == 0:
raise ValueError("Divided by zero.")
return 1 / n
文件:只能将字符串写入文本文件
命令 | 模式 |
---|---|
‘r’ | 读取模式:不配置时默认 |
‘w’ | 写入模式,会清空原文件,再写入 |
‘a’ | 附加模式,在原文件后追加 |
‘x’ | 创建新文件并写入 |
‘r+’ | 读取和写入文件的模式,如果只有写,则替换文件头,读取多少就替换多少;如果有读,则在最后面追加;有flush()刷新到磁盘后按照重新的逻辑执行 |
参数一:文件路径;参数二:模式,参数三:编码
with open(file_path, ‘r’, encoding=“utf8”) as file_object:
简写:
with open(file_path) as file_object:
读取整个文件
函数 read()
将整个文件读为一个字符串
# 引入 os 模块
import os
# 读取pi_digits.txt文件
"""
关键字with:在不需要访问文件后将其自动关闭
open('打开的文件的名称'):返回一个表示文件的对象
read():读取文件的内容
"""
with open('pi_digits.txt') as file_object:
contents = file_object.read()
# 删除字符串末尾的空白
print(contents.rstrip())
# linux 中的写法,读取linux_files文件夹中的filename.txt
file_path = 'linux_files/filename.txt'
with open(file_path) as file_object:
contents = file_object.read()
print(contents.rstrip())
# Windows 中的写法,读取win_files文件夹中的filename.txt
file_path = 'win_files\\filename.txt'
with open(file_path) as file_object:
contents = file_object.read()
print(contents.rstrip())
逐行读取
函数 readlines()
将整个文件读为一个列表,文件的每一行对应列表的一个元素,适用于大文件读取
file_path = 'pi_digits.txt'
# 第一种:只能在with内
# 简写,去掉'r'
with open(file_path) as file_object:
for line in file_object:
print(line.rstrip())
# 第二种使用方法:可在with外
with open(file_path) as file_object:
# 将文件的各行存储在一个列表中
lines = file_object.readlines()
pi_string = ''
# 在with代码块外使用该列表
for line in lines:
# strip():删除两边的空格
pi_string += line.strip()
# 切片:从0开始,取10个
print(pi_string[:10])
tell() / seek() : 获取 / 移动 文件的位置
file_path = 'pi_digits.txt'
#
with open(file_path, "r", encoding="utf8") as f:
# 获取文件所在位置
print(f.tell()) # 输出 0 #说明在文件第一行
# 读取一行,并去掉尾部空格
print(f.readline().strip())
# 回到文件头
f.seek(0)
# 获取文件所在位置
print(f.tell()) # 输出 0
print(f.readline().strip())
写入文件
file_path = 'pi_digits.txt'
try:
with open(file_path, 'w') as file_object:
# 清空原文件,写入内容
file_object.write("I love python.")
except FileNotFoundError:
msg = "Sorry, the file " + filename + " does not exist."
print(msg)
with open(file_path, 'a') as file_object:
# 在原文件后面追加写入内容,\n表示换行
file_object.write("I \n")
file_object.write("love \n")
file_object.write("python.")
存储数据
json.dump():存储JSON文件
# 导入json模块
import json
numbers = [2, 3, 5, 7, 11, 13]
# 需要写的文件,存储的数据为JSON格式
filename = 'numbers.json'
# 写文件
with open(filename, 'w') as f_obj:
# 参数一:需要写入的内容,参数二:文件对象
json.dump(numbers, f_obj)
json.load() :读取JSON文件
# 导入模块
import json
# 文件
filename = 'numbers.json'
# 读取文件
with open(filename) as f_obj:
# 加载JSON
numbers = json.load(f_obj)
# 输出
print(numbers)
单元测试和测试用例 – 模块unittest
"""py测试文件必须以“test_”开头(或“_test”结尾)"""
"""导入模块unittest"""
import unittest
"""导入要测试的函数"""
import dog
"""测试类必须以Test开头,并且不能有init方法,创建TestCase测试类"""
class aaTestCase(unittest.TestCase):
"""只需创建这些对象一次,并在每个测试方法中使用它们"""
def setUp(self):
"""调用测试方法"""
self.my_dog = dog.BigDog('janis', 7)
"""测试方法必须以“test_”开头,测试dog.py"""
def test_dog(self):
"""对比结果,断言必须使用assert"""
assert self.my_dog.age == 7
# self.assertEquals(self.my_dog.age, 7)
if __name__ == "__main__":
"""让Python运行这个文件中的测试"""
unittest.main()
assertEqual(a, b) | 核实a == b |
assertNotEqual(a, b) | 核实a != b |
assertTrue(x) | 核实x为True |
assertFalse(x) | 核实x为False |
assertIn(item, list) | 核实item在list中 |
assertNotIn(item, list) | 核实item不在list中 |
logging 日志模块
- DEBUG:最详细的级别,所有详细日志都会被输出。
- INFO:检测代码是否按照预期执行。
- WARNING:非预期的事件发生了,或者可能在近期发生(例如:低磁盘空间)。但代码仍然执行。
- ERROR:发生了级别更高的问题,某些功能无法正常实现。
- CRITICAL:严重错误,代码可能无法继续运行。
import logging
# 在控制台打印:$ python main.py --log=WARNING 的方式实现
# logging.basicConfig(level=logging.WARNING)
# filename:日志写入到文件。一般使用 DEBUG 级别。默认会将日志追加到文件末尾
# logging.basicConfig(filename="log.log", level=logging.DEBUG)
# 如果想要覆写文件而不是追加,使用 filemode 参数:
# logging.basicConfig(filename="log.log", filemode="w", level=logging.DEBUG)
# %(message):当前日志字串
# %(asctime):当前时间。默认 datefmt 参数为 %Y-%m-%d %I:%M:%S
# %(levelname):当前日志字串级别。
logging.basicConfig(format='%(levelname)s: %(asctime)s %(message)s', datefmt='%Y-%d-%m %I:%M:%S %p', level=logging.WARNING)
a = 'python'
logging.warning("测试日志打印:{}".format(a))