Python语法学习
1. 序列
1.1 list API
list API | |
---|---|
append(data) | |
clear() | |
copy() | |
count(data) | 计算data出现次数 |
extend(list) | 附加列表 |
index(data) | 返回data第一次出现的index |
pop(index) | 删除对应index处的值 |
remove(data) | 删除列表中对应的值 |
reverse() | 列表翻转 |
sorted() | 列表排序 |
1.2 序列统计函数
序列统计函数 | |
---|---|
len(seq) | |
max(seq) | |
min(seq) | |
sum(seq) | |
any(seq) | 有一个为TRUE则为True |
all(seq) | 有一个为False则为False |
1.3 str API
str API | |
---|---|
center(length) | 字符串总长度为length,居中处理 |
find(data) | 返回找到的索引,否则返回-1 |
join(data) | 按照指定连接符将序列内容连接为一个完整的字符串 |
split(data,[,limit]) | 字符串拆分 |
lower() | 字符串小写 |
upper() | 字符串大写 |
replace(old,new) | 字符串替换 |
strip() | 删除左右空格 |
1.4 dict API
dict API | |
---|---|
clear() | 清空 |
update({k=v,}) | 大规模更新字典 |
fromkeys(seq,[value]) | 将列表转换为字典 |
get(key) | |
pop(key) | 删除key的映射 |
popitem() | 删除映射 |
keys() | |
values() | |
items() |
2. 函数
2.1 zip函数
# zip([iterable...])#压缩一个或者多个迭代器
a = [1,2,3]
b = [2,3,4]
c = [3,4,5]
c = zip(a,b,c,d)
for i in c:
print(i)
2.2 内置函数对象API
内置对象函数API | |
---|---|
callable(object) | 判断给定对象是否可以调用(是否是函数) |
eval(object) | 单行代码计算 |
exec(object) | 多行代码计算 |
compile(source,filename,mode) | 对传入的source进行编译 |
2.3 函数式编程
#lambda定义行内函数
f = lambda x:x+2#相当于f(x)=x+2
g = lambda x,y:x+y#相当于g(x,y)=x+y
a = [1,2,3]
b = [2,3,4]
# map函数用于逐一遍历
c = list(map(lambda x,y:x*y,a,b))
c = list(c)
#reduce函数用于把一个序列通过某种方式(function)转变成一个值
from functools import reduce
reduce(lambda x,y:x+y,b)
#filter函数筛选列表中符合条件的元素,返回迭代对象
b = filter(lambda x:x>2 and x<7,range(10))
b = list(b)
3. 模块
3.1 __init__.py
所有包除了定义模块之外还需定义一个__init__.py
,考虑到通配符*的作用,可以配置__all__系统变量设置引入模块。例如在com/yootk/info/__init__.py
中配置__all__=["Message"]
。
3.2 copy模块
Python的copy模块 | |
---|---|
copy(obj) | 浅拷贝 |
deepcopy(obj) | 深拷贝 |
3.3 random模块
random API | |
---|---|
random() | 0<=n<=1.0 随机浮点数 |
uniform(x,y) | x<=n<=y 随机浮点数 |
randint(x,y) | x<=n<=y 随机整数 |
random.randrange(x,y,step) | 从指定范围[x:y:step] 中生成随机数 |
choice(seq) | 从序列中随机抽取数据 |
shuffle(seq) | 将列表中数据打乱 |
sample(seq,k) | 从列表中获取指定序列分片,分片大小为2 |
MapReduce API | |
---|---|
filter(func,seq) | 数据筛选 |
map(func,seq) | 数据处理 |
reduce(func,seq) | 统计 |
3.4 创建虚拟环境
-
安装
virtualenv
工具pip install virtualenv
-
创建一个python虚拟环境
D:\python_project>virtualenv venv
-
激活虚拟环境
D:\python_project\venv\Scripts\activate.bat
之后pip install安装包存放在
{项目目录}\{虚拟环境名称}\Lib\site-packages
-
退出虚拟环境
D:\python_project\venv\Scripts\deactivate.bat
3.5 模块打包
Python使用setuptools
模块进行打包,将模块打包为.whl
文件,文件中会有对应的包和模块程序定义。wheel是python对打包文件的统称,本质是一个.zip
的二进制压缩包。
模块打包步骤
- 使用
setuptools.setup()
函数定义打包文件setup.py
- 进行模块打包操作
python setup.py bdist_wheel
- 如果要安装到本地
python setup.py install
3.6 模块发布
PyPI(Python Package Index)公共仓库
模块发布步骤
-
安装twine工具
pip install twine
-
通过twine工具上传
twine upload dist/*
4. 类和对象
4.1 Python属性
属
性
{
类
属
性
(
相
当
于
s
t
a
t
i
c
)
实
例
属
性
(
只
在
某
实
例
中
添
加
,
不
会
对
某
一
类
的
所
有
实
例
添
加
某
属
性
)
属性\begin{cases} 类属性(相当于static)\\ 实例属性(只在某实例中添加,不会对某一类的所有实例添加某属性)\\ \end{cases}
属性{类属性(相当于static)实例属性(只在某实例中添加,不会对某一类的所有实例添加某属性)
设置实例属性两种方法
# coding : utf-8
# 1.python实例属性可以在函数中添加
class Member:
info = "www.baidu.com"#类属性(static静态属性)
def set_info(self,name,age):
self.name = name#实例属性
self.age = age
def print_info(self):
print("姓名:%s 年龄:%d"%(self.name,self.age))
# 2.在类外部通过添加实例化属性
# coding : utf-8
class Member:
def print_info(self):
print("姓名:%s 年龄:%d 分数%d"%(self.name,self.age,self.score))
def main():
mem = Member()
mem.name = 'lcx'
mem.age = 19
mem.score = 99
mem.print_info()
对象使用引用传递
4.2 封装
# 私有成员变量
class Member:
def set_info(self,name,age,score):
'''
在属性前加__表示该属性为私有属性,在外部不能直接访问,也就是print(),但是如果赋值可能会当做添加新实例属性
'''
self.__name = name
self.__age = age
self.__score = score
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def get_score(self):
return self.__score
def main():
mem = Member()
mem.set_info('lcx',19,99)
mem.__name = 'wyz'#当做重新添加的属性
print("姓名:%s 年龄:%d 分数:%d"%(mem.get_name(),mem.get_age(),mem.get_score()))
if __name__=="__main__":
main()
构造函数、析构函数
class Member:
def __init__(self,name,age):#带参数构造方法
self.name = name
self.age = age
def __del__(self):#析构函数
print("地址空间为%d内存已释放"%id(self))
def show_info(self):
print("姓名:%s 年龄:%d"%(self.name,self.age))
class Member:
def __init__(self,**kwargs):#带关键字参数的构造方法
self.name = kwargs["name"]
self.age = kwargs["age"]
def show_info(self):
print("姓名:%s 年龄:%s"%(self.name,self.age))
def main():
# 匿名对象
Member(name='lcx',age=19).show_info()
if __name__=='__main__':
main()
4.3 继承
class 子类(父类,父类,。。。。):
pass
构造方法调用
-
当父类定义构造方法,子类没有定义构造方法,实例化对象会自动调用父类提供的无参构造方法,如果此时子类同时继承多个父类,按照顺序依次调用父类的无参构造
-
当子类定义构造方法时,默认不使用父类中任何构造方法,但是可以手工调用
获取继承结构信息的函数和变量API
函数或变量 | |
---|---|
__class__ | 返回类型type() |
issubclass(clazz,父类) | 判断一个class对象是否是某一个类的子类 |
4.4 多态
- 方法覆写
- 对象多态性
5. 特殊方法
5.1 对象操作支持
class Message:
def __new__(cls,*args,**kwargs):
print("【new】cls=%s、args=%s、kwargs=%s"%(cls,args,kwargs))
return object.__new__(cls)
def __init__(self,**kwargs):
print("【init】kwargs=%s"%kwargs)
__new__
比__init__
优先执行,一般用于创建一些公共类属性配置,即设置一些静态变量。
__str__()
类似java
的toString()
,覆写__str__
就可达到toString()
的效果
5.2 属性操作支持
调用拦截。开发者在调用类中方法或者属性时可通过__getattribute__(self,item)
拦截。
# coding : utf-8
import os
class Message:
def __getattribute__(self,item):#拦截的item为被调用属性名称
if item=='content':
return "www.baidu.com"
print("【getattribute】函数拦截调用")
return object.__getattribute__(self,item)#完成任务必备
def send(self,info):
print("消息发送:%s"%info)
def main():
msg = Message()
print(msg.content)
msg.send("www.youth.com")
if __name__ == '__main__':
main()
实例属性字典。python最大的特点就是每个实例化对象能够动态进行实例化属性配置,所有实例属性保存在object类的__dict__
字典变量中。
class Member:
pass
def main():
mem = Member()
mem.name = 'lcx'
print(mem.__dict__)
if __name__=='__main__':
main()
6. 异常处理
-
抛出异常 raise相当于java和c++的throw
-
自定义异常类直接继承Exception即可
-
利用with进行上下文管理,替代try,exception,finally的复杂操作
# coding : utf-8
class Message:
class __Connect:
def build(self):
print("【connect】建立通道")
return True
def close(self):
print("【connect】释放通道")
def send(self,msg):
print("【Message】发送消息%s"%msg)
def __enter__(self):#with语句开始执行时触发此方法执行,进行资源初始化
print("【enter】with语句开始执行")
self.__conn = Message.__Connect()
if not self.__conn.build():
print("【Error】消息通道建立失败")
return self
def __exit__(self,type,value,trace):#with语句结束后触发执行,释放资源
print("【exit】with语句结束执行")
self.__conn.close()
def main():
with Message() as msg:
msg.send("www.baidu.com")
msg.send("www.baidu.com")
if __name__ == '__main__':
main()
7. 序列结构扩展
7.1 set API
set API | 运算符简化 | |
---|---|---|
add(self,element) | 向集合追加数据 | |
clear(self) | 清空集合 | |
copy(self) | 集合浅拷贝 | |
difference(self,t) | 计算差集s-t | s-t |
intersection(self,t) | 计算交集 s ∩ t s\cap t s∩t | s&t |
symmetric_difference(self,t) | 对称差集 ( s − t ) ∪ ( t − s ) (s-t)\cup(t-s) (s−t)∪(t−s) | s^t |
union(self,t) | 计算并集 s ∪ t s\cup t s∪t | s|t |
discard(self,element) | 如果元素存在,删除 | |
update(self,seq) | 更新集合数据 | |
remove(self,element) | 从集合中删除数据,元素不存在报错 | |
pop(self) | 从集合中删除一个元素 |
7.2 deque API
deque API | |
---|---|
append(self,element) | 队列后端添加数据 |
appendleft(self,element) | 队列前端添加数据 |
clear() | 清空队列信息 |
count(self,element) | 获取指定元素在队列中出现次数 |
pop(self) | 从队列前端弹出数据 |
popleft(self) | 从队列后端弹出数据 |
remove(self,element) | 删除队列中指定数据 |
reverse(self) | 队列反转 |
7.3 heapq API
heapq API | |
---|---|
heapify(iterable) | 堆化 |
heappush(heap,element) | 向堆中添加数据 |
heappop(heap) | 从堆中移出一个最小值 |
nlargest(n,heap,key=fun) | 获取前n个最大值 |
nsmallest(n,heap,key=func) | 获取前n个最小值 |
7.4 enum
枚举
import enum
class Week(enum.Enum):
Monday = 0
Tuesday = 1
Wendesday = 2
Thursday = 3
Firday = 4
Saturday = 5
Sunday = 6
def main():
monday = Week.Monday
print("name:%s value:%s"%(monday.name,monday.value))
7.5 yield生成器
不会一次生成全部数据,根据需要动态控制生成器数据,避免占用过多内存。yield调用需要通过外部的next()控制,当调用next()触发yield返回数据;也可以利用生成器对象.send()向yield调用处发送信息,并且返回下一次yield内容。
def generator(maxnum):
for i in range(maxnum):
yield "baidu-%s"%i
# yield from等价于上面的操作
yield from ["baidu-%s"%i for i in range(maxnum)]
def main():
for i in generator(99):#每次for循环才会返回数据
print(i)
7.6 日期时间
7.6.1time模块
描 述 时 间 { 时 间 戳 时 间 元 组 格 式 化 日 期 时 间 描述时间\begin{cases}时间戳\\时间元组\\格式化日期时间\end{cases} 描述时间⎩⎪⎨⎪⎧时间戳时间元组格式化日期时间
函数主要为了实现时间戳、时间元组、格式化日期时间三者转换。
时间戳。每个时间戳产生时,首先通过hash函数加密形成摘要,然后将摘要发送到DTS,DTS加入收到文件的日期和时间信息再对文件进行加密最后将数据发送给用户。
- 需加时间戳的文件摘要
- DTS。收到文件的日期和时间
- 数字签名
时间元组
(tm_year,tm_mon,tm_mday,tm_hour,tm_min,tm_sec,tm_wday,tm_yday,tm_isdst)
格式化日期时间
# 年月日时分秒
string = '%Y-%m-%d %H:%M:%S'
time API
7.6.2 datetime模块
datetime模块是对time模块的重新封装,包括五个类:date类、time类、datetime类、timedelta类、tzinfo类
# coding : utf-8
import datetime
def main():
# datetime.date
print(datetime.date.today())
now = datetime.date(2017,2,17)
print(now)
#datetime.time
now = datetime.time(21,15,32,123678)
print(now)
print(now.hour,now.minute,now.second,now.microsecond)
# datetime.datetime
now = datetime.datetime.today()
print(now)
now = datetime.datetime(2020,9,8,12,11,15,32)
print(now)
# datatime.timedelta
now = datetime.datetime.today()
# 30个小时之后
print(now+datetime.timedelta(hours=30))
# 30个小时之前
print(now-datetime.timedelta(hours=30))
if __name__ == '__main__':
main()
7.7 正则表达式
re API | |
---|---|
compile(pattern,flags=0) | 重用pattern |
findall(pattern,string,flags=0) | 将匹配内容以列表形式返回 |
finditer(pattern,string,flag=0) | 将匹配内容以迭代对象形式返回 |
match(pattern,string,flags=0) | 字符串匹配 |
search(pattern,string,flags=0) | 在任意位置上进行匹配 |
split(pattern,string,flags=0) | 拆分字符串 |
match(pattern,string,flags)函数会从头开始匹配,如果匹配成功,会返回一个match类对象,在该对象中可以使用span()函数获取匹配位置索引。如果匹配不成功,返回None
res = re.match("baidu","baidu.com",re.I)
print(res)
print(res.span())
search(pattern,string,flags)可以匹配一个字符串的任意位置,同时返回匹配结果的索引位置。如果不匹配返回None
res = re.search("baidu","www.baidu.com",re.I)
print(res)
print(res.span())
范围匹配符
范围匹配符号 | |
---|---|
[abc] | abc中任意一位 |
[^abc] | 不是abc中任意一位 |
[a-zA-Z] | 某一位字母 |
[0-9] | 一位数字 |
边界匹配符 | |
---|---|
^ | 匹配开头 |
$ | 匹配结尾 |
正则表达式数量匹配 | |
---|---|
? | 字符出现0-1次 |
* | 字符出现0次、1次或多次 |
+ | 字符出现 1次或多次 |
{n} | 某字符正好出现n次 |
{n,} | 某字符出现n次以上 |
{n,m} | 某字符出现n~m次 |
简化正则表达式 | |
---|---|
\A | ^ |
\Z | $ |
\d | [0-9] |
\D | [^0-9] |
\s | [\t\n\r\f\v] |
\S | [^\t\n\r\f\v] |
\w | [a-zA-Z0-9_] |
\W | [^a-zA-Z0-9_] |
. | 匹配任意一位字符 |
正则逻辑表达式 | |
---|---|
正则表达式A正则表达式B | A之后紧跟着B |
正则表达式A|正则表达式B | A或者B |
#如果字符串前不加r,则\\d+表示\d+的意思
pattern = r'\d+'
正则表达式匹配模式 | |
---|---|
I(Ignorecase) | 忽略大小写 |
L(Locale) | 字符集本地化表示 |
M(Multiline) | 多行匹配模式 |
S(Dotall) | 修改.匹配任意模式,可匹配任何字符 |
X(Verbose) | 忽略正则表达式中的空白或者注释信息 |
可以使用|
设置多个模式同时使用
分组,正则表达式使用圆括号完成分组
# coding : utf-8
import re
string = 'id:lcx,phone:10086,birthday:2000-11-12'
#普通分组索引
pattern = r'(\d{4})-(\d{2})-(\d{2})'
result = re.search(pattern, string)
print(result.span())
print(result.group(0))#整体正则表达式作为一个分组
print("年:"+str(result.group(1)))
print("月:"+str(result.group(2)))
print("日:"+str(result.group(3)))
# 给索引命名
string = 'id:lcx,phone:10086,birthday:2000-11-12'
pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
result = re.search(pattern, string)
print(result.group("year"))
print(result.group("month"))
print(result.group("day"))
8. os模块
os API | |
---|---|
getcwd() | 获取当前工作目录 |
chdir(path) | 修改工作目录 |
system() | 执行操作系统命令 |
popen(cmd,mode,buffering=-1) | 开启命令管道 |
symlink(src,dst) | 创建软链接 |
link(src,dst) | 创建硬链接 |
os.path API | 进行路径处理操作 |
---|---|
abspath(path) | 获取绝对路径 |
basename(path) | 获取文件名称 |
dirname(path) | 返回父路径 |
exists(path) | 判断路径是否存在 |
isfile(path) | 判断路径是否为文件 |
isdir(path) | 判断路径是否为目录 |
join(path1,path2,path3) | 路径合并 |
samefile(path1,path2) | 判断是否为统一路径 |
split(path) | 将路径分割为dirname和basename |
curdir | 表示当前文件夹. |
pardir | 表示父文件夹… |
sep | 获取系统路径分隔符 |
目录操作
os下目录操作API | |
---|---|
listdir(path) | 列出当前目录下所有子路径 |
mkdir(path) | 创建单级目录 |
mkdirs(name,mode=0o777,exists_ok=False) | 创建多级目录 |
rename(src,dst) | 为目录或文件重命名 |
remove(path) | 删除当前目录 |
removedirs(path) | 删除多级目录 |
walk(path) | 列出指定目录中内容结构 |