变量和简单的数据类型
变量
message = "Hello Python!"# 定义 message 变量print(message)message = 123print(message)var_flag = TruevarFlag = true # 可以,但不推荐
变量是可以被赋值的标签,它指向特定的值,且可以随时指向新的值。
- 变量名只能包含字母、数字和下划线,且只能以字母或下划线作为开头。
- 变量名不能包含空格,但能使用下划线来分隔其中的单词。
- 一般都用小写的变量名,全大写的变量名一般用于常量,大驼峰命名法则用于类的定义(与 Java 一致)。
- Java 中默认驼峰命名,但在 Python 中默认是蛇形命名法
字符串
- 单引号
'' 和双引号 "" 都可以用来标识字符串 - 丰富的内置方法:
title(), upper(), lower(), strip() 等 - f-string 是推荐的字符串格式化方式(Python 3.6+)
a='an"d3"11'# 单引号中包含双引号print(a)ab = "Hello'Time"# 双引号中包含单引号print(ab)name = 'Hey, demon.lee'print(name.title()) # Hey, Demon.Lee 首字母大写print(name.upper()) # HEY, DEMON.LEE 全大写print(name.lower()) # hey, demon.lee 全小写s = " hi,python 123 "print(f"[{s.lstrip()}]") # [hi,python 123 ] 去掉左边空格print(f"[{s.rstrip()}]") # [ hi,python 123] 去掉右边空格print(f"[{s.strip()}]") # [hi,python 123] 去掉两边空格url="www.google.com/hey/123"print(url.removeprefix("www.")) # 删除前缀:google.com/hey/123print(url.removesuffix("www.")) # 删除后缀(没匹配到):www.google.com/hey/123print(url.removesuffix("/123")) # 删除后缀:www.google.com/heymsg = "\tHow are you?"greet = f"{name.title()}{msg}"# 使用 f-string 进行字符串格式化print(greet) # Hey, Demon.Lee How are you?
数字
1、主要是整数和浮点数
2、任意两个数相除,结果总是浮点数
c = 10/5print(c) # 2.0print(type(c)) # <class 'float'>
3、只要有操作数是浮点数,结果就是浮点数
c = 1 +2.2print(c) # 3.2
4、浮点数计算,末尾的小数位可能出现不稳定的误差
c = 0.1 + 0.2print(c) # 0.30000000000000004print(f"{c:.1f}") # 0.3 字符串格式化,保留1位小数print(f"{c:.2f}") # 0.30 字符串格式化,保留2位小数
5、长整数表达可以使用下划线(Python 3.6+)
aa = 12_000_000_000print(aa) # 12000000000
6、同时给多个变量赋值
aa,bb,cc = 11,22,"33"print(aa,bb,cc) # 11 22 33print(type(cc)) # <class 'str'>
7、乘方运算 ** ,整除运算 //
a = 2 ** 3b = a / 5c = a // 6print(a,b,c) # 8 1.6 1
8、转字符串,可以使用 str() 方法
a = 22b = 33.21print("a: "+str(a)) # a: 22print("b: "+str(b)) # b: 33.21
注释
单行注释,行内注释
# 这是单行注释 print("Hello!") # 行内注释
列表
列表简介
1、使用 [] 定义,元素用 , 分隔,支持存储任意类型
2、有序,可修改,动态数组,自动扩容
3、支持负索引,比如 -1 表示最后一个元素,-2 表示倒数第二个元素
arr = ['字符串', 123, 33.23, True, "test"]print(arr) # ['字符串', 123, 33.23, True, 'test']print(arr[1], arr[-1]) # 123 test
4、修改元素
arr[0] = "字符"print(arr) # ['字符', 123, 33.23, True, 'test']
5、添加元素:append 在末尾追加,insert 在指定位置插入
arr = [] # 创建空列表arr.append("你好") # 追加元素arr.append(123)print(arr) # ['你好', 123]arr.insert(1, True) # 在 index = 1 的位置插入数据,后面的数据自动往后移动print(arr) # ['你好', True, 123]
6、删除元素:del ,pop ,remove
arr = ['字符串', 123, 33.23, True, "test"]del arr[0] # 按索引删除print(arr) # [123, 33.23, True, 'test']e = arr.pop() # 弹出最后一个元素print(e) # testprint(arr) # [123, 33.23, True]e = arr.pop(1) # 按指定位置弹出元素print(e) # 33.23print(arr) # [123, True]arr.append(123)arr.remove(123) # 按值删除,但只匹配第一个,无返回值print(arr) # [True, 123]
7、排序:sort 原地永久排序,sorted 临时排序,reverse 反转列表,len 计算列表长度
arr = [121, 33, 1, 99, 68, 12, 77]arr1 = sorted(arr) # 临时排序print(arr1) # [1, 12, 33, 68, 77, 99, 121]print(arr) # [121, 33, 1, 99, 68, 12, 77]print(len(arr)) # 7arr.reverse() # 反转,永久print(arr) # [77, 12, 68, 99, 1, 33, 121]arr.sort() # 永久排序(默认升序)print(arr) # [1, 12, 33, 68, 77, 99, 121]arr.sort(reverse=True)print(arr) # [121, 99, 77, 68, 33, 12, 1]
操作列表
1、代码块通过缩进界定,不像 Java 或 C 中的 {} ,Python 中 4 个空格表示缩进,注意不要混用 Tab 和空格
2、遍历列表:for item in list:
arr = [121, 33, 1]for i in arr: print(i) # 注意缩进print(f"arr len: {len(arr)}") # 非循环体不需要缩进# 输出内容如下:121331arr len: 3
如果是空循环体,可以用 pass 代替。
3、创建数值列表:range 函数
# range(stop) - 从 0 开始,stop 不包含在内# range(start, stop) - stop 不包含在内# range(start, stop, step) - 带步长for value in range(1, 3): print(value)# 输出内容如下:12for value in range(2): print(value)# 输出内容如下:01arr = list(range(1, 10, 3)) # 转列表print(arr) # [1, 4, 7]
4、列表统计:min ,max,sum
arr = [1,3,5]print(min(arr)) # 1print(max(arr)) # 5print(sum(arr)) # 9
5、列表推导
even_squares = [x ** 2for x in range(2,11,2)]print(even_squares) # [4, 16, 36, 64, 100]
6、切片:Python 切片 list[0:3] 类似 Java 的 list.subList(0, 3)
list[start:end] 包含 start,不包含 stoplist[:] 相当于复制整个列表,但仍属于浅拷贝
arr = ['Hey','你好','时间']arr1 = arr[0:1]print(arr1) # ['Hey']arr1.append('world')print(arr) # ['Hey', '你好', '时间']print(arr1) # ['Hey', 'world']print(arr[:2]) # ['Hey', '你好'] 复制:从 0 到 1print(arr[2:]) # ['时间'] 复制:从 2 到末尾print(arr[-2:]) # ['你好', '时间'] 复制:从倒数第 2 到末尾
7、元组(Tuple):不可变列表,用于存储不可变数据,不能修改元素值,但可以给变量重新赋值,用 () 定义
arr1 = (1, 3, 9)arr2 = (1) # 这不是元组,而是数字 1print(type(arr2)) # <class 'int'>arr3 = (1,) # 这是单元素元组print(type(arr3)) # <class 'tuple'>arr1[0] = 0# 提示错误:TypeError: 'tuple' object does not support item assignmentarr1 = ('hi', '2026')print(arr1) # ('hi', '2026')
8、代码风格(PEP 8)
if 语句
1、Python 中没有 switch...case (挺好,代码的坏味道,Java 中我也不会用这个语法),基本结构如下:
if xx1: xxxelif xx2: xxxelse: xxx
age = 12if age <= 6: price = 0elif age < 18: price = 15else: price = 30print(f"Your admission cost is ${price}.") # Your admission cost is $15.
2、用 == ,!= 比较值,用 and,or,not 等进行逻辑运算,对应 Java 中的 &&,|| 和 !
3、in 和 not in 可以用来检查列表成员是否存在,当然,也能用在字符串,字典等类型中
a = 12b = 13c = 'hello'd = "hello"print(a==b) # Falseprint(c==d) # True,没错,字符串也是用 == 比较f = a == bifnot f: print("hey...")arr = ["Jack", "小马", "2026"]if arr: # 检查列表是否为空 print("arr is not empty.")if'2026'in arr: print("here is 2026...")
4、支持链式比较,比如:11 < x < 50
5、三元表达:status = 'adult' if age >= 18 else 'minor'
字典
1、键值对,key 唯一,用 {} 表示,定义时,用 : 分隔元素的 key 和 value
d1 = {} # 定义空字典d2 = {'k1': 11, 2: 'test'}
2、基本操作
- 获取元素值:
dict[key] , dict.get(key) ,前者对于不存在的 key 会报错,后者则返回 None - 遍历 key 列表,value 列表 和 key-value 列表分别是:
dict.keys() ,dict.values() 和 dict.items()
print(d2['k1']) # 11print(d2[2]) # testprint(d2['k2']) # 元素不存在,提示错误:KeyError: 'k2'print(d2.get('k2')) # 元素不存在,不报错,返回 Noneprint(d2.get('k2', 'hey')) # 元素不存在,返回默认值 heyd2['k2'] = 'Hi'# 增加或修改元素d2.update(k1=110, user="root") # 增加或修改元素del d2['k2'] # 删除指定 key 的元素d2.pop('user', None) # 移除指定 key 的元素,如果 key 不存在,就返回 Noneprint(d2.keys()) # dict_keys(['k1', 2])print(d2.values()) # dict_values([11, 'test'])print(d2.items()) # dict_items([('k1', 11), (2, 'test')])for k, v in d2.items(): print(k, v)
3、集合:set,无序不重复的元素集合
set1 = set() # 定义空集合set2 = set(d2.values()) # 使用 d2 的值集合进行初始化set3 = {'k1', 11, True}set3.add('Hey')set3.remove(True)print(set2) # {'test', 11}print(set3) # {'k1', 'Hey', 11}print('c'in set3) # False
4、嵌套:字典列表,字典中存储字典,字典中存储列表
# 字典列表alien_0 = {'color': 'green', 'points': 5}alien_1 = {'color': 'yellow', 'points': 10}alien_2 = {'color': 'red', 'points': 15}aliens = [alien_0, alien_1, alien_2]print(aliens) # [{'color': 'green', 'points': 5}, {'color': 'yellow', 'points': 10}, {'color': 'red', 'points': 15}]# 字典中存储字典users = {'aeinstein': {'first': 'albert','last': 'einstein','location': 'princeton', },'mcurie': {'first': 'marie','last': 'curie','location': 'paris', },}# 字典中存储列表pizza = {'crust': 'thick', # 值是字符串'toppings': ['mushrooms', 'extra cheese'], # 值是列表}
用户输入和 while 循环
input 函数
- 返回值类型是字符串,如果需要整数或浮点数,需要进行转换
msg = input("hello, how old are you?")age = int(msg)print(age)
while 循环
- while-else 特色结构:else 在循环正常结束时执行,如果用 break 退出,else 不会执行
# 删除列表中的元素pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']while'cat'in pets: pets.remove("cat")print(pets) # ['dog', 'dog', 'goldfish', 'rabbit']# while 判断集合时会自动判断是否为空,不需要额外的 empty 判断while xxList: # 如果 xxList 为空,那么判断就是 Falsepass# while-else 特色结构numbers = [1, 3, 5, 7, 9]target = 4index = 0while index < len(numbers):if numbers[index] == target: print(f"找到 {target} 在索引 {index}")break index += 1else: print(f"未找到 {target}")
函数
Python 中函数是一等公民,可以赋值给变量、作为参数传递等。
1、定义
# 定义defgreet_user(name):"""显示简单的问候语"""# 函数注释 print(f"Hello, {name}")returnf"hey,{name}"# 调用greet_user("Pony") # Hello, Pony
2、参数传递:默认值,按位置传参,按关键字传参
- 位置传参与关键字传参混合使用时,位置实参必须在关键字实参前面
# 默认值defdescribe_pet(pet_name, animal_type='dog'):# animal_type 默认 'dog' print(f"I have a {animal_type} named {pet_name}.")describe_pet('willie') # 按位置传参describe_pet(animal_type='hamster', pet_name='harry') # 按关键字传参,顺序不重要
3、任意数量参数
*args 和 **kwargs 各自最多只有一个,且 **kwargs 必须在最后
defmake_pizza(*toppings): print(toppings)make_pizza('pepperoni', 'mushrooms', 'cheese') # ('pepperoni', 'mushrooms', 'cheese')defbuild_profile(first, last, **user_info): user_info['first_name'] = first user_info['last_name'] = lastreturn user_infouser = build_profile('albert', 'einstein', location='princeton', field='physics')print(user) # {'location': 'princeton', 'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein'}
4、模块导入
# 导入整个模块import pizza# 导入特定函数from pizza import make_pizza# 给导入的模块设置别名import pizza as p# 给导入的函数设置别名from pizza import make_pizza as mp# 不推荐:导入模块中的所有函数from pizza import *
类
1、定义类与创建实例
- 构造方法:
__init__ ,类似于 Java 的构造函数 self 类似于 Java 类中的 this 关键字,但必须显示声明- 创建实例直接调用类名,不需要 Java 中的
new 关键字 - 访问属性: instance.attribute(惯用直接访问),调用方法: instance.method()
classDog:"""小狗的简单模拟"""def__init__(self, name, age):"""初始化属性""" self.name = name self.age = age self.description = ''# 给属性设置默认值defsit(self):"""蹲下""" print(f"{self.name} is now sitting.")defroll_over(self):"""打滚""" print(f"{self.name} rolled over!")defmock(self, mock_flag):"""mock""" self.mock_flag = mock_flag # 动态添加成员属性 print(f"{self.name} mock: {mock_flag}") dog1 = Dog("Jim", 3)print(dog1) # <__main__.Dog object at 0x1077052b0>print(dog1.name) # Jimdog1.roll_over() # Jim rolled over!
2、继承
- 单继承: Child(Parent),也支持多继承: Child(Parent1, Parent2, Parent3)
- 调用父类构造函数:
super().__init__
classCar:def__init__(self, make, model, year): self.make = make self.model = model self.year = year self.odometer_reading = 0defget_descriptive_name(self):returnf"{self.year}{self.make}{self.model}"classElectricCar(Car):# 继承 Cardef__init__(self, make, model, year): super().__init__(make, model, year) # 调用父类构造 self.battery_size = 75defdescribe_battery(self): print(f"This car has a {self.battery_size}-kWh battery.")my_tesla = ElectricCar('tesla', 'model s', 2019)print(my_tesla.get_descriptive_name()) # 2019 tesla model smy_tesla.describe_battery() # This car has a 75-kWh battery.
3、访问控制
@property 类似 Java 中的 getter()__方法名__(前后各两个下划线)被称为魔术方法或特殊方法,它是Python 保留的,在特定时机被自动调用
classPerson:def__init__(self, name, age):# 1. 公开属性 - 任何地方都可以访问 self.name = name# 2. 约定私有 - 单下划线开头 self._age = age# 3. 名称修饰私有 - 双下划线开头 self.__secret = "hidden"# getter @propertydefage(self):return self._age# setter @age.setterdefage(self, value): self._age = value# 公开方法defsay_hello(self): print(f"Hello, I'm {self.name}")# 约定私有方法def_internal_method(self): print("Internal use only")# 名称修饰私有方法def__private_method(self): print("Private by name mangling")jack = Person('Jack', 33)print(jack.name) # jackprint(jack._age) # 33 可以访问,但不建议jack.age = 28# 通过 `@age.setter` 实现 setter 效果print(jack.age) # 28 通过 `@property` 实现 getter 效果print(jack.__secret) # AttributeError: 'Person' object has no attribute '__secret'print(jack._Person__secret) # hidden 名称修饰后可访问
文件和异常
文件
1、读取
- 使用
with 关键字自动管理文件资源,不需要手动调用 close() (Java 需要 try-finally 或 try-with-resources)
# 方式1:一次性加载with open('pi_digits.txt') as file_object: contents = file_object.read() print(contents)# 方式2:逐行迭代,如果是大文件,推荐此方式with open('langchain_agent_shell.py') as file_object:for line in file_object: print(line.rstrip())# 方式3:一行行读取with open('langchain_agent_shell.py') as file_object: line1 = file_object.readline() line2 = file_object.readline() print(line1) print(line2)# 方式4:一次性加载所有行到列表with open('langchain_agent_shell.py') as file_object: lines = file_object.readlines() print(f"line num: {len(lines)}")for line in lines: print(line.rstrip())
2、写入
模式:r 读取(默认),w 写(覆盖),a 追加
with open("demo-py.txt", "w") as f: f.write("你好,Python......\n人生苦短,我用Python。\n")with open("demo-py.txt", "a", encoding='utf-8') as f: f.write("测试123......")
3、JSON 数据处理
- 将 Python 对象转成字符串:
json.dumps() - 将字符串转 Python 对象:
json.loads()
>>> jstr = '{"你好":"hello", "u2":"测试", "u3": null}'>>> d1 = json.loads(jstr)>>> type(d1)<class 'dict'>>>> >>> print(d1){'你好':'hello', 'u2': '测试', 'u3': None}>>>
异常
1、try-except-else-finally 结构,else 在无异常时执行
try: file = open('data.txt') data = file.read()except FileNotFoundError: print("File not found")else: print("File found")finally: print("Cleanup code here")# 如果 data.txt 不存在,则输出File not foundCleanup code here# 如果 data.txt 存在,则输出File foundCleanup code here
2、常见异常
ZeroDivisionError # 除零FileNotFoundError # 文件不存在ValueError # 值错误(如 int("abc"))TypeError # 类型错误IndexError # 索引越界KeyError # 字典键不存在AttributeError # 属性不存在NameError # 变量未定义SyntaxError # 语法错误ModuleNotFoundError # 模块不存在ImportError # 导入错误
参考资料
[1] Python 编程(第3版): https://book.douban.com/subject/36365320/