python基础

基本语法

注释

单行:#

多行:'''"""

1
2
3
4
# 如果一段代码太长,可用\分段
a = b + c + \
d + e + \
f

变量类型

查看类型

type()查看变量类型

isinstance(a, (类型1, ...))判断是否是其中一种类型或子类

数字

  • int
  • bool(True/False)
  • float
  • complex(复数)

/返回浮点数,//返回整数的部分

字符串

单行字符串可用''"",多行字符串可用''' '''""" """

转义符号\

不让\生效,在引号前加r

可用+连接字符串,*重复字符串

字符串是不可改变量

切片

左闭右开

-1为末尾位置

还可加上步长,步长-1表示逆向

格式化

1
2
3
4
5
6
7
8
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))

# 还有前面加f的格式化语法
name = 'aaa'
print(f'Hello {name}') # Hello aaa

w = {'name': 'baidu', 'url': 'www.baidu.com'}
print(f'{w["name"]}: {w["url"]}') # baidu: www.baidu.com

列表

列表的元素是可改变的

1
2
3
4
5
6
a = [1, 2, 3, 4, 5, 6]
print(a[1 : 2]) # [2]
print(a[1 :]) # [2, 3, 4, 5, 6]

a[1] = 0
print(a) #[1, 0, 3, 4, 5, 6]

列表操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 增加元素
list1 = [1, 2, 3]
list1.append(4)
print(list1) # [1, 2, 3, 4]

# 删除元素
del list1[0]
print(list1) # [2, 3, 4]

# 比较列表
import operator

list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(operator.eq(list1, list2)) # False

元组

元组的元素不可以改变

可以把字符串看成特殊的元组

1
2
3
4
5
tup = (1, ) # 只包含一个元素的元组
a = (1) # int类型
b = () # 空元组
print(type(tup)) # <class 'tuple'>
print(type(a)) # <class 'int'>

集合

集合的元素可变,唯一

创建可用{}set(),空集合要用set

1
2
3
4
5
6
7
8
9
10
11
12
a = set('abracadabra')
b = set('alacazam')

print(a)

print(a - b) # a 和 b 的差集

print(a | b) # a 和 b 的并集

print(a & b) # a 和 b 的交集

print(a ^ b) # a 和 b 中不同时存在的元素

字典

创建可用{}dict,空字典可用{}创建

key必须为不可变类型

1
2
3
4
a = {'a': 1, 'b': 2, 'c': 3, 4 : 'd'}
print(a) # {'a': 1, 'b': 2, 'c': 3, 4: 'd'}
print(a['a']) # 1
print(a[4]) # d

字典操作

1
2
3
4
5
6
7
8
# 删除指定key
d = {1 : 1, 2 : 2, 3 : 3}
del d[1]
print(d) # {2: 2, 3: 3}

# 清空字典
d.clear()
print(d) # {}

输入输出

1
2
3
4
5
6
# 输入
price = input("Enter price: ")

# print默认带换行
print(price)
print(price, end = '')

format格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 按位置填充
print("Hello, {}!".format("Alice"))
print("Hello, {0}, you are {1} years old.".format("Bob", 25))

# 按关键字填充
print("Site name: {name}, Rank: {rank}".format(name="Google", rank=1))

# 混合字典访问
user = {"name": "Alice", "age": 18}
print("Name: {0[name]}, Age: {0[age]}".format(user))

# 解包
data = {"site": "Google", "rank": 1}
print("Site: {site}, Rank: {rank}".format(**data))

格式化控制符

格式符 含义 示例值 示例结果
d 十进制整数 {0:d} 42
f 浮点数(默认 6 位) {0:f} 3.141593
.2f 保留 2 位小数 {0:.2f} 3.14
>10 右对齐,占 10 宽度 {0:>10} text
<10 左对齐,占 10 宽度 {0:<10} text
^10 居中,占 10 宽度 {0:^10} text
, 千位分隔符 {0:,} 1,000,000
% 百分比(乘以 100) {0:.2%} 25.00%

条件/循环

  • if / elif / else

  • match…case(相当于switch…case,在3.10版本可用)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    status = 400
    match status:
    case 400 | 401 | 402:
    return "Bad request"
    case 404:
    return "Not found"
    case 418:
    return "I'm a teapot"
    case _:
    return "Something's wrong with the internet"
  • while…else

  • for…in…else

    range(5): 遍历从0到4

  • pass: 空语句,不做任何事

导入模块

导入模块的搜索路径:

  1. 当前目录
  2. 环境变量 PYTHONPATH 指定的目录
  3. Python 标准库目录
  4. .pth 文件中指定的目录
1
2
3
4
5
6
7
8
# 整个模块
import sys

# 模块中的某个函数
from sys import argv, path

# 模块中的所有函数(不推荐,容易覆盖已经定义的函数)
from sys import *

每个模块都有一个__name__属性

  • 如果模块是被直接运行,__name__ 的值为 __main__
  • 如果模块是被导入的,__name__ 的值为模块名。

数学函数

  • abs(): 绝对值
  • ceil()/floor(): 向上/向下取整
  • round(): 四舍五入
  • cmp(): 比较两个数
  • max()/min(): 取最大/最小值
  • pow(): 开方
  • sqrt(): 平方根

错误异常

处理异常

1
2
3
4
5
6
7
8
9
10
11
# 完整语法
try:
# 可能抛出异常的代码
except ExceptionType1:
# 处理方式 1
except ExceptionType2 as e:
# 处理方式 2,可获取异常对象 e
else:
# 没有发生任何异常时执行
finally:
# 不管是否异常都会执行(清理资源用)

抛出异常

1
2
3
4
def sqrt(x):
if x < 0:
raise ValueError("不能对负数开平方")
return x ** 0.5

常见异常类型

异常名 说明
ValueError 参数类型/值不合法
ZeroDivisionError 除以 0
IndexError 索引超出范围
KeyError 字典中键不存在
FileNotFoundError 打开的文件不存在
TypeError 操作/函数类型不对
NameError 使用了未定义的变量

自定义异常

1
2
3
4
5
6
7
8
9
10
class MyError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message

try:
raise MyError("MyError")
except MyError as e:
print(e)

文件

打开文件

1
f = open(file, mode='r', encoding=None)

打开模式

模式 含义 文件不存在时行为 可读 可写 是否清空原文件
r 只读 ❌ 报错
w 只写 ✅ 创建新文件 ✅ 清空
a 追加写入 ✅ 创建新文件 ❌(在末尾写)
r+ 读写 ❌ 报错
w+ 写读(先清空) ✅ 创建新文件 ✅ 清空
a+ 读写(追加写入) ✅ 创建新文件 ❌(只追加)
rb/wb 二进制读写 适合图片、音频等 看上面 看上面 看上面

写入文件

使用with open() as f会自动关闭文件,不然要手动f.close()

1
2
3
4
5
6
7
8
# 覆盖写入
with open("test.txt", "w", encoding="utf-8") as f:
f.write("Hello, world!\n")
f.write("Second line.\n")

# 追加写入
with open("test.txt", "a", encoding="utf-8") as f:
f.write("Appended line.\n")

读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 一次读完全部内容(字符串)
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)

# 按行读取
with open("test.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line.strip())

# 读一行
f.readline()

迭代器

访问集合元素的一种方式

可以记住遍历的位置的对象,只能往前不会后退

使用

1
2
3
4
5
6
7
8
9
10
11
# 用next()访问
a = [1, 2, 3]
b = iter(a)
print(next(b)) # 1
print(next(b)) # 2
print(next(b)) # 3
print(next(b)) # 报错

# 用for循环访问
for i in iter(a):
print(i)

创建迭代器

实现__iter__()__next__()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyNum:
def __iter__(self):
self.num = 0
return self

def __next__(self):
tmp = self.num
if tmp < 20:
self.num += 1
return tmp
else:
raise StopIteration # 停止迭代
myclass = MyNum()
it = iter(myclass)
for i in it:
print(i)

生成器

使用了yield函数被称为生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 每次到yield时,函数会返回n,并且在这里暂停,在下次调用时从这里继续执行
def countdown(n):
while n > 0:
yield n
n -= 1

# 创建生成器对象
generator = countdown(5)

# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
print(next(generator)) # 输出: 3

# 使用 for 循环迭代生成器
for value in generator:
print(value) # 输出: 2 1

函数

不定长参数

1
2
3
4
5
6
7
# 一个*为元组
def method(var1, *var2):
print(var1, " ",var2)

method(1) # 1 ()
method(1, 2) # 1 (2,)
method(1, 2, 3) # 1 (2, 3)
1
2
3
4
5
6
7
8
9
10
11
12
# 一个**为字典
def method(var1, *var2, **var3):
print(var1)
print(var2)
print(var3)

method(1,2,3,4,5, a = 1, b = 2)
'''
1
(2, 3, 4, 5)
{'a': 1, 'b': 2}
'''

匿名函数

作用是为了简洁,性能上和普通函数没差

1
2
3
4
5
sum = lambda arg1, arg2: arg1 + arg2

# 调用sum函数
print("相加后的值为 : ", sum(10, 20)) # 相加后的值为 : 30
print("相加后的值为 : ", sum(20, 20)) # 相加后的值为 : 40

函数装饰器

函数装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数

用于不修改原函数的基础上动态地增加或修改函数的功能

类似java的注解+AOP

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def decorator_function(original_function):
def wrapper(*args, **kwargs):
# 这里是在调用原始函数前添加的新功能
before_call_code()

result = original_function(*args, **kwargs)

# 这里是在调用原始函数后添加的新功能
after_call_code()

return result
return wrapper

# 使用装饰器
@decorator_function
def target_function(arg1, arg2):
pass # 原始函数的实现

实例:函数执行时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time


def time_logger(func):
def wrapper(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print("参数: ", args)
print("执行时间: ", end_time - start_time)
return res
return wrapper


@time_logger
def say_hello(name):
print("Hello! ", name)
time.sleep(0.5)

say_hello("Alice")

实例:带参数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(n):
func(*args, **kwargs)
return wrapper
return decorator

@repeat(3)
def say_hello():
print("Hello World!")

say_hello()

类装饰器

类装饰器用于动态修改类行为

实例:实现类的单例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class SingletonDecorator:
"""类装饰器,使目标类变成单例模式"""
def __init__(self, cls):
self.cls = cls
self.instance = None

def __call__(self, *args, **kwargs):
"""拦截实例化过程,确保只创建一个实例"""
if self.instance is None:
self.instance = self.cls(*args, **kwargs)
return self.instance

@SingletonDecorator
class Database:
def __init__(self):
print("Database 初始化")

db1 = Database()
db2 = Database()
print(db1 is db2) # True,说明是同一个实例

面向对象

构造方法

__init()__,创建对象时自动调用

不写默认是个空的构造方法

1
2
3
4
5
6
7
8
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

p = Person("John", 22)
print(p.age)
print(p.name)

类方法

类方法用def定义,且第一个参数要为self

继承

子类继承父类的属性和方法

子类里可用super().来调用父类的方法

1
2
3
4
5
6
7
8
9
10
11
class Animal:
def speak(self):
print("动物在叫")

class Dog(Animal):
def bark(self):
print("汪汪汪")

d = Dog()
d.speak()
d.bark()

多继承时决定调用哪个类的方法,按从左到右的优先级

即先找自己,在从左到右找父类(如果父类也有父类,则会顺着它的父类找上去)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A:
def hello(self):
print("A")

class B(A):
def hello(self):
print("B")

class C(A):
def hello(self):
print("C")

class D(B, C):
pass

D().hello() # 输出 B

私有属性和方法

定义:在属性或方法前加__

私有属性和方法只能在本类中访问

python的私有并不是真的私有,只是改了其名字,变为_类型__属性名

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person:
def __init__(self, name, age):
self.__name = name # 私有属性
self.__age = age # 私有属性

def __say_secret(self): # 私有方法
print("这是一个秘密")

def show(self):
print(f"{self.__name}, {self.__age}")
self.__say_secret()

print(Person("Tom", 20).show())

魔法方法

魔法方法是 Python 自动调用的一些特殊方法

方法 作用
__init__(self, ...) 构造函数,创建对象时调用
__new__(cls, ...) 真正创建对象的方法,__init__ 前执行(用于元类)
__del__(self) 析构函数,删除对象时调用
__str__() print(obj) 时调用
__repr__() 解释器或 repr(obj) 时调用

运算符重载

方法 对应操作
__add__ + 加法
__sub__ - 减法
__mul__ * 乘法
__eq__ == 比较
__lt__ < 小于

多线程

Python的多线程是并发的,而非真正的并行

CPython使用全局解释器锁(GIL)来保证线程安全,即同一时刻只有一个线程可以执行Python字节码。即使有多核CPU,GIL也会阻止多线程的并行执行

通过threading模块来使用多线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import threading
import time

def say_hello():
for i in range(3):
print(f"线程 {threading.current_thread().name} 打招呼")
time.sleep(1)

# 创建两个线程
t1 = threading.Thread(target=say_hello, name='T1')
t2 = threading.Thread(target=say_hello, name='T2')

t1.start()
t2.start()

t1.join()
t2.join()

print("主线程结束")
功能 说明
Thread(target=...) 创建线程并指定要执行的函数
start() 启动线程
join() 阻塞,直到被调用线程终止
current_thread() 获取当前线程信息
Lock() 创建互斥锁,防止多线程同时修改共享数据
enumerate() 返回一个包含正在运行的线程的列表
active_count() 返回正在运行的线程数量

守护线程

主线程会等待普通线程结束后才结束,而不会等待守护线程

要在start()前设置t.daemon = True才为守护线程

适合做后台服务或辅助任务

线程同步

互斥锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import threading

count = 0
lock = threading.Lock()

def add():
global count
for _ in range(100000):
with lock:
count += 1 # 保证这段代码只有一个线程能执行

t1 = threading.Thread(target=add)
t2 = threading.Thread(target=add)
t1.start()
t2.start()
t1.join()
t2.join()

print("count:", count)

可重入锁

threading.RLock()

支持一个线程加多次锁,适合递归或多个函数都加锁时

信号量

1
2
3
4
5
6
7
8
9
import threading
import time

sem = threading.Semaphore(3) # 最多3个线程同时进入

def task():
with sem:
print(threading.current_thread().name, "进入")
time.sleep(2)

线程通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import threading
import time

event = threading.Event()

def worker():
print("等待事件触发...")
event.wait()
print("事件已触发,开始工作")

t = threading.Thread(target=worker)
t.start()

time.sleep(3)
print("触发事件!")
event.set()

JSON

通过dump()转换为json格式,load()读取json

1
2
3
4
5
6
7
8
9
10
11
import json

# 写入文件
data = {'name': 'Bob', 'age': 30, 'is_student': True}
with open('data.json', 'w') as f:
json.dump(data, f, indent=4, ensure_ascii=False)

# 读出json数据
with open('data.json', 'r') as f:
data = json.load(f)
print(data)

pip

python的包管理工具

  • 查看pip版本

    pip --version

  • 下载包

    pip install 包名

  • 删除包

    pip uninstall 包名

  • 查看已安装的包

    pip list


python基础
http://xwww12.github.io/2025/06/01/python/python基础/
作者
xw
发布于
2025年6月1日
许可协议