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 语句中可指定的数据类型:NullIntegerRealTextBlob

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 控制分页逻辑。
posted @ 2024-01-16 06:16  汉学  阅读(27)  评论(0)    收藏  举报