【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://blog.csdn.net/m0_69908381/article/details/132368704
出自【进步*于辰的博客】
相关博文:【python细节、经验】锦集。
注:本文可能不适合 0 python基础的博友,因为对于各类知识点,我阐述的宗旨是“阐明使用细节”,而不是基础知识。
文章目录
- 1、特殊指令符
- 1.1 `del xx`
- 1.2 `python fpath args`
- 2、内置函数
- 3、关于列表(`list`)
- 3.1 切片示例
- 3.2 方法
- 4、关于元组(`tuple`)
- 5、关于字典(`map`)
- 5.1 概述
- 5.2 方法
- 6、关于集合(`set`)
- 6.1 概述
- 6.2 方法
- 7、关于变量
- 7.1 分类
- 7.2 可变参数
- 7.2.1 `*args`格式
- 7.2.2 `**args`格式
- 7.2.3 特殊用法
- 8、关于`lambda`表达式
- 8.1 特点
- 8.1 用法1:简化函数
- 9、关于面向对象
- 10、关于异常处理
- 11、关于模块
- 12、关于标准库
- 12.1 `sys`库
- 12.2 `os`库
- 12.3 `math`库
- 12.4 `random`库
- 13、关于实例创建
- 最后
1、特殊指令符
1.1 del xx
1、del list[索引] # 删除列表元素
2、del tuple # 删除整个元组
3、del map[key] # 删除字典映射
1.2 python fpath args
注:在终端(Terminal)执行。
运行源代码文件。其中,fpath 是源文件全限定名;args 是命令行参数列表,可任意指定。
示例:
python model/Util.py name=csdn year=2023 # 运行 model 包下的Util.py文件,指定命令行参数 name=csdn,year=2023
2、内置函数
摘要 | 参数说明 | 返回值类型/返回值 | 说明 |
---|---|---|---|
list(tuple t) | 列表 | 将元组转换成列表。注:不修改原元组 | |
range(int max) | 序列最大值 | 序列 | 此方法作用很多,此处的作用是指定一个最大值,返回0 ~ max - 1 的序列,常用于遍历 |
filter(a, b) | a 是方法,即过滤条件;b 是序列 | 序列 | 过滤序列,需与lambda连用,示例见相关博文第4项 |
input(String tip) | 提示 | str | 键盘输入 |
dir([模板名]) | 列表 | 获取对象的模板标识符,无参时获取的是当前模板标识符 | |
max(字典) | str | 返回最大 value 对应的 key |
3、关于列表(list
)
参考笔记二,P25.3~5。
3.1 切片示例
- 例:
list = [1, 2, 3, 4]
,则list[-3:] = [2, 3, 4]
、list[:3] = [1, 2, 3]
,故:list[-3: 3] = [2, 3]
。由于[2, 3] = [2, 3, 4] 并 [1, 2, 3]
,因此,list[-3: 3] = list[-3:] 并 list[:3]
; - 例;
list[a: b: x]
,其中,a 是起始索引,b 是终止索引,x 是步长。若x > 0
,则从左往右切片;否则,从右往左切片。
注:实际切片内容并不一定是按照[a, b)
(即 a → b)或(b, a]
(即 b → a)规则进行切片。由于a/b/x
三者都有“正负”2种情形,因此实际的切片情况很多,我暂且没有找到规律,因此只能按照示例1的“拆分”方法进行分析。
具体方法:
1、将 [a: b: x] 拆分d成 [a: : x] 和 [: b: x];
2、计算[a: : x]:a 为起始索引,若x > 0,则向右取所有;否则,向左取所有。得到:[list[a], ...];
3、计算[: b: x]:b 为终止索引,同理,得到:[..., list[b]];
4、结果:取两者交集.
3.2 方法
摘要 | 参数说明 | 返回值类型/返回值 | 说明 |
---|---|---|---|
append(Object o) | 追加一个元素 | ||
extend(List it) | 追加列表 | ||
insert(int i, Object o) | 插入元素 | ||
pop(int i) | 返回被删除元素 | 删除元素。若不指定,则删除最后一个元素 | |
remove(Object o) | 移除匹配的第一个元素 | ||
index(Object o) | 索引 | 查找匹配的第一个元素。若找不到,则报错 | |
reverse() | 反转列表。相当于list[::-1] | ||
count(Object o) | int | 计数 | |
sort() | 排序,默认升序。注:列表所有元素类型必须一致 |
注:
- 列表元素类型可混搭;
- 切片时,若索引超出范围,不报错。
4、关于元组(tuple
)
参考笔记二,P33.1。
概述:
- 元组自创建后无法修改;
- 若元组只有一个元素,则末尾必须添加一个"
,
",否则其类型就不是元组,而是此元素类型; - 元组无法修改,但基本支持列表拥有的查询系列方法,如:
count()
、index()
,故元组的查询效率高于列表(元组的作用之一)。
示例:
t = (2023)
print(type(t))
t = (2023,)
print(type(t))
print(t.count(2023))
print(t.index(2023))
打印结果:
5、关于字典(map
)
参考笔记二,P33.2。
5.1 概述
- 添加映射时,若 key 已存在,则覆盖 value;
- 用“
{}
”表示空字典; - 访问不存在的 key 时,报错;
- 当为不存在的 key 赋值时,添加此映射;
示例:
m = {}
print(type(m)) # 打印:<class 'dict'>
m = {
"name" : 'yuchen',
"year" : 2023
}
# print(m['age']) # 报错:KeyError
5.2 方法
1、clear()
:清空字典,无返回值。
2、copy()
:复制字典,属“浅复制”。
3、fromkeys(a, b)
:创建字典。
注:a 是序列,b 是默认值(可不指定)。
示例:
m = {} # 空字典
l = [2, 0, 2, 3]
m = m.fromkeys(l) # 使用列表构建字典
print(m)
m = m.fromkeys(l, 0) # 指定所有映射的 value 为 0,即默认值
print(m)
t = (2023,)
m = m.fromkeys(t) # 使用元组构建字典
print(m)
s = set([2, 0, 2, 3])
m = m.fromkeys(s) # 使用集合构建字典
print(m)
打印结果:
4、get(a, b)
:获取 value。
注:a 是 key,b 是默认值(当 key 不存在时作为返回值,可不指定)。若 key 不存在,则返回None
。
5:keys()
:返回包含字典所有 key 的“列表”。
注:表面上看是列表,实则不是,用type()
即可验证,在某些情况下类似列表。此方法常用于判断字典是否包含某个 key。
6:values()
:返回包含字典所有 value 的“列表”。
7、items()
:类似java中的map.entrySet()
,常用宇遍历字典。
6、关于集合(set
)
参考笔记二,P33.3。
6.1 概述
- 无重复值;
- 定义集合必须使用
set()
方法; - 构造有元素集合时,可以使用任意序列;
- 集合不能使用“
*
”或“连接”; - 集合常用宇数字意义上的集合操作,如:交集
&
、并集|
、对称差集^
,列表则不行。
示例:
s = set()
print(s)
print(type(s))
s1 = set((2, 0, 2, 3))
print(s1)
s2 = set(['c', 's', 'd', 'n'])
print(s2)
s3 = s1 & s2 # 返回两集合相同元素的集合
print(s3)
s3 = s1 | s2 # 返回两集合所有元素合集(若有相同元素,仅保留一个)
print(s3)
s3 = s1 - s2 # 等同于 s1 - (s1 & s2),即:返回s1去除s1与s2相同元素后的集合
print(s3)
s3 = s1 ^ s2 # 等同于 (s1 - s2) | (s2 - s1)
print(s3)
打印结果:
6.2 方法
摘要 | 参数说明 | 返回值类型/返回值 | 说明 |
---|---|---|---|
add(Object o) | 追加元素 | ||
remove(Object o) | 移除元素。若元素不存在,报错 |
7、关于变量
参考笔记二,P34.8。
7.1 分类
- 必须参数:指方法调用时必须指定的参数;(其实就如 java 中的实参,要求个数、类型对应)
- 关键字参数:指方法调用时通过
形参名=值
的方式指定实参,故可忽略实参顺序; - 默认参数:指方法定义时已指定默认值的参数,且必须定义在最后;(调用时可不指定)
- 可变参数:指不能在定义方法时确认参数的个数和内容(类型)所使用的参数;
- 组合参数。
7.2 可变参数
7.2.1 *args
格式
接收“序列”,相当于 java 中的可变参数,args
的类型是“元组”。
示例:
def show(*args):
for e in args:
print(e)
# 如 java 中的”xx...“,会将一组数自动封装成数组,在此处是序列
show(2023, 'csdn')
# java 中的可变参数也可这样定义实参,不过不允许直接这样初始化(也有点多此一举)
# 而在此处,尽管 [2023, 'csdn'] 是一个序列,但 args 仅将其视为一个元素,因此无法遍历(直接打印出“[2023, 'csdn']”)
show([2023, 'csdn'])
# (2023, ), ('csdn',)是两个元组,最后,args 会封装成 ((2023, ), ('csdn',))
show((2023, ), ('csdn',))
打印结果:
改进:(为调用show([2023, 'csdn'])
时,能遍历其内元素)
def show(*args):
for e in args:
if isinstance(e, list):
for i in e:
print(i)
else:
print(e)
打印结果:
7.2.2 **args
格式
表示“字典”(固定),实参必须是关键字参数(也可是字典,但需要使用**
标识,往下看)。
示例:
def show(**args):
# 因为 args 固定为字典,因此可调用成员方法 items()
for k,v in args.items():
print(k, v)
show(year=2023, flag='csdn')
打印结果:
7.2.3 特殊用法
(我暂且不知如何描述,看示例)
1、上述*args
的示例也可这样改:
l = [2023, 'csdn']
show(*l)
# 或:
show(*range(10))
即指明其是一个列表,这样*args
就不会将其视为一个元素。
总结:若实参是一组数,如:1, 2, 3
,则*args
可将其封装成元组;若实参为序列,如:{1, 2, 3}
、range(10)
,则*args
会将其视为一个元素或报错(此时就需采用此特殊用法)。
2、**args
的实参可使用字典,上述**args
的示例可这样改:
m = {
'year': 2023,
'flag': "csdn"
}
show(**m)
即指明其是一个字典。
注: 若*args
与**args
连用,也可使用此特殊用法进行指定。不过,顺序不可调换,使用关键字参数也不行。
8、关于lambda
表达式
参考笔记二,P34.10。
8.1 特点
- lambda 语句块只会执行一次,不存在被外部程序反复调用可能;
- 在某些函数必须使用函数作为参数,但是函数本身十分简单且只有一处使用。
8.1 用法1:简化函数
示例:
def calculate(x, y):
return x + y, x - y
t = calculate(10, 20)
lambda 改进:
f = lambda x, y: [x + y, x - y] # 相当于方法定义
print(type(f)) # 打印:<class 'function'>
t = f(10, 20)
(冒号):
左边是参数列表,右边是返回值。
9、关于面向对象
参考笔记二,P35.13、P36.1。
(注:以下阐述都基于类。)
1、构造方法__init__(self)
的返回值必须是None
,即无返回值,(指无返回值,并不是说需要手动指定return None
)
2、所有方法(除了静态方法、类方法)的第1个参数默认为self
,代指实例,可自定义名;
3、在所有方法中,由self
定义的变量都是成员变量;而直接定义的变量不是成员变量,仅是局部变量,其生命周期仅在函数内,在方法外定义的变量是类变量;
示例:
# 此示例中的3个 name 是3个变量,即3个定义,没有重赋值
class Platform:
name = 'csdn' # 定义类变量
def __init__(self, name):
self.name = 'bilibili' # 定义成员变量
self.name = name # 为成员变量 name 重赋值
# 这不是为类变量/成员变量 name 重赋值,而是定义局部变量
# 因此在此示例中,在类外无法访问
name = '博客园'
print(Platform.name) # 访问类变量,打印:csdn
# 实例化。实例化时,由于仅定义了一个带有一个参数的构造方法,因此需要指定一个实参
p1 = Platform("开源中国")
print(p1.name) # 访问成员变量,打印:开源中国
4、在变量前加__
(双下划线)表示私有变量。在 java 中,私有成员变量的作用域为当前类,而 python 中私有实例变量(即成员变量)的作用域为所有方法(因为第2点);
示例:
class Platform:
def __init__(self, name):
self.__name = name
def getName(self):
return self.__name
p1 = Platform('csdn')
print(p1.getName()) # 打印:csdn
5、在方法前加__
表示私有方法,私有方法只能在类内部调用,实例不能直接调用;(此性质与 java 相同)
示例:
class Platform:
def __init__(self, name):
self.__name = name
def __getName(self):
return self.__name
def toString(self):
print('name = ' + self.__getName())
p1 = Platform('csdn')
p1.toString() # 打印:name = csdn
6、实例无法修改类变量,若修改(赋值),则其实是创建一个同名的成员变量;
示例:
class Platform:
name = 'csdn'
def getName(self):
return self.name
p1 = Platform()
print(Platform.name) # 打印:csdn
print(p1.name) # 打印:csdn
r = p1.getName()
print(r) # 打印:csdn
# 从打印结果可看出,访问顺序是:成员变量 → 类变量
p1.name = 'bilibili'
print(Platform.name) # 打印:csdn
print(p1.name) # 打印:bilibili
r = p1.getName()
print(r) # 打印:bilibili
# 从打印结果可以看出,p1.name 不是访问类变量 name,而是定义成员变量 name
7、在类内,修改类变量的方法只有3种:1、重新定义;2、通过类名调用;3、在类方法内通过cls
调用,因此总结第6点;
8、静态方法的定义是在def
前添加@staticmethod
,其作用是用于存放逻辑性代码,这些逻辑和类本身没有实际性的交互,即不涉及方法和属性的操作;静态方法不绑定类也不绑定实例,相当于给方法添加了一个前缀;(暂且不知静态方法具体的作用,其调用方式与类方法相同)
9、类方法的定义是在def
前添加@classmethod
,第1个参数默认为cls
,代指类本身,可自定义名。
示例:
class Platform:
name = 'csdn'
@classmethod
def setName(cls, name):
cls.name = name
print(Platform.name) # 打印:csdn
Platform.setName('bilibili')
print(Platform.name) # 打印:bilibili
10、关于异常处理
参考笔记二,P36.4/5。
对于基础的异常处理,比较简单,看示例。
示例:
class DigiProcess:
def checkZero1(self, n):
try:
x = n / 0
except Exception as e:
print(e)
finally:
print("error")
def checkZero2(self, n):
try:
x = n / 0
except Exception as e:
raise Exception("divide zero")
d = DigiProcess()
d.checkZero1(2023)
try:
d.checkZero2(2023)
except Exception as e:
print(e)
打印结果:
11、关于模块
参考笔记二,P36.6/7。
指可反复使用(调用)的源代码文件。
导入方式:
1、import 文件名
2、from 文件名 import xx
注:xx 是代码块名,如:方法名、类名。
示例:(将第10项的示例作为模块,其全限定名是test.T1
。此示例在另一个文件中)
from test.T1 import DigiProcess
d = DigiProcess()
d.checkZero1(2023)
可用__name__
测试,_-name__
用于获取当前模块名。如果与当前文件名相同,说明是被导入模块;如果结果是__main__
,说明是当前运行文件。
12、关于标准库
参考笔记二,P37.1、P42.3、P51.2。
12.1 sys
库
1、sys.platform # 识别操作系统
2、sys.argv # 获取命令行参数,见第1.2项
# x 是可选参数,此参数会成为返回值,用于捕获 sys.exit() 的调用情况,
# 0-正常退出,其他为异常
3、sys.exit(x) # 退出程序
# 所谓模块搜索路径,即导入模块(import)时,搜索模块的位置与顺序
# 返回一个列表,故可自行添加搜索路径
4、sys.path # 获取模块搜索路径
# 在首次运行时,会将模块信息导入其中,
# 再次启动时从中获取模块信息,以加快运行速度
5、sys.modules # 获取模块“缓存”(字典)
模板搜索顺序:(补充)
- 当前目录;
- shell 变量
pythonpath
对应目录; - 默认目录(项目目录)。
12.2 os
库
1、os.path.dirname(__file__) # 获取文件目录,__file__ 是当前文件的绝对路径
2、os.getCwd() # 获取当前路径
os.chdir(str) # 切换当前路径
3、os.rename(a, b) # 重命名文件,a、b 是文件绝对路径
4、os.path.exists() # 判断文件/目录是否存在
5、os.path.isfile() # 判断是否是文件
6、os.path.isdir() # 判断是否是目录
7、os.environ # 获取系统环境变量
8、os.mkdir() # 创建单层目录
9、os.makedirs() # 创建多层目录
12.3 math
库
# 常数
1、math.pi # 圆周率
2、math.e # 自然常数
# 运算函数
1、math.ceil(number) # 向上取整
2、math.floor(number) # 向下取整
3、math.pow(number, number) # 指数运算
4、math.log(对数, [底数]) # 对数计算,底数默认为 e
5、math.sqrt(number) # 平方根
# 三角函数:与 java 中相同
# 角度与弧度换算
1、math.degrees(number) # 弧度 → 角度
2、math.radians(number) # 角度 → 弧度
此库中的很多函数与Math类中的很多方法相似/相同。
12.4 random
库
1、random.random() # 生成 0 ~ 1 一个浮点数
2、random.uniform(min, max) # 生成一个指定范围的浮点数
3、random.randint(min, max) # 生成一个指定范围的整数
4、random.choice(序列) # 获取序列一个元素
5、random.shuffle(list) # 打乱列表
13、关于实例创建
参考笔记二,P42.1。
__new__(cls)
是静态方法,就底层而言,其实它才是创建实例的方法,即构造方法。而__init__(self)
的作用仅是为实例进行初始化,即为属性赋值。故前者在后者之前被调用,只有当前者返回cls
实例时,后者才会被调用。
因此,底层创建实例的过程是:将__new__(cls)
创建后返回的实例cls
传入__init__(self)
进行初始化。
若想测试此过程,可重写这2个方法:
class Platform:
def __new__(cls, *args, **kwargs):
print(cls)
return cls
def __init__(self):
print(self)
c1 = Platform() # 打印:<class '__main__.Platform'>
c1.__init__(c1) # 打印:<class '__main__.Platform'>
当调用Platform()
实例化时,底层调用了__new__()
,返回实例cls
,然后手动传入__init__()
进行初始化。(当然这个示例的证明效力有点不够,大家对这个知识点先有个了解就行)
最后
本文中的举例是为了方便大家理解、以及阐述相关知识点而简单举出的,不一定有实用性,也不一定有针对性,比如:集合运算&
,目的是获取两集合相同元素,而第6.1项的示例中我没有刻意去定义s1
、s2
包含了相同元素。我之所以如此:
- 这些细节很简单,大家在其他编程语言或课程、书本或资料上肯定或多或少接触过或完全知道,因此没必要特意举例;
- 本文阐述的宗旨是“阐明使用细节”,而对于其他附属知识并不一定会细致说明。
因此,一些细节需要大家自行测试或查找资料。
本文持续更新中。。。