python 语法笔记
常用字符串操作
# 去除空格
"test string ".strip()
# 去除字符串前导、后缀的指定字符
"----test string----".strip("-")
# 子字符串出现次数
"----test string----".count("-")
# 子字符串首次出现的位置,返回结果为 Base 0,未找到返回 -1
"test string".find("s")
# 字符串替换
"----test string----".replace("-", "*")
列表
# 创建空白列表
myList = []
# 获取列表长度
iLen = len(myList)
# 获取指定数据在列表中出现的次数,如果列表中不存在,将抛出错误
iCount = myList.count('Apple')
# 查询指定项是否存在于列表中
if 'Apple' in myList:
...
# 向列表追加项
myList.append('Banana')
# 合并两个列表
myList.extend(myList2) # 合并到 myList 中,不可将返回结果赋值给其他变量,a = myList.extend(myList2) 是错误的
a = myList1 + myList2 # 这种合并方式可以将结果赋值给其他变量
# 移除第一个匹配的列表项,如果没有匹配项,将抛出错误
myList.remove('Apple')
# 反转列表
myList.reverse() # 对原列表生效
# 列表排序
myList.sort() # 对原列表生效
# 列表相等的判定
if listA == listB: # 两列表必须元素及其顺序完全一样才算相等
字典
# 创建空白字典
myDict = {}
# 创建并初始化字典
myDict = {'LiaoNing':'ShenYang', 'JiLin':'ChangChun', 'HeiLongJiang':'HaErBin'}
# 向字典添加键对
myDict['HeBei'] = 'ShiJiaZhuang'
# 删除键对,并返回键所对应的值。如果键不存在,将抛出错误。
lastCity = myDict.pop('HeBei')
# 查找字典中是否存在指定的键
if myDict.has_key('HeBei'): # python2 语法,python3 已移除
if 'HeBei' in myDict:
# 读取指定键对应的值,如果不存在,则返回指定的 defalut 值(python3 语法)
a = myDict.get(aKey, defalut=None)
# 返回字典中所有键的列表:
myDict.keys()
# 返回字典中所有值的列表:
myDict.values()
# 两个字典是否相等的判断(只要两个字典的键及相对应的值相等即可,与项的保存顺序无关)
if myDict1 === myDict2:
函数
参见函数的参数
# 参数的默认值
# 默认值参数必须指向不可变对象,下面用法是错误的
def add_end(L=[]):
# 解决方法
def add_end(L=None):
# 可变数量参数,常写成 *args,用其他变量名也是可以的
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
# 调用方式
sum = calc(1, 3, 5, 7, 9)
# 将 list 或者 tuple 元素传入可变数量参数,在 list 或者 tuple 名称前面加 * 即可
sum = calc(*aList)
# 可变数量关键字参数,常写成 **kwargs(keyword arguments),用其他变量名也可以
def person(name, age, **kw):
if 'city' in kw: # 如果有city参数
pass
if 'job' in kw: # 如果有job参数
pass
print('name:', name, 'age:', age, 'other:', kw)
# 调用方式
person('Adam', 45, gender='M', job='Engineer')
# 将字典传入可变数量关键字参数
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
# 主函数
if __name__ == "__main__":
main()
类
# 定义类
# 在定义时指定基类,如无基类,建议将基类指定为 object
class MyClass(object):
a = 5
# 类方法的第一个参数必须是 self,用以引用类的所有成员变量和方法。调用方法时不必为 self 指定实参
def print_a(self):
# 使用 self 引用成员变量或方法
print(self.a)
# 构造函数,在创建实例时自动运行
def __init__(self, name="None", grade="K"):
self.name = name
self.grade = grade
# 判断实例对象是否相等的函数,当遇到 实例1 == 实例2 时自动调用
def __eq__(self, other):
# 以一个成员变量为依据判断两个实例是否相等,当然也可以依据多个成员变量来判断
return self.num != other.num
# 判断实例对象是否不相等的函数,当遇到 实例1 != 实例2 时自动调用
def __ne__(self, other):
# 以一个成员变量为依据判断两个实例是否相等,当然也可以依据多个成员变量来判断
return self.num == other.num
# 返回实例提示信息的函数,当遇到 print(实例名)时自动调用
def __str__(self):
'''
docstring
在 python shell 中使用 help(类名) 时,会自动提取 docstring 到帮助文档中
'''
# 返回一个字符串供打印
return f"The name is {self.name}, grade is {self.grade}"
# 实例化类
myVar = MyClass()
导入外部包
# 导入当前目录下 books.py ,引入其中代码时需显式使用 books 前导
import books
aBook = books.Book()
# 导入当前目录下 books.py 文件中的 Book 类
from books import Book
# 导入 classes 目录下的 books.py 文件中的 Book 类
from classes.books import Book
专门存放库文件的文件夹称为包
,包文件夹下一般要有一个 __init__.py
文件,它可以是空文件。在导入此包中的库文件时, __init__.py
中的代码首先被执行。
random包
## random 包
import random
random.randint(1, 10) # 生成随机整数,包括两侧端点 1 和 10
random.random() # 生成 0-1 之间的浮点数,不包括 0 和 1
random.uniform(1, 10) # 生成 1-10 之间的随机浮点数,不包括 1 和 10
random.choice(myList) # 返回列表或元组中的一个随机项
# 在 python shell 中,import 一个包后,可使用 help(包名) 查看帮助信息
help(random)
datetime 包
import datetime
aTime = datetime.time(11, 30, 5) # 初始化一个时间对象
aTime.hour # 返回小时数
aTime.minute # 返回分钟数
aTime.second # 返回秒数
aDate = datetime.date(year=2024, month=5, day=31) # 使用命名参数初始化一个日期对象,以防参数位置错误
aDateTime = datetime.datetime(2024, 5, 5, 12, 30, 0) # 初始化一个日期时间对象
now = datetime.datetime.now() # 返回当前时间
# 格式化输出,strftime 函数不支持中文,可使用以下代码格式化日期时间
str = f"{now.year}年{now.month}月{now.day}日"
文件读写
使用 open
打开一个文件,格式为 open(文件名, 文件操作符)
,文件操作符格式为 (r|w|a)[b][+]
,含义如下:
- r 以只读方式打开文件,文件的指针将会放在文件的开头(默认模式,如果省略操作符,则以 r 模式打开文件)。
- w 以只写方式打开文件,如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
- a 以追加方式打开文件,如果该文件已存在,文件指针将指向文件的结尾,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
- b 二进制模式
- + 打开一个文件进行更新(可读可写),(r+ == w+ == r+w ??)
f = open('c:\\text\\a.txt')
# 读取所有行到列表中
lineList = f.readlines()
# 每次读取一行
f.seek(0) # 重置指针到文件头
while True:
line = f.read()
if not line:
break
print(line)
# 向文件中写入一行
f.write("a line")
# 向文件中一次写入多行
f.writelines(linesList)
# 关闭文件
f.close
# 为防止文件打开异常,更安全方便的方式,不必显式调用 close
with open('/path/to/file', 'r') as f:
print(f.read())
文件与路径操作
import os, sys
# 取得当前工作路径
path = os.getcwd()
# 取得当前脚本路径
sys.path[0]
# 取得指定路径下的文件列表,指定文件夹中的文件及子目录都将取到列表中,只包含文件名,不是全路径。
# 此函数不搜索子文件夹,只搜索本级文件夹。
fileList = os.listdir('/path/to/file')
# 切换当前工作目录
os.chdir('c:\\python34\\lib')
# 在当前文件夹下创建 new 文件夹
os.makedir('new')
# 逐级创建文件夹(给定路径中不存在的文件夹将逐级创建)
os.makedirs('c:\\killme\\test\\2')
# 取得文件信息
stat = os.stat('README.txt')
size = stat.st_size # 文件字节数
# 最后访问时间,stat.st_atime 为时间戳格式,转换为日期格式
aTime = datetime.datetime.fromtimestamp(stat.st_atime)
# 路径组合
path = os.path.join('usr', 'bin', 'spam') # 'usr\\bin\\spam'
# 转换为绝对路径
path = os.path.abspath(相对路径)
# 转换为相对路径
path = os.path.relpath(绝对路径, 起始目录)
# 判断是否为绝对路径
os.path.isabs(路径名)
# 从文件全路径中分解取得路径名与文件名
fullpath = 'c:\\windows\\system32\\calc.exe'
path = os.path.dirname(fullpath)
filename = os.path.basename(fullpath)
# os.path.split() 函数可以从全路径中同时得到路径与文件名
path, filename = os.path.split(fullpath)
# 路径分隔符常量
os.path.sep # '\\'
# 取得文件大小(如果传入文件夹,则返回0;如果文件不存在,将引发异常)
os.path.getsize(file)
# 文件或文件夹是否存在
os.path.exists(path)
# 如果目标存在,并且是一个文件
os.path.isfile(path)
# 如果目标存在,并且是一个文件夹
os.path.isdir(path)
遍历文件夹
for currentFolder, subFoldersList, filesList in os.walk(path):
print(currentFolder, subFoldersList, filesList)
对于下面的目录结构,
C:\1
│ b.txt
│ c.txt
├─11
│ │ a.txt
│ ├─111
│ │ d.doc
│ └─112
│ e.doc
└─12
test.py
打印的结果如下:
c:\1 ['11', '12'] ['b.txt', 'c.txt']
c:\1\11 ['111', '112'] ['a.txt']
c:\1\11\111 [] ['d.doc']
c:\1\11\112 [] ['e.doc']
c:\1\12 [] ['test.py']
JSON 操作
JSON
对象的基本格式为 {"key": value}
,键必须为字符串,值可以是数字、字符串、布尔值、列表或其他JSON对象,但每个 JSON 文件中只能存在一个 JSON 对象,也就是说,JSON对象可以嵌套,但不可以并列。
几种特殊值的说明:
- 字符串 必须用双引号包围
- 布尔值 true或false,没有引号,没有大写
- 列表 ["thing", "thing"]
- 空值 null,没有引号,没有大写
import json
# 打开一个 JSON 文件
f = open('car.json')
# 从文件指针载入 JSON,返回的 car 为 python 的字典类型
car = json.load(f)
# 引用 JSON 属性与引用 python 的 dict 类型一致
car['mycar']['color'] = 'red'
# 将 JSON 对象保存到文件
f = open('car.json', 'w')
# JSON 对象写入文件指针,格式为单行文本
json.dump(car, f)
# JSON 对象写入文件指针,缩进格式化
json.dump(car, f, indent=2)
# 将 JSON 对象保存到字符串中,注意,比 dump 多了一个字母 “s”
str_json = json.dumps(car, indent=2)
# 类实例(类的所有属性必须全部是基本数据类型)可以通过 vars 函数转换为字典,并写入 JSON 文件。
f = open('newcar.json', 'w')
mycar = Car()
json.dump(vars(mycar), f, indent=2)
# 如果类的属性包括其他对象,需要自己写一个函数来导出
class Classroom():
self.room_number = 5
self.students = []
def get_json_dict(self):
d = vars(self)
student_list = []
for student in self.students
student_list.append(vars(student))
d['students'] = student_list
return d
json.dump(first_grade.get_json_dict, f, indent=2)
sqlite 操作
sqlite 的 SQL 语句中可指定的数据类型:Null
,Integer
,Real
,Text
,Blob
。
import sqlite3
conn = sqlite3.connect('mytest.db')
cursor = conn.cursor()
# 建立表
sql = '''create table students (
name text,
username text,
id int)'''
cursor.execute(sql)
# 插入数据
while True:
name = input("Student\'s name:")
username = input("Student\'s username:")
id_num = input("Student\'s id number:")
if (not name) or (not username) or (not id):
break
sql = '''insert into students (name, username, id)
values (:st_name, :st_username, :id)'''
cursor.execute(sql, {'st_name':name, 'st_username':username, 'id':id_num})
# 另一种参数化查询的语法,可以避免 SQL 注入攻击
cursor.execute("INSERT INTO students (name, username, id) VALUES (?, ?, ?)", ("Bob White", "Bob", 5))
conn.commit()
# 查询数据
sql = 'select * from students'
results = cursor.execute(sql)
# 取得首条结果
a_students = results.fetchone()
# 取得全部结果
all_students = results.fetchall()
# all_students 返回的数据集以元表列表的形式呈现,形如
# [('Hannah', 'hn', 1), ('Jackey', 'jk', 2)]
for stu in all_students:
print(stu[1])
# 修改数据
sql = 'update students set username = "zhh" where id = 1'
# 确保修改起作用,最安全的方法是使用一个新的游标
cursor2 = conn.cursor()
cursor2.execute(sql)
# 执行 update 或 delete 语句后一定要提交修改才能保存
conn.commit()
# 游标用完后要关闭
cursor.close()
conn.close() # 确保关闭连接
# 处理异常
try:
cursor.execute(SQL)
conn.commit()
except sqlite3.DatabaseError as e:
print(f"Database error: {e}")
conn.rollback()
finally:
conn.close() # 确保关闭连接
# 事务控制
try:
# 开始事务
conn.isolation_level = None # 设置事务隔离级别
cursor.execute("BEGIN") # 开始事务
# 执行多个操作
cursor.execute("INSERT INTO users (name, email) VALUES ('Eva', 'eva@example.com')")
cursor.execute("INSERT INTO users (name, email) VALUES ('Frank', 'frank@example.com')")
# 提交事务
conn.commit()
except sqlite3.DatabaseError as e:
print(f"Database error: {e}")
conn.rollback()
finally:
# 关闭连接
conn.close()
# 分页查询
# 在处理大量数据时,分页查询可以提高效率,减少内存占用。
import sqlite3
# 连接到数据库
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# 查询第一页数据
page_size = 10
page_number = 1
offset = (page_number - 1) * page_size
cursor.execute(f"SELECT * FROM users LIMIT {page_size} OFFSET {offset}")
results = cursor.fetchall()
print(results)
# 查询第二页数据
page_number = 2
offset = (page_number - 1) * page_size
cursor.execute(f"SELECT * FROM users LIMIT {page_size} OFFSET {offset}")
results = cursor.fetchall()
print(results)
# 关闭连接
conn.close()
# LIMIT 和 OFFSET 是 SQL 中用于分页查询的关键字。
# LIMIT 设置每页的记录数。
# OFFSET 设置跳过的记录数。
# page_number 和 page_size 控制分页逻辑。