Python概览
要把Python当做一种工具
优点:简单和明确,解释型语言,具有平台可移植性,类库丰富,开发源码,面向对象编程和函数式编程都提供支持,可扩展性和可嵌入性.
缺点:执行效率稍低,代码无法加密。
历史:1990年,Python诞生.2000年,Python2.0发布.2008年,Python3.0发布,2010年,Python2.7发布.
Win10开发环境
官网下载:新建文件夹,直接安装(默认配置path),在CMD中$python -V查看版本
Cpython是内置的解释器.官方的Python解释器是用C语言实现.Anaconda: Python流行的发行版.
IDE:
Vscode,Sublime Text,Pycharm.SPyder,Atom,Jupter Notebook,Vim,命令行.
学习概括
从工程的角度去学习 Python.
第一步:大厦之基,勤加练习
以 Python 为例,如果你能够理解变量间的赋值、基本的数据类型、条件与循环语句、函数的用法,
那么你就达到了第一步的底线标准,应该开始在课下多多练习了。动手编程做一个简易的计算器
第二步:代码规范,必不可少.
第三步:开发经验,if 质的突破:
拥有大中型产品的开发经验是必不可少的。因为实战经验才能让你站得更高,望得更远。
基础知识
基本数据结构:列表,元组,字典,集合,字符串,栈,队列,堆,树,图.
条件语句,循环语句,文件输入与输出,自定义函数,错误与异常处理,面向对象编程,模块化.
进阶知识
对象的比较复制,参数的传递,迭代器,生成器,装饰器,元类,操作符字参数,上下文管理器.并发编程,全局解释器锁,垃圾回收机制,Python和其他语言(C++)的混合使用.
核心应用
数据分析与处理:
Numpy,Scipy科学计算,MatPlotlib绘图,Pandas数据索引与处理.
服务端开发:
Django框架,Flask轻量级框架,用户登录验证,缓存,端到端监控,单元测试.
爬虫开发:
索引操作,Scarpy框架,数据抓取存储,备份与恢复,Mongodb应用,高级查询和分组聚合操作,实践项目.
人工智能:
广告精准投放,计算机视觉,自然语言处理,智能搜索引擎,量化交易策略.
一:基础语法
注释:
单行注释:#xx ,多行注释 """xx""""。
数据类型:
1. 数字(int)类型:int、float、complex
2. 布尔型(bloo)
3. 字符串(str)
4. 列表(list)
5. 元组(tuple)
6. 字典(dict)
7. 集合(set)
数字类型(int)
Python3中,无论整数的大小长度为多少,统称为整型int。
int_demo1 = 100 ** 2
print("数据类型是",type(int_demo1))
int_demo2 = int('123')
print(type(int_demo2))
int_demo3 = 456
print(int_demo3.bit_length())
布尔类型(bool)
只存在两种值 True 和 False,对应的二进制值分别是 1 和 0。True的值太多, False 的值只有七个:None, 空([], (), {}, ""), 0。
bool_demoZ = bool(1)
print(bool_demoZ)
#以下是所有False
bool_demo1 = bool(None)
print(bool_demo1)
bool_demo2 = bool( )
print(bool_demo2)
bool_demo3 = bool([])
print(bool_demo3)
bool_demo4 = bool(())
print(bool_demo4)
bool_demo5 = bool({})
print(bool_demo5)
bool_demo6 = bool("")
print(bool_demo6)
bool_demo7 = bool(0)
print(bool_demo7)
字符串(str)
字符串可由单引号或双引号来创建,字符串是不可修改的,字符串可进行以下操作
(1)索引
(2)切片
(3)长度
(4)遍历
(5)删除
(6)分割
(7)替换
(8)连接
(9)大小写替换
(10)判断以什么开头
(11)判断字符串的内容
(12)格式话输出
(13)扩展
#index() 和 find() 的区别:若索引的字符串或序列不在字符串内,
# index--->返回的是ValueError:subString not found,而find--->返回 -1。
#索引
string_demo1 = "abc"
index_a = string_demo1.index("a",0)
print(index_a)
find_a = string_demo1.find("b",0)
print(find_a)
#切片
string_demo2 = "abcderf"
section = string_demo2[0:1]
print(section)
#长度
string_demo3 = "abcdef"
len = len(string_demo3)
print(len)
#遍历..这个demo have some bug
# string4 = "它那么幼稚"
# for ergodic_str in string4:
# print("ergodic_str: ", ergodic_str)
# for index in range(len(string4)):
# print("ergodic_str2: ", string4[index])
#删除
string_demo5 = "abcdef"
del string_demo5
#分隔, partition制定分隔符;split指定分隔符分割几次
string_demo6 = "你的苹果是红色的."
fg = string_demo6.partition("-")
print(fg)
#替换,相关方法replace,strip,lstrip,rstrip
string_demo7 = "7pgpgh123213"
th_a = string_demo7.replace('7',"ff",2)
print(th_a)
th_b = string_demo7.strip() #去掉两边的空格
print(th_b)
th_c = string_demo7.lstrip()#去掉左边的空格
print(th_c)
th_d = string_demo7.rsplit()#去掉右边的空格
print(th_d)
#连接
string_demo8 = "MOMOMO"
jo = '*'.join(string_demo8)
print(jo)
string_demo8a = ['2','1','34']
zh = "->".join(string_demo8a)
print(zh)
#大小写转换
#第一个单词首字母大写:capitalize;全部字母小写:lower;全部字母大写:upper;单词首字母大写:title;大写转小写,小写转大写:swapcase
string_demo9 = "Hello World"
dx_a =string_demo9.capitalize()
print(dx_a)
da_b = string_demo9.lower()
print(da_b)
da_c = string_demo9.upper()
print(da_c)
da_b = string_demo9.title()
print(da_b)
da_e = string_demo9.swapcase()
print(da_e)
#判断字符串的内容
# isalnum字符串是数字或字母的组合;isalpha字符串全部是字母;isdigit字符串数字的组合
string_demo10 = "Mad Man 01"
pdzf_a = string_demo10.isalnum()
print(pdzf_a)
pdzf_b = string_demo10.isalpha()
print(pdzf_b)
pdzf_c = string_demo10.isdigit()
print(pdzf_c)
#判断以什么开头
string_demo11 = "How Do You 网"
pdfz_a = string_demo11.startswith("How")
pdfz_b = string_demo11.endswith("w")
print(pdfz_a)
print(pdfz_b)
#格式化输出
string_demo12 = "你是什么大象{name}"
print(string_demo12.format(name="云南象"))
print(string_demo12.format_map({"name":"红象"}))
#扩展
string13 = "name\tage\tsex\nA\t22\tmale\nB\t23\tfmale"
expandtabs_str = string13.expandtabs()
print("expandtabs_str: \n", expandtabs_str)
列表(List)
由一系列特定元素顺序排列的元素组成的,它的元素可以是由任何数据类型即数字、字符串、列表、元组、字典、布尔值等,同时其元素是可以修改的。
(1)索引、切片
(2)追加
(3)拓展
(4)插入
(5)取出
(6)删除
(7)排序
#索引,切片
list_demo1 = [123,'string',[1,2,3],(1,2,3),{"App":"1"},True]
index_list = list_demo1[2]
print(index_list)
section_list= list_demo1[0:3]
print(section_list)
#追加append,整体添加
list42 = list_demo1
list42.append([1,2])
print(list42)
#扩展extend,分解添加
list43 = list_demo1
list43.extend([1,4])
print(list43)
#插入insert
list44 = list_demo1
list44.insert(3,"O")
print(list44)
#取出pop
list45 = list_demo1
list45.pop()
print(list45)
#删除remove,del
list46 = list_demo1
list46.remove("string")
print(list46)
del list46[0]
print(list46)
#排序
list47 = [23,5,3,222,344]
print(sorted(list47))
print(sorted(list47,reverse=True))
元组(tuple)
元组即为不可修改的列表,用圆括号标识,特性和list相似
tuple0 = (1,23,3424,234234)
print(tuple0)
字典(dict)
字典为一系列的键-值对,每个键值通过逗号分割,每个键对应一个值,可以通过键来访问值。无序访问。 键的要求:必须是不可变的。可以是数字、字符串、元组、布尔值。
dict0 = {
("Heloo"): 1,
"momo": "英文",
True: ['mm']
}
print("dict0",dict0)
#遍历字典--键
for key in dict0:
print(key)
#遍历字典--键值对
print(dict0.items())
#遍历字典---值
print(dict0.values())
集合(set)
集合是一个无序不重复元素的集。set集合类需要的参数必须是迭代类型的,如:序列、字典等,然后转换为无序不重复的元素集。由于集合是不重复的,所以可以对字符串、列表、元组进行去重。
集合的特性:
(1)去重
(2)无序
(3)每个元素必须为不可变类型(hashable类型,可作为字典的key)
set0 = {"A",'a','a',"B"}
set1 = set({"C","D",'e',(12,2)})
set2 = frozenset({"G","F","不变集合"})
#增(add,update)
set0.add("加一")
print(set0)
set0.update("t")
print(set0)
#删除pop remove discard
set0.pop()
print(set0)
set0.remove('A')
print(set0)
set0.discard('W')#未找到则无视
print(set0)
set4 = {"1","2"}
set5 = {"3","4"}
#关系运算,交集,并集,差集,issubset,isupperset
print("交集&",set4 & set5)
print("差集",set4 - set5)
print("并集",set4 | set5)
print("交叉布集",set4 ^ set5)
print("issubset前是否时后的子集", set4.issubset(set5))
print("isupperset前是否是后的父集",set4.issubset(set5))
栈(stack)
栈是一种后进先出(FILO)的数据结构,可以操作列表来实现栈的数据结构特性。删除的元素相当于是删掉了栈尾的元素.
class Stack():
def __init__(self, size):
self.stack131 = []
self.top = -1
self.size = size
def isfull(self):
return self.top + 1 == self.size
def isempty(self):
return self.top == '-1'
# 入栈前先检查栈是否已满
def push_stack(self, x):
if self.isfull():
raise Exception("statck is full")
else:
self.stack131.append(x)
self.top = self.top + 1
# 出栈之前检查栈是否为空
def pop_statck(self):
if self.isempty():
raise Exception("stack is empty")
else:
self.top = self.top - 1
self.stack131.pop()
def show_stack(self):
print(self.stack131)
if __name__ == "__main__":
s = Stack(10)
s.show_stack()
for i in range(6):
s.push_stack(i)
s.show_stack()
for i in range(3):
s.pop_statck()
s.show_stack()
print("stack FILO is end.......")
队列(queue)
队列是一种后进先出(FIFO)的数据结构,可以操作列表来实现栈的数据结构特性。新增的元素是添加的队列结尾的元素,出队列的元素相当于是删掉了对列前面的元素.
class Queue():
def __init__(self, size):
self.queue132 = []
self.front = -1
self.rear = -1
self.size = size
def isfull(self):
return self.rear - self.front + 1 == self.size
def isempty(self):
return self.front == self.rear
# 入队列
def enqueue(self, x):
if self.isfull():
raise Exception("queue is full")
else:
self.queue132.append(x)
self.rear = self.rear + 1
# 出队列
def dequeue(self):
if self.isempty():
raise Exception("queue is empty")
else:
self.queue132.pop(0)
self.front = self.front + 1
def show_queue(self):
print(self.queue132)
if __name__ == "__main__":
s = Stack(10)
s.show_stack()
for i in range(6):
s.push_stack(i)
s.show_stack()
for i in range(3):
s.pop_statck()
s.show_stack()
print("stack FILO is end.......")
q = Queue(7)
q.show_queue()
for i in range(6):
q.enqueue(i)
q.show_queue()
for i in range(3):
q.dequeue()
q.show_queue()
变量与变量命名:
一种存储数据的载体。
变量名由字母、数字和下划线构成,数字不能开头。大小写敏感,不要跟关键字和系统保留字冲突。最好用小写字母拼写,多个单词用下划线连接。
受保护的实例属性用单个下划线开头。私有的实例属性用两个下划线开头。
类型转换与占位符语法,运算符
使用`type`函数对变量的类型进行检查
int():将一个数值或字符串转换成整数,可以指定进制。
float()`:将一个字符串转换成浮点数。
str():将指定的对象转换成字符串形式,可以指定编码。
chr():将整数转换成该编码对应的字符串(一个字符)。
ord():将字符串(一个字符)转换成对应的编码(整数)。
占位符语法**:其中`%d`是整数的占位符,`%f`是小数的占位符,`%%`表示百分号
运算符:优先级从高到低的顺序列出了所有的运算符,运算符的优先级指的是多个运算符同时出现时,先做什么运算然后再做什么运算。
二:语法结构
选择结构
顺序结构,一条一条语句顺序执行.
分支结构又称为选择结构,是程序代码根据判断条件选择执行特定的代码。 如果条件为真,程序执行一部分代码;否则执行另一部分代码.
基本语法:1、if 2、if...else 3、if...elif...else 4、if...elif...elif......else 5、if 嵌套
# 1.if
a = 1
if a == 1:
print("你的输出正确")
# 2.if...else...
a = 1
if a == 1:
print("a的值为1")
else:
print("a的值不为1")
# 3.if...elif...else...
a = 1
if a > 1:
print("a的值大于1")
elif a == 1:
print("a的值等于1")
else:
print("a的值小于1")
# 4.if...elif...elif......else
a = 1
if a == 1:
print("a的值为1")
elif a == 2:
print("a的值为2")
elif a == 3:
print("a的值为3")
else:
print("a的值为不知道是什么")
# 5.if 嵌套
a = 1
b = 2
if a == 1:
if b == 2:
print("b的值为1")
else:
print("b的值不知道是什么")
else:
print("a的值迷失了~")
循环结构
循环结构是指满足一定的条件下,重复执行某段代码的一种编码结构。
Python的循环结构中,常见的循环结构是for循环和while循环。
for 循环经常用与遍历字符串、列表、字典等数据结构,for循环需要知道循环次数。
# 1. for...in...
list1 = [1, 2, 3, 4, 5, 2, 4, 7, 9, 0]
count = 0
for i in list1:
if i == 2:
count += 1
print("count: ", count)
# 2.嵌套for循环
# 乘法表
result = 0
for i in range(1, 10):
for j in range(1, i + 1):
print(str(j) + '*' + str(i) + '=' + str(i*j) + '', end=' ')
print(' ')
# 3.while循环
num = 1
while num <= 5:
print("num:", num)
num += 1
三:文件操作
读写文件是最常见的IO操作,现代操作系统不允许普通程序直接操作磁盘,读写文件就是请求操作系统打开一个文件操作对象,通过操作系统提供的接口进行对文件的读写操作。
读文件
#读文件
# codecs模块:主要用来解决文件乱码的问题
import codecs
f_read =codecs.open('qs.txt','rb',encoding="utf-8")
print(f_read.read())
f_read.close()
写文件
#写文件
f_write = codecs.open('qs.txt','wb',encoding="utf-8")
f_write.write("ABC")
f_write.close()
文件操作的常用方法
#读文件
import codecs
f_read =codecs.open('qs.txt','rb',encoding="utf-8")
print(f_read.read())
f_read.close()
#写文件
f_write = codecs.open('qs.txt','wb',encoding="utf-8")
f_write.write("ABC")
f_write.close()
#常用方法
#1.readlines():读取所有行,直到结束符EOF并返回列表
f_readlines = codecs.open('qs.txt','rb',encoding="utf-8")
f_a = f_readlines.readlines()
print(type(f_a))
print(f_a)
print(f_a[0])
f_readlines.close()
#2.realine():用于从文件读取整行,包括"\n"字符,如果指定一个非负数,则返回制定大小的字节数,包括'\n"字符.
# __next__():返回迭代器的下一个指向.
f_readline = codecs.open('qs.txt','rb',encoding="utf-8")
f_b= f_readline.readline()
print(f_b)
#print(f_readline.__next__())
f_readline.close()
#writelines():用于向文件中写入一序列的字符串
f_writelines = codecs.open('qs.txt','rb',encoding="utf-8")
#f_c = f_writelines.write("2131nnnn3\n\n")
#f_d = f_writelines.writelines(["123123\n","12333\n"])
f_writelines.close()
#tell()返回当前位置
f_tell = codecs.open('qs.txt','rb',encoding="utf-8")
print(f_tell.tell())
#seek():用于移动文件读取指针到制定位置
f_seek = codecs.open('qs.txt','rb',encoding="utf-8")
f_seek.seek(0)
f_seek.writelines(["222\n"])
f_seek.close()
#name()读取文件名
f_name = codecs.open('qs.txt','rb',encoding="utf-8")
print(f_name.name)
flush(): 刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。一般情况下,文件关闭后会自动刷新缓冲区,
# 但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法。
文件上下文管理
#文件操作中经常会忘记文件的关闭操作,使用with操作会避免这一情况的发生。
with codecs.open('qs.txt', 'wb', encoding='utf-8') as f_with:
f_with.write("test with.")
print("f_with_closed: ", f_with.closed)
print("f_with_closed: ", f_with.closed)
四:函数
函数是一段组织好的、可以重复使用的,用来实现单一或相关功能的代码段。
函数能提高应用的模块性,提高代码的利用率。
1.自定义函数
语法
def 函数名 (参数):
....xxx
#自定义函数
def zdy(a):
print("一段话)
#函数调用
zdy(1)
参数:普通参数,默认参数,动态参数
#普通参数
def para_a(para1, para2): #形参
print(para1)
para_a(100,200) #实参
#默认参数,调用时没有传入的值,用默认,有则用传入.
def para_b (para1,para2,moren="默认值JK"):
print("moren")
print(para1)
print(para2)
para_b("WWW",22)
#动态参数:可以接受任意个参数,有两种args和kwargs,其中args必须在kwargs前面.
#*agr接受按位置传参的值,返回一个元组.**kwargs接受按关键字传参的值,组成一个字典.
def dtcanshu (para1,para2,*args,**kwargs):
print(para1)
print(para2)
print(args)
print(kwargs)
dtcanshu(1,2,3,4)
函数返回值
#return 语句用于退出函数,选择性向调用方式返回一个表达式,不带参数值的return语句返回None
def fz(a,b):
zh = a + b
print(zh)
return zh
sm = fz(200,111)
print(sm)
2.异常处理
异常就是程序执行时发生错误的信号.
常用异常处理类:
(1) AttributeError 访问的对象没有该属性
(2) IOError 输入/输出异常,基本上是无法打开文件
(3) ImportError 无法引入模块或包,基本是路径或名称错误
(4) IndentationError 语法错误,代码没有正确对齐
(5) IndexError 下标索引超出边界
(6) KeyError 访问的字典里面不存在的键
(7) KeyboardInterrupt Ctrl + c 被按下
(8) NameError 访问一个还未被赋予对象的变量
(9) SyntaxError Python代码非法,代码不能编译
(10) TypeError 传入对象类型与要求的不符合
(11) ValueError 传入一个调用者不期望的值
(12) UnboundLocalError 访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量
(13) AssertionError 断言错误,说明断言的条件为假
异常处理方式
#try...exception...finally
yc = [1,2,3]
try:
for i in yc:
print(yc[i+2])
raise TypeError("主动抛出异常")
except IndexError as e:
print("异常 % 已经捕获,下面再有不捕获了" %e)
except Exception as e:
print(e)
finally:
print("程序执行结束,不管异常是否被捕获,这里一定执行")
# try...exception...else
yc_b = [1, 2, 3]
try:
for i in [1, 4]:
print(i)
except IndexError as e:
print(e)
except SyntaxError as se:
print(se)
else:
print("只有再try语句里面的执行成功的时候,才会执行else里面的内容")
#自定义异常
class EvaException(BaseException):
def __int__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
try:
raise EvaException("自定义错误")
except EvaException as e:
print(e)
断言
assert断言是声明其布尔值必须为真的判定,如果发生异常则说明表达式为假。
assert 1 == 1
try:
assert 1 == 2
except AssertionError as e:
print("断言的判断条件为错,异常已捕获: %s " % e)
3.迭代器
迭代器 指的是迭代取值的工具,迭代是一个重复的过程,每一次的重复都是基于上一次的结果而进行的;迭代提供了不依赖于索引而进行取值的方法。
可迭代对象 但凡内置 _iter_ 方法的对象,都称之为可迭代对象。Python常见数据类型中,str、list、tuple、dict、set、文件对象都是可迭代对象。
迭代器对象 (1)既内置 __next__方法,(2)又有 __iter__方法的对象,执行迭代器的 _iter_ 方法得到的依然是迭代器对象本身,执行 _next_ 方法可以不依赖索引进行取值。
总的来说: 迭代器一定是可迭代对象,而可迭代对象不一定是迭代器。
判断可迭代对象和迭代器
from collections.abc import Iterable, Iterator
ddq = "ABCDSEF"
list1 = range(10)
if isinstance(ddq,Iterable):
print("该对象是可迭代对象")
elif isinstance(ddq,Iterator):
print("该对象时迭代器")
else:
print("判断不存在")
迭代器的使用
from collections.abc import Iterable, Iterator
list1 =range(5)
for i in list1:
print(i)
#将可迭代对象转换为迭代器对象
if isinstance(list1,Iterable):
print("该对象是可迭代对象")
elif isinstance(list1,Iterator):
print("该对象是迭代器")
else:
print("您的判断不存在")
list2 = iter(list1)
try:
print("迭代器对象获取数据:",next(list2))
except StopIteration as e:
print("That is all floks!")
4.生成器
受内存的限制,我们如果要用列表生成式生成一个比较大的列表的时候就棘手了。生成器是一个特殊的程序,可以被用作控制循环的迭代行为,Python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()和send()函数恢复生成器。生成器一次只返回一个值。
创建生成器
demo = [x*x for x in range(10)]
print("列表生成式",demo)
d1 = (x*x for x in range(5))
print("生成器",d1)
try:
print("生成器迭代值",next(d1))
except StopIteration as e:
print("生成器所有的值已经迭代结束")
斐波拉契数列
# 0 1 1 2 3 5 8 13 21
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a+b
n = n + 1
return "done"
g = fib(5)
while True:
try:
x = next(g)
print("......: ", x)
except StopIteration as e:
print("生成器已迭代完毕...", e.value)
print("生成器已迭代完毕...", e.args)
bre
5.装饰器
Python的装饰器(decorators)就是用来拓展原来函数功能的一种函数,目的是不改变原函数名(或类名)的情况下,给函数增加新的功能。
def authority(function_to_decorate):
def auth():
username = input("请输入用户名:")
password = input("请输入用户密码:")
if username == 'crisimple' and password == '123456':
print("......认证成功......")
function_to_decorate()
else:
print("......认证失败......")
return auth200
@authority
def view_space():
print("......欢迎进入哔哩哔哩个人空间......")
if __name__ == "__main__":
view_space()
print("view_space.__name__ is: ", view_space.__name__)
装饰器应用
(1)引入日志
(2)函数执行时间统计
(3)执行函数前于谦准备
(4)执行函数后的清理工作【测试固件运用】
(5)权限校验等场景【登录/权限限制】
(6)缓存
带固定参数的装饰器
def message_auth(function_to_decorate):
def auth(user, passwd):
username = input("请输入用户名:")
password = input("请输入用户密码:")
if username == user and password == passwd:
print("......认证成功......")
function_to_decorate(user, passwd)
else:
print("......认证失败......")
return auth
@message_auth
def message(user, passwd):
print("......您可以查看您的消息了......")
无固定参数的装饰器
def pay_auth(function_to_decorate):
def auth(*args, **kwargs):
input("=====请输入你的动态口令=====: ")
function_to_decorate(*args, **kwargs)
return auth
@pay_auth
def pay(a, b, c):
print("......您的账户余额为动态口令之和:%s" % (a+b+c))
多个装饰器装饰同一函数
# 对于Python中的”@”语法糖,装饰器的调用顺序与使用 @ 语法糖声明的顺序相反。
def first_decorator(function_to_decorator):
def wrapper():
print("This is first decorator01")
function_to_decorator()
print("End of the first decorator01")
return wrapper
def second_decorator(function_to_decorator):
def wrapper():
print("This is second decorator02")
function_to_decorator()
print("End of the second decorator02")
return wrapper
@first_decorator
@second_decorator
def func_decorator():
print("...【This is to be decorated function】...")
Python内置装饰器
在Python中有三个内置的装饰器,都是跟class相关的:staticmethod、classmethod 和property。
(1)staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用
(2)classmethod 与成员方法的区别在于所接收的第一个参数不是 self (类实例的指针),而是cls(当前类的具体类型)
(3)property 是属性的意思,表示可以通过通过类实例直接访问的信息,对于一个类的属性,python的访问是没有限制的,但有时候我们需要对属性的访问加以限制,property可以胜任
class Foo(object):
def __init__(self):
self.name = 'zha nan'
self.age = '23'
# 不用传递self对象,就相当于是个普通方法
@staticmethod
def direct_call():
print("类静态方法,可以在类不进行实例化的情况下调用,可以不用传self参数了,看到这句话就说明了这个道理")
# 使用classmethod装饰器装饰后,方法的第一个参数是类对象;调用类方法不需要创建类的实例。classmethod也是一个类,所以classmethod是一个类装饰器。
@classmethod
def class_method(cls):
print(cls.direct_call)
# 对于一个类的属性,python的访问是没有限制的,但有时候我们需要对属性的访问加以限制,property可以胜任
# property是一个类,它有三个方法,deleter,setter,getter,有两种使用方式。
@property
def name(self):
return self.name
@name.setter
def name(self, set_num):
return self.name == set_num
@name.deleter
def name(self):
del self.name
from abc import abstractclassmethod, ABCMeta
# 一个类中的任何方法被abstractmethod装饰后,这个类不能实例化并且子类必须实现被abstractmethod装饰的方法
class ChildFoo(abstractmethod=ABCMeta):
@abstractclassmethod
def eat(cls):
pass
6.Python内置函数
# 1. abs() --- 返回数字的绝对值
a11 = 1
a12 = -2
a13 = 0
print("%s 的绝对值为 %s" % (a11, abs(a11)))
print("%s 的绝对值为 %s" % (a12, abs(a12)))
print("%s 的绝对值为 %s" % (a13, abs(a13)))
print("\n")
# --------------------------------
# bin() --- 返回一个整数int或长整型long int的二进制表示
bin_1 = 10
bin_2 = 20
print("%s经过bin后返回%s" % (bin_1, bin(10)))
print("%s经过bin后返回%s" % (bin_2, bin(20)))
print("\n")
# --------------------------------
# max() --- 返回给定参数的最大值,参数可以为序列
print("返回序列的最大值:", max(100, 200, 3000, 800))
print("\n")
# --------------------------------
# min() --- 返回给定参数的最小值,参数可以为序列
print("返回序列的最小值:", min(-100, 200, 0, -10000))
print("\n")
# ---------------------------------
# reversed() --- 用于反向列表元素
reverse_list = [3, 5, 7, 1]
reversed_tuple = (1, 4, 3, 5)
reverse_list.reverse()
print("%s 的反向输出为:%s" % (reverse_list, reverse_list))
# print("%s 的反向输出为:%s" % (reversed_tuple, reversed_tuple))
print("\n")
# -----------------------------
# oct() --- 将一个整数转换成8进制字符串
print("返回八进制的字符串:", oct(10))
# -----------------------------
# zip() --- 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
# 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
zip_1 = [1, 2, 3]
zip_2 = [4, 5, 6]
zip_3 = [7, 8, 9]
zipped1 = zip(zip_1, zip_2)
zipped2 = zip(zip_3, zip_2)
print("压缩成数组:", zipped1)
print("解压数组:", zip(*zipped2))
print("\n")
# -----------------------------
# complex([real[, imag]]) 创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数
# real -- int, long, float或字符串
# imag -- int, long, float
print("返回一个复数:", complex(1, 2))
print("返回一个复数:", complex("1+2j"))
print("\n")
# 2. divmod() --- 把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
a21 = -7
b21 = -2
a22 = 0
b22 = 5
a23 = 20
b23 = 0
print("%s 除以 %s 的;返回结果为:%s" % (a21, b21, divmod(a21, b21)))
print("%s 除以 %s 的;返回结果为:%s" % (a22, b22, divmod(a22, b22)))
# print("%s 除以 %s 的;返回结果为:%s" % (a23, b23, divmod(a23, b23)))
print("\n")
# pow(x, y) --- 返回x的y次方的值
c31 = 2
cc31 = -3
c32 = 2
cc32 = 3
print("%s 的 %s 次幂运算为:%s" % (c31, cc31, pow(c31, cc31)))
print("%s 的 %s 次幂运算为:%s" % (c32, cc32, pow(c32, cc32)))
print("\n")
# ---------------------------------------------------------
# sum(iterable[, start]) --- 对一系列数据求和
# iterable --- 可迭代对象:列表、元组、集合
# start --- 指定增加的参数,如果没有设置这个值,默认为0
sum_1 = [0, 1, 2, 3]
sum_2 = (9, 1, 2, 3)
sum_3 = {9, 1, 2, 0}
print("%s 求和结果为:%s" %(sum_1, sum(sum_1)))
print("%s 求和结果为:%s" %(sum_2, sum(sum_2)))
print("%s 求和结果为:%s" %(sum_3, sum(sum_3)))
print("\n")
# --------------------------------------------
# sorted(iterable, cmp=None, key=None, reverse=False)
# iterable -- 可迭代对象
# cmp -- 比较的函数有两个参数,参数的值从可迭代对象中取出,函数必须遵守,大于返回1,小于则返回-1,等于则返回0
# key -- 用来进行比较的元素,只有一个参数,函数的参数取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序
# reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)
sorted_dict = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
print("排序结果为:", sorted(sorted_dict, key=lambda s: s[2], reverse=True))
print("\n")
# 3. input & raw_input
# input() 读取一个合法的 python 表达式,输入字符串时必须引号括起来,否则会引发 SyntaxError
# raw_input() 将所有输入作为字符串看待
# 当实际测试下来两个并没有什么区别的感觉
# a31 = input("input: ")
# print("输入的数据为 %s, 它的类型为:%s" % (a31, type(a31)))
# a32 = input("raw_input: ")
# print("输入的数据为 %s, 它的类型为:%s" % (a32, type(a32)))
# 4. open() --- 用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写
# file() --- 用于创建file对象,它有一个别名叫open()
# 打开文件的模式:
# r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
# rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
# r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
# rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
# w 打开并只能写入。若文件已存则打开文件并从头开始编辑,原内容会被删除。若该不存在,创建新文件。
# wb 二进制格式打开文件只用于写入。若文件已存在则打开文件并从头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
# w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
# wb+ 以二进制格式打开文件用于读写。如果该文件已存在则打开文件从开头开始编辑原内容会被删除。如果该文件不存在,创建新文件。
# a 打开文件用于追加。若文件已存在,文件指针放在文件的结尾。新的内容会被写入已有内容。若文件不存在,创建新文件进行写入。
# ab 二进制格式打开文件用于追加。若文件已存文件指针放在文件结尾。新内容会写入到已有内容。若文件不存在,创建新文件进行写入。
# a+ 打开文件用于读写。若文件已存在文件指针将放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
# ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
# file对象的方法
# file.read([size]) --- 指定大小读取文件,若不写size,则返回整个文件
# file.readline() --- 返回一行
# file.readlines([size]) --- 返回指定size行,未指定的则返回全部行
# for line in f: print line --- 通过迭代器访问
# f.write["Hello"] --- 写入字符串数据,若是写入其他类型的数据则需先转换成字符串类型,再写入
# f.tell() --- 返回一个整数,表示当前文件指针的位置
# f.seek(偏移量,[起始位置]) --- 用来移动文件指针,偏移量可正可负;起始位置:0-文件头,默认;1-当前位置;2-文件尾
# f.close() --- 关闭文件
with open('55_decorators.py', 'r', encoding='utf-8') as f:
content = f.readline()
print(content)
print("\n")
# 5. staticmethod --- 内置装饰器,返回类的静态函数
class StatiClass(object):
@staticmethod
def write():
print("类的静态方法")
StatiClass.write()
print("\n")
# -------------------------------------
# classmethod --- 内置装饰器修饰的函数不需要实例化,第一个参数由self变为cls,用来调用类的属性、类的方法、
class ClassMethod(object):
bar = 1
def func1(self):
print('foo')
@classmethod
def func2(cls):
print(cls.bar)
cls().func1()
ClassMethod.func2()
print("\n")
# 6. all() --- 判断给定的可迭代对象参数 iterable 中的所有元素是否都为True,如果全是返回True,不是则为False
# 除了0,空,None,False外都算True
a61 = [1, 2, 3, 4, 5]
a62 = [1, '', '2', 'a']
a63 = [1, 0, '2', 'a']
a64 = [1, False, '2', 'a']
print("%s 的返回:%s" % (a61, all(a61)))
print("%s 的返回:%s" % (a62, all(a62)))
print("%s 的返回:%s" % (a63, all(a63)))
print("%s 的返回:%s" % (a64, all(a64)))
print("\n")
# any() --- 判断给定的可迭代参数iterable是否全为False,则返回 False,如果有一个为True则返回True
b61 = [1, 2, 3, 4, 6]
b62 = [0, 2, 3, 4, 6]
b63 = [0, '', False, None]
print("%s 的返回:%s" % (b61, any(b61)))
print("%s 的返回:%s" % (b62, any(b62)))
print("%s 的返回:%s" % (b63, any(b63)))
print("\n")
# 7. enumerate --- 将可遍历的数据对象(列表、元组或字符串)组合成一个索引序列,同时列出数据和数据下表,多用于for循环
# enumerate(sequence, [start=0]) --- sequence(一个序列、迭代器或其他支持迭代对象);start(下标起始位置)
sequence71 = ['A', 'B', 'C']
sequence72 = "I'm a good boy."
sequence73 = (1, 2, 3)
for i, element in enumerate(sequence71):
print(i, element)
for i, element in enumerate(sequence72):
print(i, element)
for i, element in enumerate(sequence73):
print(i, element)
print("\n")
# iter(object[, sentinel]) --- 生成迭代器
iter_1 = [1, 2, 3, 4, 5, 6]
iter_2 = "xiao"
for i in iter_1:
print("=====%s" % i)
print("**************", next(iter(iter_2)))
print("**************", next(iter(iter_2)))
print("**************", next(iter(iter_2)))
print("**************", next(iter(iter_2)))
print("\n")
# -----------------------------
# next() --- 返回迭代器的下一个项目
next_1 = iter([1, 2, 3, 4])
while True:
try:
x = next(next_1)
print("next访问迭代器的数据:", x)
except StopIteration:
break
print("\n")
# 8. int() --- 将一个字符串或数字转换为整型
a81 = 0.1
a82 = 3.8
a83 = -1
a84 = '123'
print("%s 整形为 %s" % (a81, int(a81)))
print("%s 整形为 %s" % (a82, int(a82)))
print("%s 整形为 %s" % (a83, int(a83)))
print("%s 整形为 %s" % (a84, int(a84)))
print("\n")
# str() --- 返回一个对象的string格式
print(str(123))
print(type(str({"A": 1, "B": 2})))
print("\n")
# --------------------------------------------------------------
# tuple() --- 将列表转换为元组
tuple_1 = [1, 2, 3, 7]
print("tuple()将 %s 转换成元组后为:%s" % (tuple_1, tuple(tuple_1)))
print("\n")
# --------------------------------
# list() --- 将元组转换为列表
list_1 = (1, '2', 'xyz', 7)
print("list()将 %s 转换成列表后为:%s" % (list_1, list(list_1)))
print("\n")
# --------------------------------
# slice(start, stop, step) --- 实现切片对象,用在切片操作函数里的参数传递
slice_list = [1, 2, 3, 4, 5, 6, 7]
myslice = slice(1, 6, 2)
print("slice截取列表:", slice_list[myslice] )
print('\n')
# --------------------------------
# dict(**kwarg)
# dict(mapping, **kwarg)
# dict(iterable, **kwarg)
print("字典1:", dict())
print("字典1:", dict(a='1', b=2, c=3))
print("字典1:", dict(zip(['AA', 'BB', 'CC'], [11, 22, 33])))
print("字典1:", dict([("AAA", 111), ('BBB', 222), ('CCC', 333)]))
print("\n")
# --------------------------------
# bool() --- 将给定参数转换为布尔类型,如果没有参数,返回False
bool_1 = 0
bool_2 = 1
bool_3 = None
bool_4 = ''
bool_5 = 'A'
print("bool() 将 %s 转换为bool类型后为:%s" % (bool_1, bool(bool_1)))
print("bool() 将 %s 转换为bool类型后为:%s" % (bool_2, bool(bool_2)))
print("bool() 将 %s 转换为bool类型后为:%s" % (bool_3, bool(bool_3)))
print("bool() 将 %s 转换为bool类型后为:%s" % (bool_4, bool(bool_4)))
print("bool() 将 %s 转换为bool类型后为:%s" % (bool_5, bool(bool_5)))
print("\n")
# --------------------------------
# float() --- 将整数和字符串转换成浮点数
print("整数转换为浮点数:", float(12))
print("字符串转换为浮点数:", float('234'))
print("\n")
# --------------------------------
# set(iterable) --- 创建一个无序不重复的元素集,iterable可迭代对象
# --- 可进行关系测试,删除重复数据,还可以计算并集、交集、差集等
set_1 = set("HELLO")
set_2 = set("WORLD")
print("原集合分别为:%s %s" % (set_1, set_2))
print("%s & %s 的结果为:%s" % (set_1, set_2, set_1 & set_2))
print("%s | %s 的结果为:%s" % (set_1, set_2, set_1 | set_2))
print("%s - %s 的结果为(即前面有后面没有的):%s" % (set_1, set_2, set_1 - set_2))
print("\n")
# --------------------------------
# map(function,iterable,...) --- 会根据提供的函数对指定序列做映射
map_result = map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print("map函数返回", map_result)
print("\n")
# --------------------------------
# repr() --- 将对象转换为供解释器读取的形式
repr_dict = {"A": 1, "B": 2}
print("repr返回对象的string形式:", repr(repr_dict))
print("\n")
# --------------------------------
# hash() --- 获取取一个对象(字符串或者数值等)的哈希值
hash_1 = "test hash"
hash_2 = 123
hash_3 = str([1, 2, 3]) # 集合
hash_4 = str(sorted({'A': 1}))
print("%s 的hash值为:%s" % (hash_1, hash(hash_1)))
print("%s 的hash值为:%s" % (hash_2, hash(hash_2)))
print("%s 的hash值为:%s" % (hash_3, hash(hash_3)))
print("%s 的hash值为:%s" % (hash_4, hash(hash_4)))
print("\n")
# --------------------------------
# hex() --- 将10进制整数转换成16进制,以字符串形式表示
print("hex的结果:", hex(255))
print("\n")
# --------------------------------
# bytearray() --- 返回一个新自己数据,数组里的元素是可变的,并且每个元素的值的范围为 0 <= x < 256
print("bytearray....: ", bytearray([1, 2, 3]))
print("bytearray....: ", bytearray())
print("\n")
# 9. ord() --- 是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数
print(ord('a'))
print(ord('b'))
print(ord('C'))
# chr() --- 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
print(chr(123))
print(chr(97))
# unichr() --- 和 chr()函数功能基本一样, 只不过是返回 unicode 的字符
# print(unichr(97))
print("\n")
# 10. eval() --- 用来执行一个字符串表达式,并返回表达式的值
# eval(expression[, globals[, locals]])
# expression -- 表达式
# globals -- 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象
# locals -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象
print(eval('3 * 4'))
print(eval('pow(2, 3)'))
print("\n")
# ----------------------------------
# exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码。
exec('print("Hello World")')
print("\n")
# ----------------------------------
# str.format() 字符串格式化功能
print("{} {}".format("Hello", "Python"))
print("{1} {0} {1}".format("Hello", "Python"))
print("冲动的人:{name1}, 喜欢的人:{name2}".format(name1="小徐", name2="where?"))
print("\n")
# -----------------------------------
# compile(source, filename, mode[, flags[, dont_inherit]]) --- 将一个字符串编译为字节代码
# source -- 字符串或者AST(Abstract Syntax Trees)对象
# filename -- 代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。
# mode -- 指定编译代码的种类。可以指定为 exec, eval, single。
# flags -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象
# flags和dont_inherit是用来控制编译源码时的标志
compile_str = "for i in range(10): print(i)"
c_str = compile(compile_str, '', 'exec')
print("编译后执行结果是:", exec(c_str))
print("\n")
# 11. isinstance() --- 判断一个对象是否是一个已知类型,类似于type()
# isinstance()会认为子类是一种父类类型,考虑继承关系。
# type()不会认为子类是一种父类类型,不考虑继承关系
# isinstance(object, classinfo)
a11 = 11
print("%s 的类型为 %s" % (a11, isinstance(a11, int)))
print("%s 的类型为 %s" % (a11, isinstance(a11, (list, int, str))))
class A11(object):
pass
class A12(A11):
pass
print(isinstance(A11(), A11))
print(isinstance(A12(), A11))
print(type(A11()) == A11)
print(type(A12()) == A11)
# 12. issubclass(class, classinfo) --- 判断参数class是否是类型参数classinfo的子类
class Issub_A:
pass
class Issub_B(Issub_A):
pass
print("%s 是否是 %s的之类?%s" % (Issub_B, Issub_A, issubclass(Issub_B, Issub_A)))
print("\n")
# -------------------------
# callable() --- 检查一个对象是否是可嗲用的,如果返回True,object仍有可能调用失败;如果返回False,调用绝对失败
print("callable 1返回:", callable(0))
print("callable 2返回:", callable(pow))
print("\n")
# -------------------------
# locals() --- 以字典类型返回当前位置的全部局部变量
def return_local(x: object, y: object) -> object:
z = 1
print(locals())
all_result = return_local(2, 3)
print("返回当前位置的全部局部变量:", all_result)
print("\n")
# 13. super() --- 函数是用于调用父类(超类)的方法
# super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题
# MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。
class Super_A(object):
def add(self,x):
y = x + 1
print(y)
class Super_B(Super_A):
def add(self,x):
super().add(x)
superb = Super_B()
superb.add(2)
print("\n")
# ------------------------------
# property() --- 在新式类中返回属性值
class Property_A(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
# -----------------------------------
# getattr() --- 返回一个对象属性值
class Getattr(object):
bar = 1
g = Getattr()
print("获取属性值:", getattr(g, 'bar'))
print("\n")
# ------------------------------------
# delattr(object, name_of_atrr)
class Delattr(object):
x = 1
y = 2
z = 3
d = Delattr()
print("d的属性:", d.x)
delattr(Delattr, 'x')
# print("d的属性:" % d.x)
print("\n")
# ------------------------------------
# setattr(object, name, value) -- 设置对象的属性值,该属性不一定是存在的
class Setattr(object):
s1 = 1
s_1 = Setattr()
setattr(s_1, 's2', 5)
print("设置不存在属性的值:", s_1.s2)
print("\n")
# hasattr(object, name) --- 用于判断对象是否包含对应的属性
# object--对象;name--属性名字符串
class Hasattr(object):
x = 10
y = 100
z = 1000
print("判断对象是否含有属性:", hasattr(Hasattr, 'x'))
print("判断对象是否含有属性:", hasattr(Hasattr, 'e'))
print("\n")
# 14. filter(function, iterable) --- 过滤序列中不符合条件的元素,返回由符合条件元素组成的新列表
# function --- 判断函数
# iterable --- 可迭代对象
import random
def func_filter(x):
list_a = []
for i1 in x:
if (i1 % 2) == 0:
list_a.append(i1)
return list_a
filter_result = func_filter([1, 2, 3, 4])
print("过滤后的序列为:%s" % filter_result)
# 15. len() --- 返回对象(字符、列表、元组等)长度或项目个数
len_1 = "len"
len_2 = [1, 2, 3, 4]
len_3 = (1, 2, 3)
print("%s 的长度为:%s" % (len_1, len(len_1)))
print("%s 的长度为:%s" % (len_2, len(len_2)))
print("%s 的长度为:%s" % (len_3, len(len_3)))
print("\n")
# vars() --- 返回对象object的属性和属性值的字典对象。
class Vars_A(object):
a = 1
print("vars()返回:", vars(Vars_A))
print("vars()返回:", vars(Vars_A()))
print("\n")
# -------------------------------------------------
# range(start, stop[, step])
range_result = range(10)
print("&&&&&&&&", range_result)
print("\n")
# -------------------------------------------------
# frozenset() --- 返回一个冻结集合,冻结后结合不能再添加或删除任何元素
frozenset_1 = frozenset(range(10))
print("frozenset1: %s" % frozenset_1)
frozenset_2 = frozenset("HELLO")
print("frozenset2: %s" % frozenset_2)
print("\n")
# --------------------------------------------------
# globals() --- 以字典类型返回当前位置的全部变量
globals_1 = 'test'
print("当前位置的全局变量:", globals())
print("\n")
# 16.memoryview --- 返回给定参数的内存查看对象(Momory view)。
# 所谓内存查看对象,是指对支持缓冲区协议的数据进行包装,在不需要复制对象基础上允许Python代码访问。
v = memoryview(bytearray('abc', 'utf-8'))
print(v[0])
print(v[1])
print(v[2])
print("\n")
# -------------------------
# round(x[, n]) --- 方法返回浮点数x的四舍五入值。
print(round(10.2565, 2))
# 17. help() --- 用于查看删除活模块的用途的详细说明
print(help('sys'))
print("\n")
# print(help('str'))
# --------------------------
# dir() --- 不带参数时,返回当前范围内的变量、方法和定义的类型列表;
# 带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。
# 如果参数不包含__dir__(),该方法将最大限度地收集参数信息。
print("dir返回:", dir())
print("\n")
# id() --- 用于获取对象的内存地址
id_1 = '1'
id_2 = 1
id_3 = 4
print("%s 的内存id为:%s" % (id_1, id(id_1)))
print("%s 的内存id为:%s" % (id_2, id(id_2)))
print("%s 的内存id为:%s" % (id_3, id(id_3)))
print("\n")
五:面向对象编程
面向对象(Object Oriented)设计思想贯穿程序设计,面向对象编程(Object Oriented Programming)是针对大型软件设计提出的,它能使代码更好滴复用,使程序更加的灵活。**对象** 是一个抽象的概念,万事万物皆可对象。对象通常可划分为两个部分,**静态部分** 和 **动态部分** ;【静态部分】称之为 **属性**,【动态部分】称为 **方法** 。
面向对象编程中,将函数和变量进一步封装成类,类才是程序的基本元素,它将数据和操作紧密连接,并保护数据不被外界意外改变。
#####面向对象术语
面向对象中的相关术语整理如下:
(1)类(class):用来描述具有相同【属性】和【方法】的对象集合,定义了该集合中每个对象所共有的属性和方法,其中对象被称为类的实例;
(2)实例:也称对象,通过类定义的初始化方法赋予具体的值;
(3)实例化:创建类的实例的过程;
(4)实例变量:定义在实例中的变量,只作用于当前实例;
(5)类变量:类变量是所有实例公有的变量。类变量定义在类中,但在方法体之外
(6)数据成员:类变量、实例变量、方法、类方法、静态方法和属性等的统称;
(7)方法:类中定义的函数;
(8)静态方法:不需要实例化就可以有类执行的方法;
(9)类方法:类方法是将类本身作为对象进行操作的方法;
(10)方法重写:从父类继承的方法不能满足子类的需求,可对父类的方法进行重写;
(11)继承:一个派生类继承父类的变量和方法;
(12)多态:根据对象类型的不同以不同的方式进行处理
# (1)类
class OOPObject(object):
# (5)类变量:定义在类中,方法之外的变量
phone = 123456789
address = "memory"
# __init__方法的类在实例化的时候,会自动调用该方法,并传递对应的参数
def __init__(self, name, age):
# (4)实例变量,name 和 age就是实例变量
self.name = name
self.age = age
# (7)实例方法
def o_method(self):
print("{0}:{1}".format(self.name, self.age))
# (8)静态方法:不需要实例化就可以有类执行的方法
@staticmethod
def static_method():
print("我是静态方法")
# (9)类方法:类方法是将类本身作为对象进行操作的方法
# 采用@classmethod装饰,至少传入一个cls(指类本身,类似于self)参数。
# 执行类方法时,自动将调用该方法的类赋值给cls。
# 使用类名.类方法的调用方式(也可以使用实例名.类方法的方式调用)
@classmethod
def class_method(cls):
print("我是类方法")
# (2)实例
# (3)实例化---这个过程
o1 = OOPObject("oj", 23)
# 实例方法的调用
o1.o_method()
# (6)数据成员:类变量、实例变量、方法、类方法、静态方法和属性等的统称
# (8)静态方法的调用
OOPObject.static_method()
# 类方法
OOPObject.class_method()
面向对象的三大特征:封装、继承、多态
封装是指将数据或具体操作的代码放在某个对象内部。使这些代码的实现细节不被外界发现,外界只能通过接口访问该对象(外界也不能直接访问类的变量和方法),而不能通过任何形式修改对象内部的实现。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : 62_OOPFeatures.py
@Time : 2019/8/14 15:15
@Author : Crisimple
@Github : https://crisimple.github.io/
@Contact : Crisimple@foxmail.com
@License : (C)Copyright 2017-2019, Micro-Circle
@Desc : None
"""
class ThisClass(object):
class_name = 'This class'
class_age = 12
def __init__(self, name, age):
self.name = name
self.age = age
def print_class(self):
print("{0}:{1}".format(self.name, self.age))
# 这就说明:外部不能直接调用类变量和类方法
# print(class_name) NameError: name 'class_name' is not defined
# print_class() NameError: name 'print_class' is not defined
# 使用:类名/实例名.变量/方法,来访问类的变量或方法
print(ThisClass.class_name)
ThisClass.class_name = 'Change name value'
print(ThisClass.class_name)
ThisClass.class_add_attribute = 'Test add attribute'
print(ThisClass.class_add_attribute)
tc = ThisClass('A', 23)
print(tc.print_class())
继承实现了代码的复用,多个类公用的代码可以只在一个类中提供,其他类只需集成这个类即可。继承最大的好处就是 子类(新定义的类) 获得了 父类(被继承的类也可成为基类或超类) 的全部变量和方法同时,又可以根据需求进行修改和扩展。 继承又分为两类:实现继承(使用基类的属性和方法无需额外编码的能力) 和 接口继承(仅使用属性和方法的名称,子类必须提供实现的能力,即子类重构父类方法)。
构造方法的继承
(1)经典继承的写法:父类名称.__init__(self, 参数1, 参数2)
(2)新式类的写法:super(子类, self).__init__(self, 参数1,参数2)
实例化对象b ---> b调用子类的构造方法__init__() ---> 子类的构造方法__init__()继承父类的构造方法__init__() ---> 调用父类的构造方法__init__()
class FatherClass(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.country = 123
def father_method(self):
print('father is walking')
class BoyClass(FatherClass):
# 先继承再重构,反着来子类就不能继承父类的属性了
def __init__(self, name, age, sex):
# 继承父类的构造方法
# 经典继承
# FatherClass.__init__(self, name, age)
# 新式类继承
super(BoyClass, self).__init__(name, age)
# 定义子类本身的属性
self.sex = sex
def child_method(self):
print('child is walking')
class GirlClass(FatherClass):
pass
# 子类构造方法继承父类构造方法过程如下:
# 实例化对象b ---> b调用子类的构造方法__init__() ---> 子类的构造方法__init__()继承父类的构造方法__init__() ---> 调用父类的构造方法__init__()
b = BoyClass('Boy', 25, 'male')
print(b.name)
print(b.age)
print(b.sex)
print(b.country)
子类对父类方法的重写:如果要对父类的方法进行修改,而又不影响其他继承父类的类,我们可以再子类中重构该方法.
# 2.继承
class FatherClass(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.country = '中国'
def father_method(self):
print('father is walking')
def talk(self):
print("I'am father. %s" % self.name)
class BoyClass(FatherClass):
# 先继承再重构,反着来子类就不能继承父类的属性了
def __init__(self, name, age, sex):
# 继承父类的构造方法
# 经典继承
# FatherClass.__init__(self, name, age)
# 新式类继承
super(BoyClass, self).__init__(name, age)
# 定义子类本身的属性
self.sex = sex
print(self.name, self.age, self.country, self.sex)
def child_method(self):
print('child is walking...')
def talk(self):
print("I'am child. %s" % self.name)
class GirlClass(FatherClass):
pass
# 2.1 构造方法继承
# 子类构造方法继承父类构造方法过程如下:
# 实例化对象b ---> b调用子类的构造方法__init__() ---> 子类的构造方法__init__()继承父类的构造方法__init__() ---> 调用父类的构造方法__init__()
b = BoyClass('Boy', 25, 'male')
print(b.name)
print(b.age)
print(b.sex)
print(b.country)
# 2.2 子类重写父类方法
f = FatherClass('A', 30)
f.talk()
b.talk()
多态是指一类事物具有多种形态。Python的多态性是指在不考虑实例类型的情况使用实例,也就是说不同类型的实例有相同的调用方法。
好处:
(1)增加了程序的灵活性:以不变应万变,不论对象千变万化,使用同一种形式去调用,如show_say(animal)
(2)增加了程序的可扩展性:通过继承Animal(下面代码例子)类创建了一个新的类,使用者无需更改自己的代码,还是用show_say(animal)方法去调用。
class Animal(object): # 同一类事物:动物
def say(self):
print("I'm animal.")
class Dog(Animal): # 动物的形态之一:狗
def say(self):
print("Wang wang~")
class Cat(Animal): # 动物的形态之一:猫
def say(self):
print("Miao miao~")
class Cow(Animal): # 动物的形态之一:牛
def say(self):
print("Mou mou~")
d = Dog()
ca = Cat()
co = Cow()
# d, ca, co 都是动物,都属于动物类,肯定都有say_hi()方法,因此不用考虑他们具体是什么类型,直接使用即可
d.say()
ca.say()
co.say()
# 我们可以统一一个接口来调用动物类的say_hi()方法
def show_say(animal):
animal.say()
show_say(d)
show_say(ca)
show_say(co)
元类
Python中一切皆对象,那么我们用class关键字定义的类本身也是一个对象,负责产生该对象的类称之为元类。
学习元类是为了控制类的产生过程,还能控制对象的产生过程
渐入元类
类对象可以用class关键字创建,类对象的类型是 type,也就是说可以通过 type(元类)来创建。
# 默认的元类type实例化出一个对象Foo,实例化的结果也是一个对象
class Foo(object):
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print("%s is eating." % self.name)
f1 = Foo('mi', 9)
number = 12
dicts = {
"name": "crisimple",
"age": 23
}
print("number的ID是:", id(number))
print("dicts的ID是:", id(dicts))
print("number的type是:", type(number))
print("dicts的type是:", type(dicts))
print("Foo的ID是:", id(Foo))
print("Foo的type是:", type(Foo)) # Foo的type是: <class 'type'>
print("f1的ID是:", id(f1))
print("f1的type是:", type(f1)) # f1的type是: <class '__main__.Foo'>
# --------------------------------------
# instance ---[instance of]---> class ---[instance of]---> metaclass
# f1 ----------------> Foo --------------> type【type就是元类,元类自己也是对象】
Person = type("Person", (object, ), {"live": True, "name": 'crisimple'})
print(type(Person))
p1 = Person()
print(type(p1))
用元类创建类
Person = type("Person", (object, ), {"live": True, "name": 'crisimple'})
print(type(Person))
p1 = Person()
print(type(p1))
序列的概念,字符串的定义和常用操作,元组与列表定义和常用操作
序列:它的成员都是有序排列,并且可以通过小标偏移量访问到它的一个或几个成员.三种类型包括字符串("abcd"),列表([0,"abcd]).元组(("abc","def"))
列表与元组的区别,一个是[]一个是(),另外就是列表数据可变更,元组不可以.
编程思路:我们遇到什么问题,这个问题在现实生活中以什么方式解决,在编程思路中如何解决.
序列的基本操作:成员关系操作符(in,not in),连接操作符(+),重复操作符(*),切片操作符([:])
元组的大小比较:(1,20) > (2,20)相对于120 > 220 输出false
append()方法:增加.remove方法:减少
条件语句,for循环,while循环,for循环与while循环语句中的if嵌套,字典的定义和常用操作,列表推导式与字典推导式
#If语句
a = '1234567890'
b = int(input('输入年份'))
if (a[b % 12]) == '7':
print('Number is 7')
else:
print("Number is not 7")
#for语句
for aa in a:
print(aa)
#遍历1-12
for i in range(1,13):
print(i)
#while语句
num = 5
while True:
num = num +1
if num == 10:
continue
print(num)
tiem.sleep(1)
break
{"哈希值":"对象"} {'length':180,'width':80}
ditc1 = {}
print(type(ditc1))
#字典定义
dict2 = {'a':1,'b':2}
#字典增加
dict2['c'] = 3
print(dict2)
#计算1到10的平方
alist = []
for i in range(1,11):
if (i % 2 == 0):
alist.append(i*i)
print(alist)
#计算1到10的平方
#列表推导式
blist = [i*i for i in range(1,11) if (i % 2) ==0]
print(blist)
#字典推导式
略
文件的内建函数,文件的常用操作,异常检查和处理
#对文件进行基本的读写操作,以下是内置函数
#open()打开文件
#read()输入
#readline()输入一行
#seek()文件内移动
#write()输出
#close()关闭文件
#将小说的人物记录在文件中
#open('name.txt')默认只读方式写入
file1 = open('name.txt','w')
file1.write('诸葛亮')
file1.close()
#读取文件
file2 = open('name.txt')
print(file2 .read())
file2.close()
#写入文件
file3 = open('name.txt','a')
file3.write('刘备')
#文件常用操作
#进行逐行处理
file1 = open('name.txt')
for line in file1.readlines():
print(line)
print('=====')
file2 = open('name.txt')
print(file2.tell()) #告诉用户文件指针在哪
file2.read(1) #指针到1,下一行时打印输出
print(file2.tell())
file2.seek(0) #seek()方法指定相对位置
print(file2.tell())
#seek()方法的第一个参数保湿偏移位置,第二个参数表示 0表示从文件开头偏移 1表示从当其位置偏移 2从文件结尾
file2.seek(5,0)
print(file2.tell())
#异常的检测与处理,错误不等于异常,异常是在出现错误时采用正常控制流以外的动作,一般流程是检测到错误,引发异常,对异常进行捕获操作。
try:
<监控异常>
except Exception[,resson]:
<异常处理代码>
finally:
<无论异常是否发生都执行>
#捕获异常
try:
year = int(input('input year:'))
except ValueError:
print('年份要输入数字')
常见错误: (1)SyntaxError: unmatched 语法错误
函数的定义与常用操作,函数的可变长参数,函数的变量作用域,函数的迭代器与生成器.
#函数是对程序逻辑进行结构化的一种编程方法
#函数的定义: def 函数名(): code return 需要返回的内容
#函数的调用:函数名称()
def func(filename):
print(open(filename).read())
print('test func')
func('name.txt')
函数的可变参数
def funca (a, b, c):
print('a= %s' %a)
print('b= %s' %b)
print('c= %s' %c)
funca(1,2,c=5)
#取得参数的个数
def howlong(first, *other):
print( 1+len(other))
howlong(100)
#函数作用域
var1 = 123
def funcb():
print(var1)
funcb()
print(var1)
#函数的迭代器与生成器
list1 = [1,2,3,4,5]
it = iter(list1)
print(next(it))#next一直迭代到全部读取完,再读取就会报错
print(next(it))
#生成器
for i in range(10,20,2):
print(i)
def demoab(start,stop,step):
x = start
while x<stop:
yield x
x +=step
for ia in demoab(10,20,0.5):
print(ia)
Lambds表达式,Python内置函数,闭包的定义与使用,装饰器的定义与使用,自定义上下文管理器.模块的定义
def add(x,y):
return x+y
#lambda表达式
lambda x,y: x+y
#Python内置函数
filter(),map(),reduce(),zip()
a= [1,2,3,4,5,6,7]
print(list(filter(lambda x:x>2,a)))
print(list(map(lambda x:x+1,a)))
#print(list(reduce(lambda x,y: x+y,[2,3,4],1)))
for i in zip((1,2,3),(4,5,6)):
print(i)
#闭包,内部函数引用外部变量
def counter():
cnt = [0]
def add_one():
cnt[0] +=1
return cnt[0]
return add_one
num1 = counter()
print(num1())
#装饰器
import time
def timmer(func):
def wrapper():
start_time = time.time()
func()
stop_time = time.time()
print("运行时间是 %秒" % (stop_time - start_time))
return wrapper
@timmer
def i_can_sleep():
time.sleep(3)
##上下文管理器
fd = open('name.txt')
try:
for line in fd:
print(line)
finally:
with open('name.txt') as f:
for line in f:
print(line)
#模块
import 模块名称
form 模块名称 import 方法名
#PEP8代码规范
在cmd中输入$ pip install autopep8
之后https://blog.csdn.net/qq_42451716/article/details/80998216
正则表达式
正则表达式常用的函数
re.match() 从字符串的起始位置开始匹配,匹配成功返回一个匹配的对象,否则返回None
re.search() 扫描整个字符串并返回第一个成功匹配的
re.findall() 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表;如果没有找到则返回一个空列表
re.split() 将字符串按正则表达式匹配结果进行分割,返回列表类型
re.finditer() 在字符串中找到正则表达式所匹配的所有字串,并将所有字串的结果作为一个迭代器返回
re.sub() 将字符串中所有匹配的正则表达式的地方替换成新的字符串
多进程编程
为保证并发能力,将一个单独的CPU变成多个虚拟的CPU(多道技术:时间多路复用和空间多路复用+硬件上支持隔离)。
进程:正在进行的一个过程或一个任务,负责任务的是CPU;同一程序执行两次,那也就是两个进程,比如打开两个chrome浏览器,一个看学习视频,一个写学习笔记。
并发:是伪并行,看起来是同时运行,单个CPU+多道技术就可以实现并发.
并行:同时运行,具有多个CPU才能实现并行。
开启子进程的两种方式
1.multiprocessing模块
multiprocess模块用来开启子进程,并在子进程中执行我们定制的任务(如函数),支持子进程、通信和共享数据,执行不同形式的同步,提供了Process、Queue、Pipe、Lock 等组件;与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于改进程内。
2.Process类
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动) 强调: 1. 需要使用关键字的方式来指定参数 2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号。
参数介绍:
group参数未使用,值始终为None
target表示调用对象,即子进程要执行的任务
args表示调用对象的位置参数元组,args=(1,2,'egon',)
kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
name为子进程的名称
方法介绍:
p.start():启动进程,并调用该子进程中的p.run()
p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
p.is_alive():如果p仍然运行,返回True
p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
属性介绍:
p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
p.name:进程的名称
p.pid:进程的pid
from multiprocessing import Process
import time
import random
import os
def task(name):
print("%s is running..." % name)
time.sleep(random.randrange(1, 5))
print("%s is done..." % name)
# 第二种创建子进程的方法
class MyProcess(Process):
def __init__(self, name):
super().__init__() # 将父类的功能进行重用
self.name = name
# start将调用这个run方法
def run(self) -> None:
print("%s %s is running..., parent id is %s" % (self.name, os.getpid(), os.getppid()))
time.sleep(3)
print("%s %s is done-----, parent id is %s" % (self.name, os.getpid(), os.getppid()))
if __name__ == "__main__":
# 第一种方式
p1 = Process(target=task, args=("A", ))
p2 = Process(target=task, args=("B", ))
p3 = Process(target=task, args=("C", ))
p4 = Process(target=task, args=("D", ))
# 只是给操作系统发送了一个信号,由操作系统将父进程地址空间中的数据拷贝给子进程,作为子进程运行的初始状态,开启后再运行task
p1.start()
p2.start()
p3.start()
p4.start()
print('主1......', os.getpid(), os.getppid())
# 执行结果:执行结果因为执行进程会有一段时间,所以先做打印操作
# --------------------
# 主
# 任务名称 is running...
# 任务名称 is done...
p = MyProcess('子进程2')
p.start()
# os.getpid() --- 查看子进程的id
# os.getppid() --- 查看父进程的id
print('主2......', os.getpid(), os.getppid())
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。