Python的常用小知识
文章转载自:https://fishc.com.cn/forum.php?mod=forumdisplay&fid=243&filter=typeid&typeid=403
1. 字符串的方法及注释
方法名 | 作用 |
---|
capitalize() | 把字符串的第一个字符改为大写 |
casefold() | 把整个字符串的所有字符改为小写 |
center(width) | 将字符串居中,并使用空格填充至长度 width 的新字符串 |
count(sub[, start[, end]]) | 返回 sub 在字符串里边出现的次数,start 和 end 参数表示范围,可选。 |
encode(encoding=‘utf-8’, errors=‘strict’) | 以 encoding 指定的编码格式对字符串进行编码。 |
endswith(sub[, start[, end]]) | 检查字符串是否以 sub 子字符串结束,如果是返回 True,否则返回 False。start 和 end 参数表示范围,可选。 |
expandtabs([tabsize=8]) | 把字符串中的 tab 符号(\t)转换为空格,如不指定参数,默认的空格数是 tabsize=8。 |
find(sub[, start[, end]]) | 检测 sub 是否包含在字符串中,如果有则返回索引值,否则返回 -1,start 和 end 参数表示范围,可选。 |
index(sub[, start[, end]]) | 跟 find 方法一样,不过如果 sub 不在 string 中会产生一个异常。 |
isalnum() | 如果字符串至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False。 |
isalpha() | 如果字符串至少有一个字符并且所有字符都是字母则返回 True,否则返回 False。 |
isdecimal() | 如果字符串只包含十进制数字则返回 True,否则返回 False。 |
isdigit() | 如果字符串只包含数字则返回 True,否则返回 False。 |
islower() | 如果字符串中至少包含一个区分大小写的字符,并且这些字符都是小写,则返回 True,否则返回 |
isnumeric() | 如果字符串中只包含数字字符,则返回 True,否则返回 False。 |
isspace() | 如果字符串中只包含空格,则返回 True,否则返回 False。 |
istitle() | 如果字符串是标题化(所有的单词都是以大写开始,其余字母均小写),则返回 True,否则返回 False。 |
isupper() | 如果字符串中至少包含一个区分大小写的字符,并且这些字符都是大写,则返回 True,否则返回 False。 |
join(sub) | 以字符串作为分隔符,插入到 sub 中所有的字符之间。 |
ljust(width) | 返回一个左对齐的字符串,并使用空格填充至长度为 width 的新字符串。 |
lower() | 转换字符串中所有大写字符为小写。 |
lstrip() | 去掉字符串左边的所有空格 |
partition(sub) | 找到子字符串 sub,把字符串分成一个 3 元组 (pre_sub, sub, fol_sub),如果字符串中不包含 sub 则返回 (‘原字符串’, ‘’, ‘’) |
replace(old, new[, count]) | 把字符串中的 old 子字符串替换成 new 子字符串,如果 count 指定,则替换不超过 count 次。 |
rfind(sub[, start[, end]]) | 类似于 find() 方法,不过是从右边开始查找。 |
rindex(sub[, start[, end]]) | 类似于 index() 方法,不过是从右边开始。 |
rjust(width) | 返回一个右对齐的字符串,并使用空格填充至长度为 width 的新字符串。 |
rpartition(sub) | 类似于 partition() 方法,不过是从右边开始查找。 |
rstrip() | 删除字符串末尾的空格。 |
split(sep=None, maxsplit=-1) | 不带参数默认是以空格为分隔符切片字符串,如果 maxsplit 参数有设置,则仅分隔 maxsplit 个子字符串,返回切片后的子字符串拼接的列表。 |
splitlines(([keepends])) | 在输出结果里是否去掉换行符,默认为 False,不包含换行符;如果为 True,则保留换行符。。 |
startswith(prefix[, start[, end]]) | |
strip([chars]) | 删除字符串前边和后边所有的空格,chars 参数可以定制删除的字符,可选。 |
swapcase() | 翻转字符串中的大小写。 |
title() | 返回标题化(所有的单词都是以大写开始,其余字母均小写)的字符串。 |
translate(table) | 根据 table 的规则(可以由 str.maketrans(‘a’, ‘b’) 定制)转换字符串中的字符。 |
upper() | 转换字符串中的所有小写字符为大写。 |
zfill(width) | 返回长度为 width 的字符串,原字符串右对齐,前边用 0 填充。 |
2. 游戏中的角色移动:闭包(closure)在实际开发中的作用
- 在某种情况下,我们并不方便使用全局变量,所以灵活的使用闭包可以实现替代全局变量。
例如以下的游戏开发中,我们需要将游戏中角色的移动位置保护起来,不希望被其他函数轻易可以修改到,所以我们选择使用闭包操作,参考代码及注释如下:
origin = (0, 0)
legal_x = [-100, 100]
legal_y = [-100, 100]
def create(pos_x=0, pos_y=0):
def moving(direction, step):
nonlocal pos_x, pos_y
new_x = pos_x + direction[0] * step
new_y = pos_y + direction[1] * step
if new_x < legal_x[0]:
pos_x = legal_x[0] - (new_x - legal_x[0])
elif new_x > legal_x[1]:
pos_x = legal_x[1] - (new_x - legal_x[1])
else:
pos_x = new_x
if new_y < legal_y[0]:
pos_y = legal_y[0] - (new_y - legal_y[0])
elif new_y > legal_y[1]:
pos_y = legal_y[1] - (new_y - legal_y[1])
else:
pos_y = new_y
return pos_x, pos_y
return moving
move = create()
print('向右移动10步后,位置是:', move([1, 0], 10))
print('向上移动130步后,位置是:', move([0, 1], 130))
print('向左移动10步后,位置是:', move([-1, 0], 10))
3. Python 的字典(Dict)是如何存储的?
Python 的字典有好多个名称(“映射”、“哈希”、“散列"或者"关系数组”),那你知道为什么字典会被称为 Hash(翻译为"哈希"或"散列")吗?
你知道为什么字典对于键(Key)的存储数据要求比较严格,但对于对应的值(Value)的存储却要求很宽松吗?
读完这篇文章,你将深刻理解这些问题背后的真相!
首先我们来解释一下什么是 Hash,来自维基百科:
3.1 什么是Hash?
散列函数(或散列算法,又称哈希函数,英语:Hash Function)是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值的指纹。散列值通常用来代表一个短的随机字母和数字组成的字符串。好的散列函数在输入域中很少出现散列冲突。在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到。
3.2 Python 的字典(Dict)是如何存储的?
世界上没有两片完全相同的树叶,也没有两个相同的指纹,散列函数是用于从数据中创建小的数字指纹的方法。
我们看下图示:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d965aff97046fb18263bfae22316f8f3.png)
如图,Python 调用内部的散列函数,将键(Key)作为参数进行转换,得到一个唯一的地址(这也就解释了为什么给相同的键赋值会直接覆盖的原因,因为相同的键转换后的地址是一样滴),然后将值(Value)存放到该地址中。
对于 Python 来说,键(Key)必须是可哈希的,换句话说就是要可以通过散列函数计算出唯一地址的。那如果拿一个变量当键(Key)可以吗?肯定不行。因为变量随时都可能改变,不符合可哈希原则!
同样的,列表、字典、集合这些都是可变的,所以都不能做为键(Key)来使用。
那有朋友可能会问,那元祖呢?元祖总该是不变的吧?
其实不然,因为元祖里边可以存放列表这类可变因素,所以如果实在想拿元祖当字典的键(Key),那必须对元祖做限制:元组中只包括像数字和字符串这样的不可变元素时,才可以作为字典中有效的键(Key)。
另外还需要注意的一点是,Python 的哈希算法对相同的值计算得到的结果是一样的,也就是说 12315 和 12315.0 的值相同,他们被认为是相同的键(Key)。
4. 文件的打开模式和文件对象方法
4.1 文件打开模式
打开模式 | 执行操作 |
---|
‘r’ | 以只读方式打开文件(默认) |
‘w’ | 以写入的方式打开文件,会覆盖已存在的文件 |
‘x’ | 如果文件已经存在,使用此模式打开将引发异常 |
‘a’ | 以写入模式打开,如果文件存在,则在末尾追加写入 |
‘b’ | 以二进制模式打开文件 |
‘t’ | 以文本模式打开(默认) |
‘+’ | 可读写模式(可添加到其他模式中使用) |
‘U’ | 通用换行符支持 |
4.2 文件对象方法
文件对象方法 | 执行操作 |
---|
f.close() | 关闭文件 |
f.read([size=-1]) | 从文件读取size个字符,当未给定size或给定负值的时候,读取剩余的所有字符,然后作为字符串返回 |
f.readline([size=-1]) | 从文件中读取并返回一行(包括行结束符),如果有size有定义则返回size个字符 |
f.write(str) | 将字符串str写入文件 |
f.writelines(seq) | 向文件写入字符串序列seq,seq应该是一个返回字符串的可迭代对象 |
f.seek(offset, from) | 在文件中移动文件指针,从from(0代表文件起始位置,1代表当前位置,2代表文件末尾)偏移offset个字节 |
f.tell() | 返回当前在文件中的位置 |
f.truncate([size=file.tell()]) | 截取文件到size个字节,默认是截取到文件指针当前位置 |
5. os、os.path 模块中关于文件、目录常用的函数使用方法
5.1 os模块中关于文件/目录常用的函数使用方法
函数名 | 使用方法 |
---|
getcwd() | 返回当前工作目录 |
chdir(path) | 改变工作目录 |
listdir(path=’.’) | 列举指定目录中的文件名(’.‘表示当前目录,’…'表示上一级目录) |
mkdir(path) | 创建单层目录,如该目录已存在抛出异常 |
makedirs(path) | 递归创建多层目录,如该目录已存在抛出异常,注意:'E:\a\b’和’E:\a\c’并不会冲突 |
remove(path) | 删除文件 |
rmdir(path) | 删除单层目录,如该目录非空则抛出异常 |
removedirs(path) | 递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常 |
rename(old, new) | 将文件old重命名为new |
system(command) | 运行系统的shell命令 |
walk(top) | 遍历top路径以下所有的子目录,返回一个三元组:(路径, [包含目录], [包含文件]) |
以下是支持路径操作中常用到的一些定义,支持所有平台
| |
---|
os.curdir | 指代当前目录(’.’) |
os.pardir | 指代上一级目录(’…’) |
os.sep | 输出操作系统特定的路径分隔符(Win下为’\’,Linux下为’/’) |
os.linesep | 当前平台使用的行终止符(Win下为’\r\n’,Linux下为’\n’) |
os.name | 指代当前使用的操作系统(包括:‘posix’, ‘nt’, ‘mac’, ‘os2’, ‘ce’, ‘java’) |
5.2 os.path模块中关于路径常用的函数使用方法
函数名 | 使用方法 |
---|
basename(path) | 去掉目录路径,单独返回文件名 |
dirname(path) | 去掉文件名,单独返回目录路径 |
join(path1[, path2[, …]]) | 将path1, path2各部分组合成一个路径名 |
split(path) | 分割文件名与路径,返回(f_path, f_name)元组。如果完全使用目录,它也会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在 |
splitext(path) | 分离文件名与扩展名,返回(f_name, f_extension)元组 |
getsize(file) | 返回指定文件的尺寸,单位是字节 |
getatime(file) | 返回指定文件最近的访问时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算) |
getctime(file) | 返回指定文件的创建时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算) |
getmtime(file) | 返回指定文件最新的修改时间(浮点型秒数,可用time模块的gmtime()或localtime()函数换算) |
以下为函数返回 True 或 False
| |
---|
exists(path) | 判断指定路径(目录或文件)是否存在 |
isabs(path) | 判断指定路径是否为绝对路径 |
isdir(path) | 判断指定路径是否存在且是一个目录 |
isfile(path) | 判断指定路径是否存在且是一个文件 |
islink(path) | 判断指定路径是否存在且是一个符号链接 |
ismount(path) | 判断指定路径是否存在且是一个挂载点 |
samefile(path1, paht2) | 判断path1和path2两个路径是否指向同一个文件 |
6. Python标准异常总结
异常 | 说明 |
---|
AssertionError | 断言语句(assert)失败 |
AttributeError | 尝试访问未知的对象属性 |
EOFError | 用户输入文件末尾标志EOF(Ctrl+d) |
FloatingPointError | 浮点计算错误 |
GeneratorExit | generator.close()方法被调用的时候 |
ImportError | 导入模块失败的时候 |
IndexError | 索引超出序列的范围 |
KeyError | 字典中查找一个不存在的关键字 |
KeyboardInterrupt | 用户输入中断键(Ctrl+c) |
MemoryError | 内存溢出(可通过删除对象释放内存) |
NameError | 尝试访问一个不存在的变量 |
NotImplementedError | 尚未实现的方法 |
OSError | 操作系统产生的异常(例如打开一个不存在的文件) |
OverflowError | 数值运算超出最大限制 |
ReferenceError | 弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象 |
RuntimeError | 一般的运行时错误 |
StopIteration | 迭代器没有更多的值 |
SyntaxError | Python的语法错误 |
IndentationError | 缩进错误 |
TabError | Tab和空格混合使用 |
SystemError | Python编译器系统错误 |
SystemExit | Python编译器进程被关闭 |
TypeError | 不同类型间的无效操作 |
UnboundLocalError | 访问一个未初始化的本地变量(NameError的子类) |
UnicodeError | Unicode相关的错误(ValueError的子类) |
UnicodeEncodeError | Unicode编码时的错误(UnicodeError的子类) |
UnicodeDecodeError | Unicode解码时的错误(UnicodeError的子类) |
UnicodeTranslateError | Unicode转换时的错误(UnicodeError的子类) |
ValueError | 传入无效的参数 |
ZeroDivisionError | 除数为零 |
Python 内置异常类的层次结构:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
7. Python魔法方法详解
7.1 基本的魔法方法
魔法方法 | 含义 |
---|
_new(cls[, …]) | 1. new 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 init 方法 3. new 决定是否要使用该 init 方法,因为 new 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果 new 没有返回实例对象,则 init 不会被调用 4.new 主要是用于继承一个不可变的类型比如一个 tuple 或者 string |
_init(self[, …]) | 构造器,当一个实例被创建的时候调用的初始化方法 |
_del(self) | 析构器,当一个实例被销毁的时候调用的方法 |
_call(self[, args…]) | 允许一个类的实例像函数一样被调用:x(a, b) 调用 x.call(a, b) |
_len(self) | 定义当被 len() 调用时的行为 |
_repr(self) | 定义当被 repr() 调用时的行为 |
_str(self) | 定义当被 str() 调用时的行为 |
_bytes(self) | 定义当被 bytes() 调用时的行为 |
_hash(self) | 定义当被 hash() 调用时的行为 |
_bool(self) | 定义当被 bool() 调用时的行为,应该返回 True 或 False |
_format(self, format_spec) | 定义当被 format() 调用时的行为 |
7.2 有关属性
魔法方法 | 含义 |
---|
_getattr(self, name) | 定义当用户试图获取一个不存在的属性时的行为 |
_getattribute(self, name) | 定义当该类的属性被访问时的行为 |
_setattr(self, name, value) | 定义当一个属性被设置时的行为 |
_delattr(self, name) | 定义当一个属性被删除时的行为 |
_dir(self) | 定义当 dir() 被调用时的行为 |
_get(self, instance, owner | ) 定义当描述符的值被取得时的行为 |
_set(self, instance, value) | 定义当描述符的值被改变时的行为 |
_delete(self, instance) | 定义当描述符的值被删除时的行为 |
7.3 比较操作符
魔法方法 | 含义 |
---|
_lt(self, other) | 定义小于号的行为:x < y 调用 x.lt(y) |
_le(self, other) | 定义小于等于号的行为:x <= y 调用 x.le(y) |
_eq(self, other) | 定义等于号的行为:x == y 调用 x.eq(y) |
_ne(self, other) | 定义不等号的行为:x != y 调用 x.ne(y) |
_gt(self, other) | 定义大于号的行为:x > y 调用 x.gt(y) |
_ge(self, other) | 定义大于等于号的行为:x >= y 调用 x.ge(y) |
7.4 算数运算符
魔法方法 | 含义 |
---|
_add(self, other) | 定义加法的行为:+ |
_sub(self, other) | 定义减法的行为:- |
_mul(self, other) | 定义乘法的行为:* |
_truediv(self, other) | 定义真除法的行为:/ |
_floordiv(self, other) | 定义整数除法的行为:// |
_mod(self, other) | 定义取模算法的行为:% |
_divmod(self, other) | 定义当被 divmod() 调用时的行为 |
_pow(self, other[, modulo]) | 定义当被 power() 调用或 ** 运算时的行为 |
_lshift(self, other) | 定义按位左移位的行为:<< |
_rshift(self, other) | 定义按位右移位的行为:>> |
_and(self, other) | 定义按位与操作的行为:& |
_xor(self, other) | 定义按位异或操作的行为:^ |
_or(self, other) | 定义按位或操作的行为: |
7.5 反运算
魔法方法 | 含义 |
---|
_radd(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rsub(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rmul(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rtruediv(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rfloordiv(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rmod(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rdivmod(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rpow(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rlshift(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rrshift(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rand(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_rxor(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
_ror(self, other) | (与上方相同,当左操作数不支持相应的操作时被调用) |
7.6 增量赋值运算
魔法方法 | 含义 |
---|
_iadd(self, other) | 定义赋值加法的行为:+= |
_isub(self, other) | 定义赋值减法的行为:-= |
_imul(self, other) | 定义赋值乘法的行为:*= |
_itruediv(self, other) | 定义赋值真除法的行为:/= |
_ifloordiv(self, other) | 定义赋值整数除法的行为://= |
_imod(self, other) | 定义赋值取模算法的行为:%= |
_ipow(self, other[, modulo]) | 定义赋值幂运算的行为:**= |
_ilshift(self, other) | 定义赋值按位左移位的行为:<<= |
_irshift(self, other) | 定义赋值按位右移位的行为:>>= |
_iand(self, other) | 定义赋值按位与操作的行为:&= |
_ixor(self, other) | 定义赋值按位异或操作的行为:^= |
_ior(self, other) | 定义赋值按位或操作的行为: |
7.7 一元操作符
魔法方法 | 含义 |
---|
_pos(self) | 定义正号的行为:+x |
_neg(self) | 定义负号的行为:-x |
_abs(self) | 定义当被 abs() 调用时的行为 |
_invert(self) | 定义按位求反的行为:~x |
7.8 类型转换
魔法方法 | 含义 |
---|
_complex(self) | 定义当被 complex() 调用时的行为(需要返回恰当的值) |
_int(self) | 定义当被 int() 调用时的行为(需要返回恰当的值) |
_float(self) | 定义当被 float() 调用时的行为(需要返回恰当的值) |
_round(self[, n]) | 定义当被 round() 调用时的行为(需要返回恰当的值) |
_index(self) | 1. 当对象是被应用在切片表达式中时,实现整形强制转换 2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 index 3. 如果 index 被定义,则 int 也需要被定义,且返回相同的值 |
7.9 上下文管理(with 语句)
魔法方法 | 含义 |
---|
_enter(self) | 1. 定义当使用 with 语句时的初始化行为 2. enter 的返回值被 with 语句的目标或者 as 后的名字绑定 |
_exit(self, exc_type, exc_value, traceback) | 1. 定义当一个代码块被执行或者终止后上下文管理器应该做什么 2. 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作 |
7.10 容器类型
魔法方法 | 含义 |
---|
_len(self) | 定义当被 len() 调用时的行为(返回容器中元素的个数) |
_getitem(self, key) | 定义获取容器中指定元素的行为,相当于 self[key] |
_setitem(self, key, value) | 定义设置容器中指定元素的行为,相当于 self[key] = value |
_delitem(self, key) | 定义删除容器中指定元素的行为,相当于 del self[key] |
_iter(self) | 定义当迭代容器中的元素的行为 |
_reversed(self) | 定义当被 reversed() 调用时的行为 |
_contains(self, item) | 定义当使用成员测试运算符(in 或 not in)时的行为 |