Python学习笔记
开发环境:
Python 3.9.9 (main, Nov 21 2021, 03:23:44)
[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
目录
变量和数据类型
message = "Hello, world!"
print(message)
**注意:**Python 2中无需讲打印内容放在括号内:
# Python 2
print "Hello!"
- 变量名可包含字母、数字及下划线,开头可以是字母或下划线,不能是数字,不能包含空格
字符串
字符串可用单引号或双引号:
"Communicate! It can't make things any worse."
'"Life, loathe it or ignore it, you can\'t like it." -- Marvin, "Hitchhiker\'s Guide to the Galaxy"'
字符串操作
大小写、拼接:
name = "joe noname"
name.title()
name.upper()
name.lower()
greeting = "Hello, " + name.title() + "!"
删除空白:
language = ' python '
language.rstrip() # ' python'
language.lstrip() # 'python '
language.strip() # 'python'
数字运算
2 + 3 # 5
2 - 3 # -1
2 * 3 # 6
3 / 2 # 1.5
3 ** 2 # 9,乘方
0.1 + 0.1 # 0.2
0.2 + 0.1 # 0.30000000000000004
Python 2中两个整数相除结果可能会略有不同:
# Python 2
3 / 2 # 1
3.0 / 2 # 1.5
数字于字符串合并时需要转换类型:
age = 19
print("You have a body of a " + str(age) + "year old, Please return it before it gets wrinkled.")
列表
Python里,列表的索引从0开始。
- 访问元素:
列表[索引]
,e.g.list[2]
- 访问最后一个元素:
list[-1]
- 添加新元素:
list.append(新元素)
- 在指定索引位置插入元素:
list.insert(索引, 元素)
- 删除索引位置元素:
del list[索引]
,e.g.del array[2]
- 弹出并返回栈顶元素:
popped = list.pop()
- 弹出并返回任意元素:
popped = list.pop(3)
- 根据指定值删除元素:
list.remove('bug')
,只删除第一个'bug'
排序
- 将列表排序:
list.sort()
- 返回一个排序的列表:
list.sorted()
- 返回倒序列表:
list.sorted(reverse=True)
- 反转列表顺序:
list.reverse()
- 返回列表长度:
len(列表)
列表操作
Python根据缩进来判断代码行与前一个代码行的关系。
遍历列表
fruits = ['apple', 'orange', 'banana']
for fruit in fruits:
print("Start eating " + fruit)
print("Finished eating " + fruit)
print("All fruits are gone!")
创建数值列表
for value in range(1, 3):
print(value)
# 1
# 2
single_digits = list(range(0, 10))
print(single_digits) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
squared_digits = [value ** 2 for value in range(0, 10)]
print(squared_digits) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
- 列表最大、最小值:
max(列表)
,min(列表)
- 列表数字和:
sum(列表)
列表切片(Slice)
names = ['李逍遥', '奥斯特洛夫斯基', '黑猫警长', '阿凡提', '大力水手', '樱木花道', '白居易', '野原新之助']
print(names[0:3]) # 从0开始到索引2:['李逍遥', '奥斯特洛夫斯基', '黑猫警长']
print(names[1:4]) # 从1开始到索引3:['奥斯特洛夫斯基', '黑猫警长', '阿凡提']
print(names[:2]) # 从0开始到索引1:['李逍遥', '奥斯特洛夫斯基']
print(names[5:]) # 从5开始到末尾:['樱木花道', '白居易', '野原新之助']
print(names[-3:]) # 最后三个:['樱木花道', '白居易', '野原新之助']
for name in names[:5]:
print(name)
复制列表
复制一个列表,且不影响原列表:
names_backup = names[:]
附值,新列表操作会影响原列表:
names_backup = names
元组
Python的元组(Tuple)具有有序、不可改变、可复制的特性。
point = (41, 21)
for value in point:
print(value)
mixed_tuple = ('hi', 123, True)
创建只有一个元素的元组时需注意:
thistuple = ('apple',)
type(thistuple) # <class 'tuple'>
thistuple = ('apple')
type(thistuple) # <class 'str'>,这里只是个简单的字符串
if
if
的语法:
if conditional_test1:
statement1
elif conditional_test2:
statement2
# elif conditional_testN:
# statementN
else
statementN
- 判断是否相等:
==
- 判断是否不等:
!=
- 大于:
>
,小于:<
,大于等于:>=
,小于等于:<=
- 检查多个条件:
and
,or
:age > 21 and age < 65
,age < 18 or age > 80
- 检查特定值是否包含在列表里:
'白居易' in names
- 检查特定值是否不包含在列表里:
'曹孟德' not in names
- 判断列表是否为空:将列表名用在条件表达式中,至少包含一个元素时Python返回
True
,否则False
age = 19
if age >= 18:
print("Common sense is the collection of prejudices acquired by age eighteen.")
print(" -- Albert Einstein")
else
print("What should young people do with their lives today? Many things, obviously. But the most daring thing is to create stable communities in which the terrible disease of loneliness can be cured.")
print(" -- Kurt Vonnegut, Jr.")
字典
player = {'name': 'Peter', 'age': 21}
print(player['name']) # 'Peter'
print(player['age']) # 21
player['country'] = 'Earth'
-
创建空字典:
features = {}
-
删除键值:
del player['country']
-
遍历字典:
for k, v in player.items()
-
遍历字典所有键:
player.keys()
,排序:sorted(player.keys())
-
遍历字典所有值:
player.values()
print("Key " + k + " has value of: " + v)
用户输入和while循环
name = input("Who are you? ")
race = input("What are you? ")
age = input("How old are you? ")
print("Hello " + name + ", " + "you are a young " + race + ", age " + int(age))
**注意:**Python 2请使用raw_input()
来获取用户输入。
while
prompt = "\nDo you agree to vote for him?"
message = ""
while message.lower() != "yes":
message = input(prompt)
print(message)
- 许多语言中常用的
break
和continue
在Python里也适用
函数
函数、参数、参数名:
def show_greeting(name):
print("Hello, " + name + "!")
show_greeting("Tom")
show_greeting(name = 'Tom')
默认值
def prepare_food(is_vegetarian = False, is_diet = False):
if is_vegetarian:
print("Vegetarian food.")
else:
print("Regular food.")
if is_diet:
print("Diet option.")
prepare_food() # Regular food.
prepare_food(is_vegetarian = True) # Vegetarian food.
prepare_food(is_diet = True, is_vegetarian = True) # Vegetarian food. Diet option.
- 指定参数名时,参数顺序不重要
返回值,可选参数
def formatted_name(first_name, last_name, middle_name = ''):
if middle_name:
full_name = first_name + ' ' + middle_name + ' ' + last_name
else:
full_name = first_name + ' ' + last_name
return full_name.title()
print(formatted_name('Mono', 'Brown')) # Mono Brown
返回列表与禁止修改列表
def get_initials(names[:], initials)
任意数量参数
def prosecutes(sentence, *names):
print(sentence + ':')
for name in names:
print(name)
prosecutes('Prosecutes the following anti-revolutionists:', 'Tom', 'Jo', 'Sam')
任意数量的键值:
# profile.py
def create_player(first, last, **info):
profile = {'first_name': first, 'last_name': last}
for key, value in info.items():
profile[key] = value
return profile
player = create_player('Mark', 'Twin', country='UK', occupation='Cook')
print(player)
# {'first_name': 'Mark', 'last_name': 'Twin', 'country': 'UK', 'occupation': 'Cook'}
**info
两个星号让Python把所有键值都存在一个字典中。
模块
import profile
profile.create_player('Alex', 'Bob', occupation='Hacker', country='N/A')
# {'first_name': 'Alex', 'last_name': 'Bob', 'occupation': 'Hacker', 'country': 'N/A'}
导入模块Module
后,便可调用其中任何一个函数:Module.function()
。
导入特定函数
from module_name import function_name
导入函数改名
from profile import create_player as cp
导入模块改名
import profile as p
p.create_player('First', 'Last', job='Trouble Maker')
导入模块所有函数
导入模块中所有函数后,调用函数不需要加模块名前缀,一般不建议使用。
from profile import *
create_player('Noface', 'Man', color='Red')
类
定义一个Name
类,包含名、姓以及可选的中间名:
class Name():
def __init__(self, first, last, middle = ""):
self.first = first
self.last = last
self.middle = middle
def fullname(self):
if self.middle:
return self.first.title() + ' ' + self.middle.title() + ' ' + self.last.title()
else:
return self.first.title() + ' ' + self.last.title()
定义一个Person
类,包含人的基本信息,名字为Name
类实例:
class Person():
def __init__(self, name: Name, age, gender):
self.name = name
self.age = age
self.gender = gender
def intro(self):
print(self.name.fullname() + " is a " + self.gender + ", " + str(self.age) + " year(s) old.")
创建一个Person
实例,调用其方法,并访问其属性:
name = Name('Tom', 'Brown', 'Elizabeth')
someone = Person(name, 18, "male")
someone.intro()
someone.name
定义一个Student
类,继承Person
类,重载intro
方法并加上额外的描述:
class Student(Person):
def __init__(self, name, age, gender, course):
super().__init__(name, age, gender)
self.course = course
def describe_course(self):
print("This student is currently doing " + self.course + " course.")
def intro(self):
Person.intro(self)
self.describe_course()
student = Student(name, 15, 'female', 'Mummification')
student.intro()
# Tom Elizabeth Brown is a female, 15 year(s) old.
# This student is currently doing Mummification course.
__init__()
实例构造方法,self
参数不可少,创建实例时自动传入- 如果以上类定义存在
person.py
文件里,其他源代码可以导入模块来使用:import person
或from person import Student
混名
以下类定义:
class Box:
def __init__(self):
self.__secret == 5
self._shared = 1
访问变量_shared
:
Box()._shared # 1
访问变量__secret
出错:
Box().__secret
# AttributeError: 'Box' object has no attribute '__secret'
Python编译器遇到以两个下划线开始的变量命名时,会把此变量改名为_Box__secret
:
Box()._Box__secret # 5
- 没办法完全禁止访问实例变量
类方法和静态方法
class Box:
value = 12
@classmethod
def classMethod(cls):
print("Class Method, cls.value = ", cls.value)
@staticmethod
def staticMethod():
print("Static method)
- 关键字
@classmethod
用来在方法前表示此方法为类方法 - 类方法的第一个参数为类,而不是
self
- 类方法可以访问类变量
调用类方法可以用类名+方法名,或者实例名+方法名:
Box.classMethod()
Box().classMethod()
- 关键字
@staticmethod
用来标志静态方法 - 静态方法没有实例或类的参数
调用静态方法依然可以用类名+方法名,或者实例名+方法名:
Box.staticMethod()
Box().staticMethod()
文件和异常
poem.txt:
白日依山尽
黄河入海流
欲穷千里目
更上一层楼
with open('poem.txt') as file_object:
contents = file_object.read()
print(contents)
# 输出:
# 白日依山尽
# 黄河入海流
# 欲穷千里目
# 更上一层楼
#
- 以上程序输出最后有一行空行,因为
read()
方法到达文件末尾时会返回一个空字符串,显示出来即为一个空行 - 可以把
print(contents)
改为print(contents.rstrip())
来去掉空行
逐行读取
filename = 'poem.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
将文件转换为包含各行内容的列表
filename = 'poem.txt'
with open(filename) as file_object:
lines = file_object.readlines()
写入文件
filename = 'poem.txt'
with open(filename, 'w') as file_object:
file_object.write('偶闻蛙声惊骤雨\n') # 写入不会自动换行
file_object.write('常有心上些许愁')
打开文件的机种模式:
'w'
写入模式'r'
只读模式'a'
附加模式'r+'
可写可读模式
异常处理
first_number = input('First number: ')
second_number = input('Second number: ')
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't devide by zero!")
else:
print(answer)
处理文件异常:
filename = 'poem.txt'
try:
with open(filename) as f_obj:
contents = f_obj.read()
except FileNotFoundError:
print('File not found: ' + filename + '!')
出现异常时沉默:
except FileNotFoundError:
pass
JSON
import json
filename = 'name_list.txt'
names = ['Tom', 'Jack', 'Tony']
with open(filename, 'w') as f_obj:
json.dump(names, f_obj)
with open(filename) as f_obj:
names = json.load(f_obj)