Python 测开27期 - 柒柒 - Python笔记

作者:王瑾琪
日期:2023/05/17


1. 控制台输出

print()在括号中加上字符串,就可以向屏幕上输出指定的文字

# 打印hello world
>>> print('hello, world')
hello, world

# 接受多个字符串,用逗号“,”隔开,就可以连成一串输出
>>> print('我觉得','这件事情','太酷辣!')
我觉得 这件事情 太酷辣!

# 打印日志
>>> text = '这是日志内容'
>>> print('日志--->',text)
日志---> 这是日志内容

2. 数据类型

整数 int

Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1,100,-8080,0

浮点数 float

浮点数也就是小数,如1.23,3.14,-9.01
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的,而浮点数运算则可能会有四舍五入的误差。

字符串 str

字符串是以单引号’或双引号"括起来的任意文本,比如’abc’,“xyz”
Python允许用’‘’…‘’'的格式表示多行内容

# 忽略字符串转义
>>> print(r'\\\t\\')
\\\t\\

# 字符串格式化
>>> text = '苹果'
>>> print('这是一个%s'%text)
这是一个苹果

# 使用format()进行格式化
>>> print('这是一个{}'.format(text))
这是一个苹果

# 使用f''进行格式化
print(f'这是一个{text}')
这是一个苹果

# 列表转换为字符串 join()
a = ["h", "o", "g", "w", "a", "r", "t", "s"]
# 将列表中的每一个元素拼接起来
print("".join(a))

# 字符串切分 split()
demo = "hogwarts school"
demo.split(" ")

# 字符串文本替换 replace()
# 将原字符串中的school替换为top school
"hogwarts school".replace("school", "top school")

# 去除首尾空格 strip()
# 去除头部空格 lstrip()
# 去除尾部空格 rstrip()

布尔值 bool

在Python中,可以直接用True、False表示布尔值
常与if-else , while一起使用

列表 list

list是一种有序的集合,可以随时添加和删除其中的元素

# 创建一个列表
fruit = ['apple','orange','banana']
----------------------------------------
# 获取列表长度
>>> len(fruit)
3
----------------------------------------
# 通过索引访问列表元素
>>> fruit[0]
apple
>>> fruit[-1]
banana
----------------------------------------
# append:往list中追加元素到末尾
>>> fruit.append('lemon')
>>> fruit
['apple','orange','banana','lemon']
----------------------------------------
# extend:将一个可迭代对象的所有元素,添加到列表末尾
li = []
li.extend('hogwarts')  # 添加的是字符串的所有字母
li.extend([1, 2, 3])  # 接收列表的所有元素
li.extend((4, 5, 6))  # 接收元组的所有元素
li.extend({'a': 1, 'b': 2})  # 接收字典的所有key值
print(li)
----------------------------------------
# insert:将一个对象插入到指定的索引位置
# 在索引0的位置插入元素
li = [0, 1, 2]
li.insert(0, 'hogwarts')
print("插入后: ", li)  # 打印 ['hogwarts', 0, 1, 2]
----------------------------------------
# pop:删除list末尾的元素,可传参数index
>>> fruit.pop()
lemon
>>> fruit
['apple','orange','banana']
----------------------------------------
# remove:移除列表中第一个等于 item 的元素
# 移除第一个2
li = [1, 2, 3, 2, 1]
li.remove(2)
print(li)  # 打印 [1, 3, 2, 1]
----------------------------------------
# sort:对列表进行原地排序
nums = [2, 4, 3, 1, 5]

# 1、不传参数,默认升序,数字从小到大排列
nums.sort()
print(nums)  # 打印 [1, 2, 3, 4, 5]

# 2、指定key=len,按元素的长度排序
words = ['Python', 'Java', 'R', 'Go']
words.sort(key=len)
print(words)  # 打印 ['R', 'Go', 'Java', 'Python']

# 3、指定reverse=True,降序
nums = [2, 4, 3, 1, 5]
nums.sort(reverse=True)
print(nums)  # 打印 [5, 4, 3, 2, 1]
----------------------------------------
# reverse:将列表中的元素顺序反转
nums = [8, 1, 5, 2, 77]
nums.reverse()
print(nums)  # 打印[77, 2, 5, 1, 8]
----------------------------------------
# 列表推导式
# 语法:[x for x in li if x ...]
result = [ele ** 2 for ele in range(1, 11) if ele % 2 == 0]
print(result)  # 打印 [4, 16, 36, 64, 100]
----------------------------------------
# 1、重复
li = [1] * 5
print(li)  # 打印[1, 1, 1, 1, 1]

# 2、合并
li1 = [1, 2, 3]
li2 = [99, 100]
print(li1 + li2)  # 打印[1, 2, 3, 99, 100]

元祖 tuple

tuple和list非常类似,但是tuple一旦初始化就不能修改

# 创建一个元祖
fruit = ('apple','orange','banana')

# index:返回与目标元素相匹配的首个元素的索引
t = (1, 3, 2, 3, 2)
print(t.index(3))
t = ('h', 'o', 'g', 'w', 'a', 'r', 't', 's', 'a')
print(t.index('a'))

# count:返回某个元素出现的次数
t = (1, 2, 2, 3, 3, 3, 3)
print(t.count(3))

# 元组解包:把一个可迭代对象里的元素,赋值到由对应的变量组成的元组中
a, b, c = (1, 2, 3)
print(a, b, c)

字典 dict

dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度

# 创建一个字典
d = {'Bob':1,'Lisa':2}

# 将数据添加到字典
>>> d['Mary'] = 3

# 获取字典数据
>>> d['Bob'] # 若value不存在,则抛出KeyError
>>> d.get('Bob') # 若value不存在,则返回 None

# 通过key删除数据
>>> d.pop('Mary')
----------------------------------------
# 获取所有的key
dc = {"name": "Harry Potter", "age": 18}
keys = dc.keys()
print(type(keys), keys)
# 将视图对象转成列表
print(list(keys))
----------------------------------------
# 获取所有的value
dc = {"name": "Harry Potter", "age": 18}
values = dc.values()
print(type(values), values)
# 将视图对象转成列表
print(list(values))
----------------------------------------
# 获取所有key和value
dc = {"name": "Harry Potter", "age": 18}
items = dc.items()
print(type(items), items)
# 将视图对象转成列表
print(list(items))
----------------------------------------
# update:使用来自 dict 的键/值对更新字典,覆盖原有
dc = {"name": "Harry Potter", "age": 18}
dc.update({"age": 20, "hobby": "magic"})
print(dc)
# 打印结果{'name': 'Harry Potter', 'age': 20, 'hobby': 'magic'}
----------------------------------------
# 字典推导式
#将key和value分别进行交换。也就是key变成值,值变成key。
dict_01 = {'a': 1, 'b': 2, 'c': 3}
dict_02 = {v: k for k, v in dict_01.items()}
print(dict_02)
----------------------------------------

集合 set

set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key
通常用于去重

# 新建一个集合
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}

# add:将单个对象添加到集合中
st = {1, 2, 3}
st.add(99)

# update:批量添加来自可迭代对象中的所有元素
li = [1, 2, 3]
st1 = set()
st1.update(li)

# remove:从集合中移除指定元素
# discard:从集合中移除指定对象
st = {1, 2, 3, 4, 5}
st.remove(1024)  # 删除不存在的元素会抛出KeyError
st.discard(1024) # 删除不存在的元素不报错

# pop:随机从集合中移除并返回一个元素
st = {1, 2, 3, 4, 5}
item = st.pop()

# clear:清空集合,移除所有元素
st = {1, 2, 3, 4, 5}
st.clear()

# intersection:集合运算:交集
set1 = {1, 3, 2}
set2 = {2, 4, 3}
print(set1.intersection(set2))
print(set1 & set2)

# union:集合运算:并集
set1 = {1, 3, 2}
set2 = {2, 4, 3}
print(set1.union(set2))
print(set1 | set2)

# difference:集合运算:差集
set1 = {1, 3, 2}
set2 = {2, 4, 3}
print(set1.difference(set2))
print(set1 - set2)

3. 条件判断

通过if进行条件判断,若if语句判断为True,则执行if中的内容
if添加一个else语句,意思是,如果if判断是False,不要执行if的内容,去把else执行

  • if
if True:
    print('进入循环')
  • if-else
age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')
  • if-elif-else
age = 3
if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
else:
    print('kid')
  • 三目运算符
# 正常的赋值操作和判断语句结合
if a>b:
    h = "变量1" 
else:
    h = "变量2"
	
# 优化之后更简洁的写法
h = "变量1" if a>b else "变量2"

4. 循环

4.1 for循环

通过for…in循环,依次把list或tuple中的每个元素迭代出来

# 依次打印列表中的人名
names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)
    
# 依次打印整数0-4
for number in range(5):
    print(number)
    
# 依次打印字段的键值对
d = {'Bob':1,'Lisa':2,'Mary':3}
for k,v in d.items():
    print(k)
    print(v)

4.2 while循环

只要条件满足,就不断循环,条件不满足时退出循环

# 打印 0-9
n = 0
while n < 10:
    print(n)
    n += 1
  • break 退出循环
# 当n=3时,退出循环
n = 0
while n<10:
    print(n)
    n += 1
    if n ==3:
        break
  • continue 跳过当前循环,进入下次循环
# 打印10以内的奇数
n = 0
while n<10:
    n += 1
    if n%2 == 0:
        continue
    print(n)

5. 异常处理

捕获异常

捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。

# 语法
try: # 先执行try中语句
    <语句>
except: # 若try中语句发生异常,则执行except中语句
    <语句>
else: # 若try中语句执行成功,则执行else中语句
    <语句>
finally: # 无论try中语句是否成功,最后执行finally中语句
    <语句>

自定义异常

class MyError(Exception):
	def __init__(self, value):
		self.value = value
	def __str__(self):
		return repr(self.value)

6. 封装与继承

封装

提供数据访问功能(getter)

  • 计算属性
  • 语法:使用@property装饰器
  • 调用:实例.方法名
class Account:
    # 普通属性
    bank = "BOC"
    # 内部属性
    _username = "Hogwarts"
    # 私有属性
    __password = "888"

    @property
    def password(self):
        return self.__password
		
# 实例化对象
obj = Account()
# 访问实例的私有属性
print(obj.password)  # 将会打印 888

提供数据操作功能(setter)

  • 语法:使用@计算属性名.setter装饰器
  • 调用:实例.方法名
class Account:
    # 普通属性
    bank = "BOC"
    # 内部属性
    _username = "Hogwarts"
    # 私有属性
    __password = "888"

    @property
    def password(self):
        return self.__password

    @password.setter
    def password(self, value):
        # 增加数据的校验
        if len(value) >= 8:
            self.__password = value
        else:
            print("密码长度最少要有8位!")

# 实例化对象
obj = Account()

# 修改私有属性(满足校验条件)
obj.password = "hogwarts666"  # 修改成功
print(obj.password)  # 将会打印 hogwarts666

# 修改私有属性(不满足校验条件)
obj.password = "123"  # 修改不会生效
print(obj.password)  # 将会打印 888

类型检查

isinstance(实例,类名)

  • 检查对象是否是某个类及其派生类的实例

issubclass(类名1,类名2)

  • 检查类名1是否为类名2的子类

7.数据类 dataclass

使用@dataclass定义数据类

@dataclass
class Cat:
	name : str
	weight : int
	color : str

field的使用

  • 数据类中,可使用field为变量指定默认值
  • 可变类型必须使用field
  • default和default_factory不能同时存在
@dataclass
class Cat:
	name : str
	# 通过default指定默认值
	weight : int = field(default=2)
	# 通过default_factory指定空列表
	children : list = field(default_factory=list)
	# init=False 实例化对象时,不需要传入该参数,但需要一个默认值
	color : str = field(default='橘色',init=False)

asdict()

asdict(数据类实例):将数据类实例转换为字典


8. 装饰器

闭包函数

  • 闭包的内部函数中,对外部作用域的变量进行引用
  • 闭包无法修改外部函数的局部变量
  • 闭包可以保存当前的运行环境
# 定义闭包函数
def student_grade(grade):
	def output_student(name,age):
		print(f'姓名:{name} 年龄:{age} 年级:{grade}')
		return output_student

# 定义学生年级,此时student对象是output_student函数
student = student_grade(1)
# 传入姓名和年龄,此时调用output_student()函数
student('哈利','12')

装饰器

不带参数的函数装饰器

  • 不使用装饰器
# 定义打印函数
def hogwarts():
    print('霍格沃兹')

# 定义开始和结束的打印,并将打印函数传入
def zsq(fun):
    print('开始')
    fun()
    print('结束')

# 函数调用
zsq(hogwarts)
  • 使用装饰器
# 装饰器作用:计算函数运行时间
def timer(func):
	# 如果被装饰函数有参数,需要在内函数加形参
	# 因为无法确定参数数量,所以传入不定长参数
	def inner(*args, **kwargs):
		start_time = datetime.datetime.now()
		func(*args, **kwargs) # 此处传入参数
		end_time = datetime.datetime.now()
		print(f"执行时长:{end_time - start_time}")
	# 返回内函数
	return inner

带参数的函数装饰器

def say_nation(country):
    def wrapper(func):
        def deco(*args, **kwargs):
            if country == '中国':
                print('我来自中国')
            else:
                print(f'我来自{country}')
            return func(*args, **kwargs)
        return deco
    return wrapper

不带参数的类装饰器

  • init 接收函数
class logger:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print(f"类装饰器{self.func.__name__}开始执行...")
        return self.func(*args, **kwargs)

带参数的类装饰器

  • init 接收参数
  • call 接收函数
class logger:
    def __init__(self, param):
        self.param = param

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print(f"类装饰器{func.__name__}开始执行...")
            print(f'参数为:{self.param}')
            return func(*args, **kwargs)
        return wrapper


@logger('王瑾琪')
def martin(msg):
    print('我是martin')
    print(f'say {msg}')
    return '完成'

9. 内置库

OS库

OS目录相关

  • os.getcwd():获取当前目录
  • os.chdir():切换目录
  • os.listdir():列出当前目录内容
  • os.mkdir():创建空目录
  • os.makedirs():递归创建多级目录
  • os.rmdir():删除空目录
  • os.rename():重命名目录
  • os.remove():删除文件

OS路径相关

  • os.path.abspath(path) 返回绝对路径
  • os.path.basename(path) 返回文件名
  • os.path.dirname(path) 返回文件路径
  • os.path.split(path) 分割路径
  • os.path.join(path) 拼接路径
  • os.path.exists(path) 判断路径是否存在
  • os.path.isdir(path) 判断是否是目录
  • os.path.isfile(path) 判断是否是文件
  • os.path.getsize(path) 获取文件大小

文件操作

读写模式

  • r:以只读模式打开文件,并将文件指针指向文件头;如果文件不存在会报错
  • w:以只写模式打开文件,并将文件指针指向文件头;如果文件存在则将其清空,如果文件不存在则创建
  • a:以只追加可写模式打开文件,并将文件指针指向文件尾部;如果文件不存在则创建

读操作

  • read():一次读取文件所有内容,返回一个str
  • read(size):每次最多读取指定长度的内容,返回一个str;size指定字符长度
  • readlines():一次读取文件所有内容,按行返回一个list
  • readline():每次只读取一行内容

日期与时间模块

获取当前日期

datetime.datetime.now()

字符串与时间互转

s="2021-09-27 06:47:06"
# 将字符串 转换为datetime实例
s1=datetime.datetime.strptime(s,'%Y-%m-%d %H:%M:%S')

# 时间转成字符串
now = datetime.datetime.now()
result = now.strftime('%a, %b %d %H:%M')

参考链接:https://docs.python.org/3/library/datetime.html?highlight=strftime

时间戳与时间互转

import datetime
mtimestamp = 1632725226.129461
# 将时间戳转成时间 
s = datetime.datetime.fromtimestamp(mtimestamp)
# 将时间转成时间戳
print(s.timestamp())

json库

python对象与JSON字符串互相转换

  • dumps():将 Python 对象编码成 JSON 字符串
    • indent:根据数据格式缩进显示,默认为 None,没有缩进
    • ensure_ascii:对中文使用 ASCII 编码,默认为 True
  • loads():解码 JSON 数据,该函数返回 Python 对象

JSON文件读取与写入

  • dump(): Python 对象编码,并将数据写入 json 文件中
  • load():从 json 文件中读取数据并解码为 Python 对象
import json

# 定义 python 结构
data = [{'a': 1, 'b': '2', 'c': True, 'd': False, 'e': None }]   

# 将 python 对象编码为 JSON 字符串
json_data = json.dumps(data)
# 将 JSON 字符串解码为 python 对象
python_data = json.loads(json_data)
# 写入 JSON 数据,在代码当前目录生成一个 data.json 的文件
with open('data.json', 'w') as f:    
     json.dump(data, f)   
# 读取数据,读取 json 文件并解码成 python 对象
with open('data.json', 'r') as f:
     data = json.load(f)

正则表达式 re库

正则表达式对象转换

  • compile():将字符串转换为正则表达式对象
    适用于需要多次使用这个正则表达式的场景
import re
'''
prog:正则对象,可以直接调用匹配、替换、分割的方法,不需要再传入正则表达式
pattern:正则表达式
'''
# 构造正则对象
prog = re.compile(pattern)
# 直接通过正则对象调用方法
prog.match(str,flag)

匹配字符串

pattern: 正则表达式
string: 要匹配的字符串
flags: 可选,控制匹配方式
- A:只进行 ASCII 匹配
- I:不区分大小写
- M:将 ^ 和 $ 用于包括整个字符串的开始和结尾的每一行
- S:使用 (.) 字符匹配所有字符(包括换行符)
- X:忽略模式字符串中未转义的空格和注释

  • match():从字符串的开始处进行匹配

    # 例:匹配hogwarts
    pattern = r"hogwarts"
    # 定义字符串
    s1 = "hogwarts is good"
    s2 = "hello hogwarts"
    # 使用match匹配
    match1 = re.match(pattern,s1,re.I) 
    match2 = re.match(pattern,s2,re.I) 
    # match1 返回匹配结果
    # match2 返回None
    
  • search():在整个字符串中搜索第一个匹配的值

    # 例:匹配hogwarts
    pattern = r"hogwarts"
    # 定义字符串
    s1 = "hello hogwarts"
    s2 = "hello hogwarts hogwarts"
    # 使用search匹配
    match1 = re.search(pattern,s1,re.I) 
    match2 = re.search(pattern,s2,re.I) 
    # match1 返回匹配结果
    # match2 返回返回第一个匹配结果
    
  • findall():在整个字符串中搜索所有符合正则表达式的字符串,返回列表

    # 例:匹配hogwarts
    pattern = r"hogwarts"
    # 定义字符串
    s1 = "hello hogwarts hogwarts"
    # 使用findall匹配
    match_list = re.findall(pattern,s1,re.I) 
    # match1 返回匹配结果,数据类型为list
    

获取match和search的匹配结果

  • 匹配值的起始位置:result.start()
  • 匹配值的结束位置:result.end()
  • 匹配位置的元祖:result.span()
    结果为:(start,end)
  • 要匹配的字符串:result.string
  • 匹配到的数据:result.group()

替换字符串

  • sub():实现字符串替换
    import re
    
    '''
    pattern:正则表达式
    repl:要替换的字符串
    string:要被查找替换的原始字符串
    count:可选,表示替换的最大次数,默认值为 0,表示替换所有匹配
    flags:可选,控制匹配方式
    '''
    # 语法
    re.sub(pattern, repl, string, [count], [flags])
    

分割字符串

  • split():根据正则表达式分割字符串,返回列表
    import re
    
    '''
    pattern:正则表达式
    string:要匹配的字符串
    maxsplit:可选,表示最大拆分次数
    flags:可选,控制匹配方式
    '''
    # 语法
    re.split(pattern, string, [maxsplit], [flags])
    
    # 分割url中的参数和地址
    p = r"[?|&]"
    url = "https://www.baidu.com/s?wd=1111&name=2222"
    # 结果返回一个list
    result = re.split(p,url)
    # 打印结果为
    # ['https://www.baidu.com/s','wd=1111','name=2222']
    

7. 参考文档

python官方文档
菜鸟教程-python
知乎-python基础语法总结