python

Python基础

Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。

注释

注释使用井号和三引号。

1
2
3
4
5
6
7
'''
多行注释用仨引号。
'''
"""
仨双引号也行。
"""
# 等等,要是连这句都注释了,代码块里不就什么都没有了?

print可以接受多个字符串,用逗号分割,输出会加空格。

1
print("hello", "world")

还可以输出数字,表达式。

1
print("1+1=", 1 + 1)

格式化输出:

1
print("num = %d" % (num))

生输出:

1
2
3
print('''hello
world''')
print(r'\t\t\t')

input用于输入值到变量。输入的结果是字符串。

1
age =input("请输入年龄:")

变量和常量

Python的关键字有:

1
2
import keyword
print(keyword.kwlist)
1
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

变量不需要声明类型,初始化时确定类型。使用变量前必须定义。

1
2
3
tmp = 10
num2 = num1 = 10
num3, num4 = 3, 4

删除变量使用del。

1
del tmp

type用于查看变量的类型。

1
2
3
print(type(10))  # <class 'int'>
print(type(10.5)) # <class 'float'>
print(type("10")) # <class 'str'>

id用于查看变量的地址。

运算符

1
2
3
4
5
6
7
算术运算符:加+ 减- 乘* 除/ 取余% 求幂** 除取整//
赋值运算符:= += -= ...
关系运算符:== != > < >= <=
位运算符:& | ^ ~ << >>
逻辑运算符:and or not
成员运算符:判断是否在列表中in not in
身份运算符:判断两个标识符是否引用同一个对象is is not

程序流程语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if 表达式:
语句
elif 表达式:
语句
else:
语句

while 表达式:
语句
else:
语句

for e in v: #可以搭配range([start], end, [step])
语句

for i, e in enumerate(v):
语句:

数学函数

  • abs()绝对值
  • max()最大值
  • min()最小值
  • pow()求幂
  • round()四舍五入
  • sum()求和
  • divmod()求商和余数
  • math.ceil()向上取整
  • math.floor()向下取整
  • math.modf()返回(小数、整数)元组
  • math.sqrt()开方
  • random.choice()输入列表,随机选择
    • random.choice(range(5))可以从[0, 1, 2, 3, 4]中选取
    • random.choice(“hello”)从字符串中选取字符
  • random.randrange([start], end, [step])在[start, end)内按步进随机生成数字
  • random.randint(0, 2)生成0、1、2中的随机数
  • random.random()生成[0,1)的浮点数
  • random.shuffle()给列表乱序
  • random.uniform()均匀分布

内置函数

  • filter(function, iterable):返回iterable的一个迭代器,其迭代满足断言function的元素
  • map(fun, l):执行fun(l)
  • reduce(function, iterable[, initializer]):用function对iterable进行累加。
  • enumerate(sequence, [start=0]):为序列附加索引。一般用于迭代。
  • iter():获取迭代器。
  • next():迭代。

数据类型

数据类型包括Number(数字)、String(字符串)、Boolean(布尔)、None(空)、list(列表)、tuple(元祖)、dict(字典)、set(集合)

字符串

字符串是不可变的文本。

字符串相关函数

  • 字符串拼接:+
  • 重复字符串:*
  • 通过索引查找字符:[]
    • 不能通过索引更改字符串
  • 截取字符串:[start:end]
  • 最大字符:max()
  • 最小字符:min()
  • 是否包含字符串:in和not in
  • 将字符串视为表达式执行eval()
  • 字符转ASCII:ord()
  • ASCII转字符:chr()

字符串方法

  • 字符个数:len()
  • 转小写:lower()
  • 转大写:upper()
  • 切换大小写:swapcase()
  • 句首字母大写:capitalize()
  • 单词首字母大写:title()
  • 居中,两边填充字符:center(width, [fillchar])
  • 左对齐,填充字符:ljust(width, [fillchar])
  • 右对齐,填充字符:rjust(width, [fillchar])
  • 右对齐,填充0:zfill(width)
  • 查找次数:count(str, [start], [end])
  • 查找位置,返回第一次出现的位置,没有返回-1:find(str, [start], [end])
  • 查找位置,从右至左:rfind(str, [start], [end])
  • 查找位置,没有查到抛异常:index(str, [start], [end])
  • rindex(str, [start], [end])
  • lstrip([char]):去掉左侧的字符,默认空格
  • rstrip([char]):去掉右侧的字符,默认空格
  • strip([char]):去掉两侧的字符,默认空格
  • split(str, [times]):以str为分割截取字符串
  • splitlines([keepends]):按\r \r\n \n分割,传入True保留换行符
  • partition(str):find()和 split()的结合体,从str出现的第一个位置起,分成3元素的元组
  • join(list):组合为字符串
  • replace(str1, str2, [times]):替换字符串
  • maketrans(str1, str2)创建字符映射表,将str1中的每个字符映射到str2中的对应字符去
    • translate(dic)用字符串映射表替换字符串
  • startswith(str, [start], [end])是否以str开头
  • endswith(str, [start], [end])
  • encode(encoding=”utf-8”, errors=”strict”)编码,strict=”ignore”表示忽略错误
    • bytes.decode(encoding=”utf-8”, errors=”strict”)
  • isalpha()字母非空串
  • isdigit()数字非空串
  • isalnum()字母数字非空串
  • isupper()有字母,所有字母都是大写的
  • islower()
  • istitle()首字母是大写的
  • isspace()是否是空白字符

列表

1
2
list1 = [1, 2, 3]
matrix1 = [[1, 0], [0, 1]]
  • 访问列表:[i]

  • 列表合并:+

  • 列表重复:*

  • 判断元素是否在列表中:in和not in

  • 列表截取:[m:n]

  • 列表长度:len()

  • 最大元素:max()

  • 最小元素:min()

  • 浅拷贝:=

  • 转列表:list()

  • append(ele):末尾追加元素

  • extend(list):追加列表中的元素

  • insert(index, ele):在下标插入元素

  • pop([index]):删除并返回元素,默认末尾

  • remove(ele):移除第一个匹配的元素

  • clear():清除全部元素

  • index(ele, [start], [end]):查找并返回索引

  • count(ele, [start], [end]):计数

  • reverse():倒序

  • sort():升序排序

  • copy():拷贝

元组

元组是不可变的列表

1
2
3
tuple1 = ()
tuple2 = (1, )
tuple3 = (1, "wow", True)
  • 访问元组:[i]
  • 元组合并:+
  • 元组重复:*
  • 判断元素是否在元组中:in和not in
  • 元组截取:[m:n]
  • 列表长度:len()
  • 最大元素:max()
  • 最小元素:min()
  • 浅拷贝:=
  • 转元组:tuple()

字典

字典是使用键值对的无序存储格式。字典中的键必须唯一,必须为不可变对象。

1
dict1 = {"Steve":60, "Alex": 70}
  • 字典元素的访问:dict[key]
  • 遍历
    • for k in dict1:
    • for v in dict1.values(): #返回值构成的列表
    • for k, v in dict1.items(): #返回以键值对元组为元素的列表
    • for i, k in enumerate(dict1)
  • get(key):取值,如果没有键返回None
  • pop(key):删除
  • sort(key):按key升序排序

集合

无序无重复集合,类似于字典,但是只存储key,因此不能存储可变对象。

创建集合需要列表、元组或字典作为输入。

1
2
s = set([1, 2, 3])
s = {1, 2, 3}
  • add(e)
  • update(list):把列表等的元素插入到集合中。
  • remove(e)
  • 遍历
    • for e in set:
    • for i, e in enumerate(set):
  • 交集:&
  • 并集:|
  • 差集:-

迭代器

1
2
from collections.abc import Iterable
from collections.abc import Iterator

可迭代对象可以直接在for循环中作用,包括集合类和generator,包括生成器和带yield的函数。可以用isinstance(o, Iterable)判断对象是否可迭代。

迭代器除了for循环,还可以通过不断使用next()来取得下一个值,直到抛出StopIteration。可以用isinstance(o, Iterator)判断对象是否是迭代器。

1
2
it = (x for x in range(10))
n = next(it)

转成迭代器使用iter(object, [sentinel])。

1
it = iter([1, 2, 3, 4])

如果iter()有两个参数,则第一个参数必须是可调用对象,如函数。直到返回了sentinel,此时给出StopIteration。

1
2
3
4
endstr = "quit"
s = ""
for line in iter(input, endstr):
s += line + "\n"

函数

函数基础

1
2
3
def 函数名(参数表列):
语句
return 表达式

不可变类型在传递中是按值传递,可变类型在传递中是按引用传递。

在调用时,可以按顺序传入参数,也可以使用关键词参数。

1
fun(s="hello", n=18)

传递参数时,如果没有这个参数,则使用默认参数。默认参数需要在所有参数表列之后。

1
2
def fun(s, n=10):
pass

不定长参数可以接收更多参数,没有名字的参数会被封到一个元组里,有名字的参数会被封装到一个字典里。

1
2
def fun(s, *args, **kwargs):
pass

匿名函数使用lambda创建。lambda只是一个表达式,有独立的命名空间,不能访问自由参数列表之外或全局命名空间的参数。

1
fun = lambda 参数表列 : 表达式

装饰器

是一个闭包,是以函数为参数和返回值的函数。

1
2
3
4
5
def checkPositive(f):
def newf(n):
print("函数被调用了")
f()
return newf

可以直接在被装饰的函数前使用@来引导装饰器。

1
2
3
4
5
6
7
8
9
10
11
def checkPositive(f):
def newf(n):
if n > 0:
f(n)
else:
print("n必须为正数")
return newf

@checkPositive
def printAge(n):
print("今年%d岁了" % (n))

配合不定长参数的话,装饰器就可以更加通用了。

nonlocal声明变量要求使用外部的局部变量。

偏函数

有时候我们希望固定函数的某个参数

1
2
def int2(s, base=2)
return int(s, base)

其实只需要这样就好:

1
2
import functools
int2 = functools.partial(int, base=2)

异常处理

异常捕获的格式:

1
2
3
4
5
try:
except: 错误码 as e:
except: (错误码列):
except:
else:
1
2
3
try:
except:
finally:

可以用断言预先判断,如果判断为假则引发异常:

1
2
3
assert (divisor != 0), "除数不能为零"
#发生异常: AssertionError
#除数不能为零

文件读写

文件操作

Python中的文件读写和C是兼容的。Python通过文件操作符对文件进行操作。

1
2
f = open(path, flag, [encoding], [errors])
f.close()

打开方式:

  • r 只读,文件描述符位于开头
  • rb 二进制只读
  • r+ 读写
  • w 只写,文件已经存在则覆盖
  • wb 二进制只写
  • w+ 读写
  • a 追加,文件描述符位于末尾
  • a+ 读写

读取方式:

  • f.read():读取全部内容
  • f.read(n):读取指定字符数
  • f.readline():读取一行,包括换行符
  • f.readline(n):读取一行中指定字符数
  • f.readlines():读取所有行,返回列表
  • f.readlines(n):读取指定字符数所在的行
  • f.seek():修改文件描述符的位置
1
2
3
4
5
6
try:
f = open(path, "r")
print(f.read())
finally:
if f:
f.close()

有简化写法,可以自动关闭文件。

1
2
with open(path, "r") as f:
print(f.read())

写文件时,文件进入缓冲区,刷新时才与硬盘交互。

  • f.write(s):写入文件
  • f.flush():刷新缓冲区
1
2
with open(path, "r") as f:
f.write("hello world!")

pickle

容器的读写需要pickle模块。

1
import pickle
  • pickle.dump(c, f):写文件
  • c = pickle.load(f):读文件

JSON

1
2
3
import json
j = json.dumps(obj)
o = json.load(j)

模块

一个py文件可以理解为一个模块,一个文件夹可以理解为一个包,包里会有__init__.py

导入模块:

1
2
3
4
5
6
7
8
import ModName
from ModName import memName
from ModName import *
import ModName as NickName
from ModName import memName as nickName

from packName import ModName
from packName.ModName import memName

os模块

os模块包含了普遍的操作系统的功能。

  • os.name:获取操作系统类型,nt是windows,posix是Linux等
  • os.environ:环境变量
  • os.environ.get(key):获取指定环境变量
  • os.curdir:当前目录
  • os.getcwd():当前工作目录,即脚本所在的目录
  • os.listdir(path):返回指定目录下的所有文件列表
  • os.chdir():更改当前工作目录
  • os.mkdir(path):创建目录
  • os.rmdir(path):删除目录
  • os.stat(path):获取文件属性
  • os.rename(path1, path2):重命名
  • os.remove(path):删除文件
  • os.system(cmd):运行命令
  • os.path.abspath(path):获取绝对路径
  • os.path.join(p1, p2):拼接路径
  • os.path.split(path):把最后一级地址拆分出来,返回元组
  • os.path.splitext(path):把最后一级地址的扩展名拆分出来,返回元组
  • os.path.isdir(path):是否为目录
  • os.path.isfile(path):是否为文件
  • os.path.exsits(path):是否存在
  • os.path.getsize(path):获取文件大小
  • os.path.dirname(path):文件所在目录
  • os.path.basename(path):文件名
  • os.sep:系统的分隔符

sys模块

  • sys.path返回查找模块路径的列表
  • sys.exit()退出
  • sys.stdin标准输入
  • sys.stdout标准输出
  • sts.stderr标准错误输出

时间模块

时间的表示形式:

  • 时间戳:以秒为单位的时间戳。
  • 元组:整型,年月日、小时分钟秒、星期、儒略日数、夏令时。
  • 格式化字符串。

datetime

包含date/time/timedelta三个类

  • dt.datetime.now()当前时间(datetime类)
  • dt.date(2020, 3, 14)创建日期
  • dt.time(15, 9, 26)创建时间
  • dt.timedelta(3)3天的时间差

time

time.time()返回时间戳
time.strftime(“%Y-%m-%d %H-%M-%S”)格式化输出时间
time.asctime(tuple)转化为字符串
time.ctime(stamp)转化为字符串
time.sleep()休眠

hashlib/hmac/uuid

1
2
3
4
5
6
7
8
9
10
11
12
m=hashlib.md5()
m.update('abc'.encode('utf8'))
print(m.hexdigest())
x=hashlib.sha1('abc'.encode('utf8'))
x=hashlib.sha224()
x=hashlib.sha256()
x=hashlib.sha384()

h=hmac.new('key'.encode(), 'msg'.encode())
print(h.hexdigest())

print(uuid.uuid4())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def uuid1(node=None, clock_seq=None):
"""Generate a UUID from a host ID, sequence number, and the current time.
If 'node' is not given, getnode() is used to obtain the hardware
address. If 'clock_seq' is given, it is used as the sequence number;
otherwise a random 14-bit sequence number is chosen."""
pass
def uuid3(namespace, name):
"""Generate a UUID from the MD5 hash of a namespace UUID and a name."""
pass
def uuid4():
"""Generate a random UUID."""
pass
def uuid5(namespace, name):
"""Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
pass

自定义模块

以下划线开始的成员,建议只在本模块中使用。from pack import *无法导入。
不希望别人使用时,在最后del掉内部成员。

直接运行当前py文件时,__name____main__,否则为模块名。

面向对象

魔法方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class Quaternions(object):
"""
一个四元数的类。
"""
__slots__ = ('r', 'i', 'j', 'k') # 规定对象可以存在的属性

def __init__(self, r=0, i=0, j=0, k=0): # 构造函数
self.r = r
self.i = i
self.j = j
self.k = k

def __del__(self): # 析构函数
pass

def __repr__(self): # repr(obj) print(obj)
return '{} + {}i+ {}j + {}k'.format(self.r, self.i, self.j, self.k)

def __str__(self): # str(obj) print(obj)
return '{} + {}i+ {}j + {}k'.format(self.r, self.i, self.j, self.k)

def __int__(self): # int(obj)
return int(self.r)

def __call__(self, *args, **kwargs): # 仿函数调用
print('__call__方法被调用了')

def __eq__(self, other):
return self.r == other.r and self.i == other.i and self.j == self.j and self.k == self.k

def __ne__(self, other):
return not self == other

def __gt__(self, other):
return self.r > other.r

def __lt__(self, other):
return self.r < other.r

def __ge__(self, other):
return self.r >= other.r

def __le__(self, other):
return self.r <= other.r

def __add__(self, other):
return Quaternions(self.r+other.r, self.i+other.i, self.j+other.j, self.k+other.k)

def __neg__(self):
return Quaternions(-self.r, -self.i, -self.j, -self.k)

def __sub__(self, other):
return self+-other

def __abs__(self):
return (self.r**2+self.i**2+self.j**2+self.k**2)**0.5

def __mul__(self, other):
return Quaternions(
self.r*other.r-self.i*other.i-self.j*self.j-self.k*other.k,
self.i*self.r+self.r*other.i-self.k*other.j+self.j*other.k,
self.j*other.r+self.k*other.i+self.r*other.j-self.i*other.k,
self.k*other.r-self.j*other.i+self.i*other.j+self.r*other.k)

def __setitem__(self, key, value): # obj[key]=value
self.__dict__[key] = value

def __getitem__(self, item): # obj[item]
return self.__dict__[item]

内置属性

python支持动态属性,可以用__slot__限定可以用的属性。
__dict__为一个对象对应的字典。
__dir__为类的所有成员。
__doc__为文档注释。

类和对象

类也是对象。

类属性(静态属性)是所有对象共享的属性。只能通过类对象修改。

私有成员由两个下划线开头,外部无法获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Person(object):
type = 'unknown'

def __init__(self, t):
self.type = t
self.__hidden = 0

def get_hidden(self):
return self.__hidden

@staticmethod
def say_hello():
print('hello')

@classmethod
def say_type(cls):
print(cls.type)

p = Person('boy')
print(p.type) # 'boy'
print(Person.type) # 'unknown'
print(p.__hidden) # AttributeError
print(p._Person__hidden)
print(p.get_hidden())

尽管不同的类对象调用相同的成员函数,但被调用的函数已经绑定了不同的对象,所以p1.fun()p2.fun()不是相同的函数。

通过类调用对象成员函数,就需要指定self。p.fun()相当于Person.fun(p)

静态方法是从属于类的方法,不属于对象。对象也可以调用。

如果对象只使用类属性,可以定义为类方法。cls为类对象。

单例

1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton(object):
__instance = None
__is_new = True

def __new__(cls, *args, **kwargs):
if cls.__instance is None:
__instance = object.__new__(cls)
return __instance

def __init__(self, num):
if self.__is_new:
self.num = num
self.__is_new = False

继承

python支持多继承,用cls.__mro__查看继承的调用顺序。

子类不继承父类的私有成员。

is用于对象是否是同一对象,isinstance用于判断对象是否是该类的一个实例,issubclass判断一个类是否是另一个类的派生类。

多态

子类构造函数可以重写父类的构造函数。

1
2
3
4
5
6
7
8
9
class A(object):
def __init__(self, x):
A.x = x


class B(A):
def __init__(self, x, y):
super(B, self).__init__(x)
B.y = y

子类可以重写父类方法,调用父类方法形成多态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person(object):
def __init__(self, name, dog):
self.name = name
self.dog = dog

def work_with_dog(self):
if self.dog is not None and isinstance(self.dog, Dog):
print('{}正在和狗工作'.format(self.name))
self.dog.work()


class Dog(object):
def __init__(self, name):
self.name = name

def work(self):
print('Dog:{}正在工作'.format(self.name))


class PoliceDog(Dog):
def work(self):
print('PoliceDog:{}正在工作'.format(self.name))

article_txt
目录