Python 基础与高级特性
1. 字符串 (String)
- 不可变性:Python 中的字符串是不可变的(immutable)。一旦创建,就不能修改。如果需要一个不同的字符串,应当新建一个。
- 索引操作:由于不存在单独的“字符”类型,对字符串做索引操作将产生一个长度为 1 的字符串。例如,对于一个非空字符串
s
,s[0] == s[0:1]
。 - 高效构建:虽然没有可变的字符串类型,但可以使用
str.join()
或io.StringIO
来根据多个片段高效率地构建字符串。
2. 列表 (List)
- 可变性:列表是一个可变(mutable)类型,即它的内容可以在创建后被改变。
- 支持的操作:列表支持索引、切片、拼接等操作。此外,列表还可以嵌套。
- 示例:
1
2
3
4# 创建和修改列表
my_list = [1, 2, 3]
my_list.append(4) # 添加元素
my_list[0] = 'a' # 修改元素
3. range
对象
- 迭代器特性:
range
返回的对象在许多方面表现得像一个列表,但它并不是真正的列表。它会在你迭代时基于所希望的序列返回连续的项,而不会生成整个列表,从而节省空间。 - 示例:
1
2print(range(10)) # 输出: range(0, 10)
list(range(10)) # 转换为列表: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4. 循环 (Loop)
- 字典循环:使用
items()
方法可以在字典中同时取出键和值。1
2
3knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
print(k, v) - 枚举循环:使用
enumerate()
函数可以在序列中同时获取索引位置和其对应的值。1
2for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v) - 多序列循环:使用
zip()
函数可以同时在两个或更多序列中循环,并将它们的元素一一匹配。1
2
3
4questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
print('What is your {0}? It is {1}.'.format(q, a))
5. 赋值、浅拷贝、深拷贝
- 直接赋值:默认情况下,赋值只是传递对象的引用。原始列表改变,被赋值的变量也会相应改变。
- 浅拷贝:使用
copy.copy()
进行浅拷贝,只复制顶层对象,子对象仍然共享引用。因此,原始数据改变时,子对象会受到影响。 - 深拷贝:使用
copy.deepcopy()
进行深拷贝,不仅复制顶层对象,还会递归地复制所有子对象。因此,原始对象的改变不会影响深拷贝中的任何子元素。1
2
3
4
5
6
7
8import copy
original_list = [[1, 2], [3, 4]]
shallow_copied_list = copy.copy(original_list)
deep_copied_list = copy.deepcopy(original_list)
original_list[0][0] = 'changed'
print(shallow_copied_list) # [[changed, 2], [3, 4]]
print(deep_copied_list) # [[1, 2], [3, 4]]
6. 序列类型
- 序列类型:Python 支持多种序列类型,包括字符串、列表、元组和
range
。它们都支持索引和切片操作。 - 元组:元组是另一种标准的序列类型,类似于列表,但它是不可变的。
1
2t = ('a', 'b', 'c')
print(t[0]) # 输出: a
7. 数据类型
- 序列:字符串、列表、元组、
range
- 字典:使用花括号
{}
或dict()
创建字典。字典是由键值对组成的无序集合。1
2my_dict = {'name': 'Alice', 'age': 30}
print(my_dict['name']) # 输出: Alice - 集合:使用花括号
{}
或set()
函数创建集合。注意:要创建一个空集合只能用set()
,因为{}
是创建一个空字典。1
2my_set = set([1, 2, 3])
print(my_set) # 输出: {1, 2, 3}
8. 模块搜索路径
- 模块导入:当导入名为
spam
的模块时,解释器首先寻找具有该名称的内置模块。如果没有找到,然后解释器从sys.path
变量给出的目录列表里寻找名为spam.py
的文件。 sys.path
初始目录:- 包含输入脚本的目录(或者未指定文件时的当前目录)。
PYTHONPATH
(一个包含目录名称的列表,语法与 shell 变量PATH
相同)。- 安装的默认设置。
9. 类 (Class)
9.1 实例对象数据属性
- 动态属性:类的实例对象数据属性不需要声明;像局部变量一样,它们将在第一次被赋值时产生。
1
2
3
4
5
6
7
8
9
10
11
12
13class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
x = MyClass()
x.counter = 1
while x.counter < 10:
x.counter = x.counter * 2
print(x.counter) # 输出: 16
del x.counter
9.2 方法对象
- 方法引用:立即调用一个方法并不是必须的。方法对象可以被保存起来以后再调用。
1
2
3xf = x.f
while True:
print(xf()) # 继续打印 'hello world',直到结束
9.3 类变量与实例变量
- 类变量:用于类的所有实例共享的属性和方法。
- 实例变量:用于每个实例的唯一数据。
- 共享数据注意事项:涉及 mutable 对象(如列表和字典)时,共享数据可能导致意外的结果。例如,
tricks
列表不应该作为类变量,因为所有的Dog
实例将共享同一个列表。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Dog:
kind = 'canine' # 类变量,所有实例共享
tricks = [] # 错误的做法,所有实例共享同一个列表
def __init__(self, name):
self.name = name # 实例变量,每个实例独立
def add_trick(self, trick):
self.tricks.append(trick)
d = Dog('Fido')
e = Dog('Buddy')
d.add_trick('roll over')
e.add_trick('play dead')
print(d.tricks) # 输出: ['roll over', 'play dead']
9.4 动态语言特性
- 运行时增加/删除属性:Python 是动态语言,可以在运行时增加或删除属性。与之相反,Java 是静态语言,属性必须在编译时定义。
10. 访问控制
- **公共属性 (
public
)**:默认情况下,所有方法和变量都是公共的,没有任何下划线。 - **保护属性 (
protected
)**:以单下划线开头的属性(如_xx
)表示受保护的属性,只能允许其本身与子类访问。 - **私有属性 (
private
)**:以双下划线开头的属性(如__xx
)表示私有属性,只能在类内部访问。 - 特殊方法:以双下划线开头和结尾的方法(如
__init__
)是特殊方法,用户不应自行定义这些名称,除非文档中有明确说明。
11. 迭代器 (Iterator)
- 迭代器协议:大多数容器对象都可以使用
for
语句进行迭代。在幕后,for
语句会在容器对象上调用iter()
函数,返回一个定义了__next__()
方法的迭代器对象。当元素用尽时,__next__()
将引发StopIteration
异常来通知终止循环。 - 示例:
1
2
3
4
5
6
7
8for element in [1, 2, 3]:
print(element)
for key in {'one': 1, 'two': 2}:
print(key)
for line in open("myfile.txt"):
print(line, end='')
12. 标准库
- 丰富的标准库:Python 提供了一个广泛的标准库,涵盖了文件处理、网络编程、正则表达式、日期时间处理等多个领域。标准库的使用极大地简化了开发过程。
13. 列表推导式 (List Comprehension)
- 简洁的语法:列表推导式提供了一种简洁的方式来创建列表。它可以替代传统的
for
循环和append()
操作。 - 示例:
1
2
3
4
5squares = [x**2 for x in range(10)]
print(squares) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # 输出: [0, 4, 16, 36, 64]