matplotlib 动态图怎么实现图的动态更新

matplotlib可视化之如何给图形添加数据标签? - 简书
matplotlib可视化之如何给图形添加数据标签?
当我们获取完数据之后,一般来说数据可视化呈现的最基础图形就是:柱状图、水平条形图、折线图等等,在python的matplotlib库中分别可用bar、barh、plot函数来构建它们,再使用xticks与yticks(设置坐标轴刻度)、xlabel与ylabel(设置坐标轴标签)、title(标题)、legend(图例)、xlim与ylim(设置坐标轴数据范围)、grid(设置网格线)等命令来装饰图形,让它更明晰与美观,但是对于数据标签(即在图形中的每一个点或条形位置上标注出相应数值),却没有直接的命令导出。我们看很多python可视化做出的柱状图等等,在柱子数量不多的条件下,没有数据标签,只有光秃秃的一个个柱子,这样就使得图形缺了些什么。事实上,在python的matplotlib中有在图形中添加文字说明的命令——text,我们就可以利用这个命令,在图中每个单位要素中添加相应文字,来构造数字标签。以本人专栏写的《大数据时代,哪些课程最受欢迎?》所爬取数据为例,经过numpy得到了不同课程类别下的平均学习人数,如图:
v2-436583cccc6aaf0bcf45_b.png
plt.figure(figsize=(10,6))
#设置x轴柱子的个数
x=np.arange(14)+1 #课程品类数量已知为14,也可以用len(ppv3.index)
#设置y轴的数值,需将numbers列的数据先转化为数列,再转化为矩阵格式
y=np.array(list(ppv3['numbers']))
xticks1=list(ppv3.index) #构造不同课程类目的数列
#画出柱状图
plt.bar(x,y,width = 0.35,align='center',color = 'c',alpha=0.8)
#设置x轴的刻度,将构建的xticks代入,同时由于课程类目文字较多,在一块会比较拥挤和重叠,因此设置字体和对齐方式
plt.xticks(x,xticks1,size='small',rotation=30)
#x、y轴标签与图形标题
plt.xlabel('课程主题类别')
plt.ylabel('number')
plt.title('不同课程类别的平均学习人数')
**#设置数字标签**
**for a,b in zip(x,y):**
** plt.text(a, b+0.05, '%.0f' % b, ha='center', va= 'bottom',fontsize=7)**
#设置y轴的范围
plt.ylim(0,3700)
plt.show()
最终得到的图形为:
不同类别学习人数.png
着重讲一下如何设置数字标签#设置数字标签
for a,b in zip(x,y):
plt.text(a, b+0.05, '%.0f' % b, ha='center', va= 'bottom',fontsize=7)
首先,前边设置的x、y值其实就代表了不同柱子在图形中的位置(坐标),通过for循环找到每一个x、y值的相应坐标——a、b,再使用plt.text在对应位置添文字说明来生成相应的数字标签,而for循环也保证了每一个柱子都有标签。
其中,a, b+0.05表示在每一柱子对应x值、y值上方0.05处标注文字说明, '%.0f' % b,代表标注的文字,即每个柱子对应的y值, ha='center', va= 'bottom'代表horizontalalignment(水平对齐)、verticalalignment(垂直对齐)的方式,fontsize则是文字大小。
条形图、折线图也是如此设置,饼图则在pie命令中有数据标签的对应参数。对于累积柱状图、双轴柱状图则需要用两个for循环,同时通过a与b的不同加减来设置数据标签位置,比如在本文另一文章[《双十一预售战下的电商风云》]() ,如图:
电商平台商品评价.png
其命令为:
电商代码.png
统计类专业,喜欢数据分析、可视化、数据挖掘、大数据,历史、文学等3578人阅读
python学习(1)
近期经常使用matplotlib进行数学函数图的绘制,但是如何使用matplotlib绘制动态图,以及绘制动态多图,直到今天才学会。
1.参考文字&
首先感谢几篇文字的作者,帮我学会了如何绘制,大家也可以参考他们的文字。
:文字作者给出了数个示例的源码,但是没有很详细的讲解,源码面前无秘密,自己看吧。:这位作者的讲解很详细,主要讲了matplotlib官方示例,大家可以参阅。
:这位作者,给出了不同的示例,而且非常详细,告诉了大家如何一步步学习Matplotlib绘图:用Python做科学计算,很好很详实的书。
2.程序源码
先贴出程序源码,在一步步做解释。
&span style=&font-family:SimSfont-size:10&&import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
# first set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1,xlim=(0, 2), ylim=(-4, 4))
ax2 = fig.add_subplot(2,1,2,xlim=(0, 2), ylim=(-4, 4))
line, = ax1.plot([], [], lw=2)
line2, = ax2.plot([], [], lw=2)
def init():
line.set_data([], [])
line2.set_data([], [])
return line,line2
# animation function.
this is called sequentially
def animate(i):
x = np.linspace(0, 2, 100)
y = np.sin(2 * np.pi * (x - 0.01 * i))
line.set_data(x, y)
x2 = np.linspace(0, 2, 100)
y2 = np.cos(2 * np.pi * (x2 - 0.01 * i))* np.sin(2 * np.pi * (x - 0.01 * i))
line2.set_data(x2, y2)
return line,line2
anim1=animation.FuncAnimation(fig, animate, init_func=init,
frames=50, interval=10)
plt.show()
现在就来解释下,这个程序我究竟干了啥
3.1建立子图、空白线
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1,xlim=(0, 2), ylim=(-4, 4))
ax2 = fig.add_subplot(2,1,2,xlim=(0, 2), ylim=(-4, 4))
line, = ax1.plot([], [], lw=2)
line2, = ax2.plot([], [], lw=2)
在上面的程序可以看到,先建立了一个figure对象,之后fig.add_subplot(2,1,1,xlim=(0, 2), ylim=(-4, 4))就是建立子图,关于子图的概念和做法,大家可以参阅下文字【4】“用Python做科学计算”关于子图的介绍。
3.2创建动画发生时调用的函数
Init()是我们的动画在在创建动画基础框架(base frame)时调用的函数。这里我们们用一个非常简单的对line什么都不做的函数。这个函数一定要返回line对象,这个很重要,因为这样就能告诉动画之后要更新的内容,也就是动作的内容是line。--来自()
上面的这段话,解释了Init()这个函数是干嘛的,因为我的程序比较特殊,希望能够在一张图中显示两个子图,如图3.1。所以我必须在两个坐标轴ax1和ax2中创建两个空白的线line,line2且在Init()中返回这两个Line。
def init():
line.set_data([], [])
line2.set_data([], [])
return line,line2
3.3动画函数
接下来你需要一个动画函数,在这个动画函数中修改你的图,同样的我需要一张图中显示两个东西,所以在动画函数中,我更新了两个图,且返回了line和line2
def animate(i):
x = np.linspace(0, 2, 100)
y = np.sin(2 * np.pi * (x - 0.01 * i))
line.set_data(x, y)
x2 = np.linspace(0, 2, 100)
y2 = np.cos(2 * np.pi * (x2 - 0.01 * i))* np.sin(2 * np.pi * (x - 0.01 * i))
line2.set_data(x2, y2)
return line,line2
3.4显示动画
最后你需要用如下的两个语句来显示动画,这里有个注意的地方,需要调整interval参数(这个参数指明了时间间隔)的大小,不然会出现如图3.2一样的情况(当你使用了,blit=True这个选项)。
同时()给我们说明了几个参数的作用,我在不在复述:
这个对象需要持续存在,所有我们要将它赋给一个变量,我们选择了一个100帧的动画(译者注:你上边的代码还是200帧,怎么到这儿就变成100帧了……,另外,这里也不一定一定要是个数字,可以是个generator 或iterable,详见API说明)并且帧与帧之间间隔20ms,blit是一个非常重要的关键字,它告诉动画只重绘修改的部分,结合上面保存的时间,
blit=true会使动画显示得会非常非常快。
anim1=animation.FuncAnimation(fig, animate, init_func=init,
frames=50, interval=10)
plt.show()
上面的工作解释完了,来看看成果。程序写的不好,我也是才初学,希望看到博客的人,能多多给我指教,不胜感激。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:63090次
排名:千里之外
原创:21篇
转载:37篇
(1)(1)(6)(2)(9)(10)(15)(4)(3)(3)(1)(1)(2)[转载]利用Python进行数据分析——绘图和可视化(八)(1)
已有 50089 次阅读
|个人分类:|系统分类:|文章来源:转载
Python有许多可视化工具,但是我主要讲解matplotlib()。此外,还可以利用诸如d3.js()之类的工具为Web应用构建交互式图像。matplotlib是一个用于创建出版质量图表的桌面绘图包(主要是2D方面)。该项目是由John Hunter于2002年启动的,其目的是为Python构建一个MATLAB式的绘图接口。如果结合使用一种GUI工具包(如IPython),matplotlib还具有诸如缩放和平移等交互功能。它不仅支持各种操作系统上许多不同的GUI后端,而且还能将图片导出为各种常见的矢量(vector)和光栅(raster)图:PDF、SVG、JPG、PNG、BMP、GIF等。matplotlib还有许多插件工具集,如用于3D图形的mplot3d以及用于地图和投影的basemap。要使用本章中的代码示例,请确保你的IPython是以Pylab模式启动的(ipython &--pylab),或通过%gui魔术命令打开了GUI事件循环集成。1、matplotlib API入门使用matplotlib的办法有很多种,最常用的方式是Python模式的IPython(ipython &-pylab)。这样会将IPython配置为使用你所指定的matplotlib GUI后端(Tk、wxPython、PyQt、Mac OS X native、GTK)。对大部分用户而言,默认的后端就已经够用了。Pylab模式还会向IPython引入一大堆模块和函数以提供一种更接近于MATLAB的界面。绘制一张简单的图表即可测试是否一切准备就绪:如果一切都没有问题,就会弹出一个新窗口,其中绘制的是一条直线。你可以用鼠标或输入close()来关闭它。matplotlib API函数(如plot和close)都位于matplotlib.pyllot模块中,其通常的引入约定是:[python]&虽然pandas的绘图函数能够处理许多普通的绘图任务,但如果需要自定义一些高级功能的话就必须学习matplotlib API。matplotlib的示例库和文档是成为绘图高手的最佳学习资源。2、Figure和Subplotmatplotlib的图像都位于Figure对象中。你可以用plt.figure创建一个新的Figure:[python]&这时会弹出一个空窗口。plt.figure有一些选项,特别是figsize,它用于确保当图片保存到磁盘时具有一定的大小和纵横比。matplotlib中的Figure还支持一种MATLAB式的编号架构(如plt.figure(2))。通过plt.gcf()即可得到当前Figure的引用。不能通过空Figure绘图。必须用add_subplot创建一个或多个subplot才行:[python]&这条代码的意思是:图像应该是22的,且当前选中的是4个subplot中的第一个(编号从1开始)。如果再把后面两个subplot也创建出来,最终得到的图像如下所示:如果这时发出一条绘图命令哪个(如plt.plot([1.5, 3.5, -2, 1.6])),matplotlib就会在最后一个用过的subplot(如果没有则创建一个)上进行绘制。因此,如果我们执行下列命令,你就会得到如下所示的效果:“k--”是一个线型选项,用于告诉matplotlib绘制黑色虚线图。上面那些由fig.add_subplot所返回的对象是AxesSubplot对象,直接调用它们的实例方法就可以在其他空着的格子里面画图了,如下所示:[python]&你可以在matplotlib的文档中找到各种图标类型。由于根据特定布局创建Figure和subplot是一件非常常见的任务,于是便出现了一个更为方便的方法(plt.subplots),它可以创建一个新的Figure,并返回一个含有已创建的subplot对象的NumPy数组:[python]&这是非常实用的,因为可以轻松地对axes数组进行索引,就好像是一个二维数组一样,例如,axes[0, 1]。你还可以通过sharex和sharey指定subplot应该具有相同的X轴或Y轴。在比较相同范围的数据时,这也是非常实用的,否则,matplotlib会自动缩放各图表的界限。3、调整subplot周围的间距默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关,因此,如果你调整了图像的大小(不管是编程还是手工),间距也会自动调整。利用Figure的subplots_adjust方法可以轻而易举地修改间距,此外,它也是个顶级函数:[python]&wspace和hspace用于控制宽度和高度的百分比,可以用作subplot之间的间距。下面是一个简单的例子,我们将间距收缩到了0:不难看出,其中的轴标签重叠了。matplotlib不会检查标签是否重叠,所以对于这种情况,你只能自己设定刻度位置和刻度标签。4、颜色、标记和线型matplotlib的plot函数接受一组X和Y坐标,还可以接受一个表示颜色和线型的字符串缩写。例如,要根据x和y绘制绿色虚线,你可以执行如下代码:[python]&这种在一个字符串中指定颜色和线型的方式非常方便。通过下面这种更为明确的方式也能得到同样的效果:[python]&常用的颜色都有一个缩写词,要使用其他任意颜色则可以通过指定其RGB值的形式使用(例如,'#CECECE')。完整的linestyle列表请参见plot的文档。线型图还可以加上一些标记(marker),以强调实际的数据点。由于matplotlib创建的是连续的线型图(点与点之间插值),因此有时可能不太容易看出真实数据点的位置。标记也可以放到格式字符串中,但标记类型和线型必须放在颜色后面。[python]&还可以将其写成更为明确的形式:[python]&在线型图中,非实际数据点默认是按线性方式插值的。可以通过drawstyle选项修改:[python]&5、刻度、标签和图例对于大多数的图表装饰项,其主要实现方式有二:使用过程型的pyplot接口以及更为面向对象的原生matplotlib API。pyplot接口的设计目的就是交互式作用,含有诸如xlim、xticks和xticklabels之类的方法。它们分别控制图表的范围、刻度位置、刻度标签等。其使用方式有以下两种:调用时不带参数,则返回当前的参数值。例如,plt.xlim()返回当前的X轴绘图范围。调用时带参数,则设置参数值。因此,plt.xlim([0, 10])会将X轴的范围设置为0到10。所有这些方法都是对当前或最近创建的AxesSubplot起作用的。它们各自对应subplot对象上的两个方法,以xlim为例,就是ax.get_xlim和ax.set_xlim。我更喜欢使用subplot的实例方法,当然你完全可以选择自己觉得方便的那个。(1)设置标题、轴标签、刻度以及刻度标签为了说明轴的自定义,我将创建一个简单的图像并绘制一段随机漫步:[python]&要修改X轴的刻度,最简单的办法是使用set_xticks和set_xticklabels。前者告诉matplotlib要将刻度放在数据范围中的哪些位置,默认情况下,这些位置也就是刻度标签。但我们可以通过set_xticklabels将任何其他的值用作标签:[python]&说明:Y轴的修改方式与此类似,只需将上述代码中的x替换为y即可。(2)添加图例图例(legend)是另一种用于标识图表元素的重要工具。添加图例的方式有二。最简单的是在添加subplot的时候传入label参数:[python]&在此之后,你可以调用ax.legend()或plt.legend()来自动创建图例:[python]&loc告诉matplotlib要将图例放在哪。如果你不是吹毛求疵的话,“best”是不错的选择,因为它会选择最不碍事的位置。要从图例中去除一个或多个元素,不传入label或传入label='_nolegend_'即可。
转载本文请联系原作者获取授权,同时请注明本文来自郭大龙科学网博客。链接地址:
上一篇:下一篇:
当前推荐数:0
评论 ( 个评论)
扫一扫,分享此博文
作者的其他最新博文
热门博文导读
Powered by
Copyright &15张图入门Matplotlib - 知乎专栏
{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"title":"15张图入门Matplotlib","author":"xianhu","content":"Matplotlib是Python中鼎鼎大名的画图库,在语法和架构上都参考与MATLAB。个人整理了该库中基础图形的画法,并做了相应的注释。Github地址:更详细的教程,还需要参考官方文档:。另外:学习Python基础请移步:学习Python爬虫基础请移步:图形较多,建议用电脑打开。示例图形包括:(1)简单的折线图:(2)Y轴范围不一致的折线图(2)Y轴范围不一致的折线图(3)子图的画法(3)子图的画法(4)简单的柱状图(4)简单的柱状图(5)水平方向的柱状图(6)更高级的柱状图(7)类表格图形(8)直方图(9)饼图(10)散点图(11)雷达图(11)雷达图(12)三维散点图(12)三维散点图(13)三维折线图(14)三维柱状图(14)三维柱状图(15)图形填充(15)图形填充","updated":"T08:40:19.000Z","canComment":false,"commentPermission":"anyone","commentCount":18,"collapsedCount":0,"likeCount":376,"state":"published","isLiked":false,"slug":"","lastestTipjarors":[],"isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-700dd6ea3e72ec8f21cb9d_r.jpg","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"Matplotlib"},{"url":"/topic/","id":"","name":"Python"},{"url":"/topic/","id":"","name":"数据可视化"}],"adminClosedComment":false,"titleImageSize":{"width":1216,"height":402},"href":"/api/posts/","excerptTitle":"","column":{"slug":"pythoner","name":"撸代码,学知识"},"tipjarState":"activated","tipjarTagLine":"真诚赞赏,手留余香","sourceUrl":"","pageCommentsCount":18,"tipjarorCount":0,"annotationAction":[],"snapshotUrl":"","publishedTime":"T16:40:19+08:00","url":"/p/","lastestLikers":[{"bio":null,"isFollowing":false,"hash":"8b70b237fd6a0cde977d80a9dce8599f","uid":04,"isOrg":false,"slug":"pu-jian-34","isFollowed":false,"description":"","name":"蒲坚","profileUrl":"/people/pu-jian-34","avatar":{"id":"3325cf98a","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"当时浣纱伴,莫得同车归。","isFollowing":false,"hash":"ece2994daca5dd6b315cc265c4ea07a3","uid":88,"isOrg":false,"slug":"chuman","isFollowed":false,"description":"","name":"chuman","profileUrl":"/people/chuman","avatar":{"id":"c19cf8c386ce010a90a530e","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"ca9c73abed","uid":40,"isOrg":false,"slug":"han-da-bing-21","isFollowed":false,"description":"","name":"Roosie","profileUrl":"/people/han-da-bing-21","avatar":{"id":"e08c0d2a36b3a9ca3e1c0d","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"31eb4afb0d1af0c42b29b","uid":026600,"isOrg":false,"slug":"wang-er-xiao-61-32","isFollowed":false,"description":"","name":"王二小","profileUrl":"/people/wang-er-xiao-61-32","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"数据挖掘机","isFollowing":false,"hash":"1d76afcb17c702c471a16fe1b01bfe27","uid":88,"isOrg":false,"slug":"ai-ai-12-85","isFollowed":false,"description":"世界观重建中","name":"呆呆","profileUrl":"/people/ai-ai-12-85","avatar":{"id":"a803fc804ff","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"Matplotlib是Python中鼎鼎大名的画图库,在语法和架构上都参考与MATLAB。个人整理了该库中基础图形的画法,并做了相应的注释。Github地址:更详细的教程,还需要参考官方文档:","reviewingCommentsCount":0,"meta":{"previous":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-d6abeaf0cf7bb7b75d19f398_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"Python"},{"url":"/topic/","id":"","name":"Python 入门"},{"url":"/topic/","id":"","name":"数据分析"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"Python爱好者,关注爬虫、数据分析、数据挖掘、数据可视化等","isFollowing":false,"hash":"890bef55fb","uid":405600,"isOrg":false,"slug":"xianhu","isFollowed":false,"description":"不想当产品的程序员不是好的数据分析师!","name":"笑虎","profileUrl":"/people/xianhu","avatar":{"id":"7e0dcfc42ad","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"content":"github地址:很多人反应打不开,可能是因为网速的原因。内容较多,耐心等待一会!============================================================自己以代码的形式整理的Python入门文档,不算空行、注释等,应该不到一千行。认认真真读完、练习完这些代码,应该就能上手工作了。可能在网页上显示的效果不理想,可以手动复制下来粘贴到文本文件中,利用notepad++等文本编辑器查看。以后还会不定时以代码的形式发布一些关于Python的教程。# _*_ coding: utf-8 _*_\n\n\"\"\"类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算\"\"\"\n\n#-- 寻求帮助:\n
# 简单的列出对象obj所包含的方法名称,返回一个字符串列表\n
help(obj.func)
# 查询obj.func的具体介绍和用法\n
\n#-- 测试类型的三种方法,推荐第三种\n
if type(L) == type([]): print(\"L is list\")\n
if type(L) == list: print(\"L is list\")\n
if isinstance(L, list): print(\"L is list\")\n
\n#-- Python数据类型:哈希类型、不可哈希类型\n
# 哈希类型,即在原地不能改变的变量类型,不可变类型。可利用hash函数查看其hash值,也可以作为字典的key\n
\"数字类型:int, float, decimal.Decimal, fractions.Fraction, complex\"\n
\"字符串类型:str, bytes\"\n
\"元组:tuple\"\n
\"冻结集合:frozenset\"\n
\"布尔类型:True, False\"\n
\"None\"\n
# 不可hash类型:原地可变类型:list、dict和set。它们不可以作为字典的key。\n
\n#-- 数字常量\n
1234, -1234, 0,
1.23, 1., 3.14e-10, 4E210, 4.0e+210
# 浮点数\n
0o177, 0x9ff, 0X9FF, 0b101010
# 八进制、十六进制、二进制数字\n
3+4j, 3.0+4.0j, 3J
# 复数常量,也可以用complex(real, image)来创建\n
hex(I), oct(I), bin(I)
# 将十进制数转化为十六进制、八进制、二进制表示的“字符串”\n
int(str, base)
# 将字符串转化为整数,base为进制数\n
# 2.x中,有两种整数类型:一般整数(32位)和长整数(无穷精度)。可以用l或L结尾,迫使一般整数成为长整数\n
float('inf'), float('-inf'), float('nan')
# 无穷大, 无穷小, 非数\n
\n#-- 数字的表达式操作符\n
# 生成器函数发送协议\n
lambda args: expression
# 生成匿名函数\n
x if y else z
# 三元选择表达式\n
x and y, x or y, not x
# 逻辑与、逻辑或、逻辑非\n
x in y, x not in y
# 成员对象测试\n
x is y, x is not y
# 对象实体测试\n
x&y, x&=y, x&y, x&=y, x==y, x!=y
# 大小比较,集合子集或超集值相等性操作符\n
# Python中允许连续比较\n
x|y, x&y, x^y
# 位或、位与、位异或\n
x&&y, x&&y
# 位操作:x左移、右移y位\n
+, -, *, /, //, %, **
# 真除法、floor除法:返回不大于真除法结果的整数值、取余、幂运算\n
-x, +x, ~x
# 一元减法、识别、按位求补(取反)\n
x[i], x[i:j:k], x(……)
# 索引、分片、调用\n
int(3.14),
# 强制类型转换\n
\n#-- 整数可以利用bit_length函数测试所占的位数\n
a.bit_length()
a.bit_length()
\n#-- repr和str显示格式的区别\n
repr格式:默认的交互模式回显,产生的结果看起来它们就像是代码。\n
str格式:打印语句,转化成一种对用户更加友好的格式。\n
\n#-- 数字相关的模块\n
# math模块\n
# Decimal模块:小数模块\n
import decimal\n
from decimal import Decimal\n
Decimal(\"0.01\") + Decimal(\"0.02\")
# 返回Decimal(\"0.03\")\n
decimal.getcontext().prec = 4
# 设置全局精度为4 即小数点后边4位\n
# Fraction模块:分数模块\n
from fractions import Fraction\n
x = Fraction(4, 6)
# 分数类型 4/6\n
x = Fraction(\"0.25\")
# 分数类型 1/4 接收字符串类型的参数\n\n#-- 集合set\n
set是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素。\n
set支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算。\n
set支持x in set, len(set), for x in set。\n
set不记录元素位置或者插入点, 因此不支持indexing, slicing, 或其它类序列的操作\n
s = set([3,5,9,10])
# 创建一个数值集合,返回{3, 5, 9, 10}\n
t = set(\"Hello\")
# 创建一个唯一字符的集合返回{}\n
t.union(s)
# t 和 s的并集\n
t.intersection(s)
# t 和 s的交集\n
c = t – s
t.difference(s)
# 求差集(项在t中, 但不在s中)
t.symmetric_difference(s)
# 对称差集(项在t或s中, 但不会同时出现在二者中)\n
t.add('x')
t.remove('H')
# 增加/删除一个item\n
t.update([10,37,42])
# 利用[......]更新s集合\n
x not in s
# 集合中是否存在某个值\n
s.issubset(t)
s.issuperset(t)
s.discard(x)
s.clear()\n
{x**2 for x in [1, 2, 3, 4]}
# 集合解析,结果:{16, 1, 4, 9}\n
{x for x in 'spam'}
# 集合解析,结果:{'a', 'p', 's', 'm'}\n
\n#-- 集合frozenset,不可变对象\n
set是可变对象,即不存在hash值,不能作为字典的键值。同样的还有list、tuple等\n
frozenset是不可变对象,即存在hash值,可作为字典的键值\n
frozenset对象没有add、remove等方法,但有union/intersection/difference等方法\n
a = set([1, 2, 3])\n
b = set()\n
# error: set是不可哈希类型\n
b.add(frozenset(a))
# ok,将set变为frozenset,可哈希\n\n#-- 布尔类型bool\n
type(True)
# 返回&class 'bool'&\n
isinstance(False, int)
# bool类型属于整形,所以返回True\n
True == 1, True is 1
# 输出(True, False)\n
\n#-- 动态类型简介\n
变量名通过引用,指向对象。\n
Python中的“类型”属于对象,而不是变量,每个对象都包含有头部信息,比如\"类型标示符\" \"引用计数器\"等\n
#共享引用及在原处修改:对于可变对象,要注意尽量不要共享引用!\n
#共享引用和相等测试:\n
L = [1], M = [1], L is M
# 返回False\n
L = M = [1, 2, 3], L is M
# 返回True,共享引用\n
#增强赋值和共享引用:普通+号会生成新的对象,而增强赋值+=会在原处修改\n
L = M = [1, 2]\n
L = L + [3, 4]
# L = [1, 2, 3, 4], M = [1, 2]\n
L += [3, 4]
# L = [1, 2, 3, 4], M = [1, 2, 3, 4]\n\n#-- 常见字符串常量和表达式\n
# 空字符串\n
S = \"spam’s\"
# 双引号和单引号相同\n
S = \"s\\np\\ta\\x00m\"
# 转义字符\n
S = \"\"\"spam\"\"\"
# 三重引号字符串,一般用于函数说明\n
S = r'\\temp'
# Raw字符串,不会进行转义,抑制转义\n
S = b'Spam'
# Python3中的字节字符串\n
S = u'spam'
# Python2.6中的Unicode字符串\n
s1+s2, s1*3, s[i], s[i:j], len(s)
# 字符串操作\n
'a %s parrot' % 'kind'
# 字符串格式化表达式\n
'a {0} parrot'.format('kind')
# 字符串格式化方法\n
for x in s: print(x)
# 字符串迭代,成员关系\n
[x*2 for x in s]
# 字符串列表解析\n
','.join(['a', 'b', 'c'])
# 字符串输出,结果:a,b,c\n
\n#-- 内置str处理函数:\n
str.upper()
str.lower()
str.swapcase()
str.capitalize()
str.title()
# 全部大写,全部小写、大小写转换,首字母大写,每个单词的首字母都大写\n
str.ljust(width)
# 获取固定长度,右对齐,左边不够用空格补齐\n
str.rjust(width)
# 获取固定长度,左对齐,右边不够用空格补齐\n
str.center(width)
# 获取固定长度,中间对齐,两边不够用空格补齐\n
str.zfill(width)
# 获取固定长度,右对齐,左边不足用0补齐\n
str.find('t',start,end)
# 查找字符串,可以指定起始及结束位置搜索\n
str.rfind('t')
# 从右边开始查找字符串\n
str.count('t')
# 查找字符串出现的次数\n
#上面所有方法都可用index代替,不同的是使用index查找不到会抛异常,而find返回-1\n
str.replace('old','new')
# 替换函数,替换old为new,参数中可以指定maxReplaceTimes,即替换指定次数的old为new\n
str.strip()
str.lstrip()
str.rstrip()
str.strip('d')
str.lstrip('d')
str.rstrip('d')\n
str.startswith('start')
# 是否以start开头\n
str.endswith('end')
# 是否以end结尾\n
str.isalnum()
str.isalpha()
str.isdigit()
str.islower()
str.isupper()
# 判断字符串是否全为字符、数字、大写、小写\n\n#-- 三重引号编写多行字符串块,并且在代码折行处嵌入换行字符\\n\n
mantra = \"\"\"hello world\n
hello python\n
hello my friend\"\"\"\n
# mantra为\"\"\"hello world \\n hello python \\n hello my friend\"\"\"\n
\n#-- 索引和分片:\n
S[0], S[len(S) – 1], S[-1]
S[1:3], S[1:], S[:-1], S[1:10:2]
# 分片,第三个参数指定步长\n\n#-- 字符串转换工具:\n
int('42'),
# 返回(42, '42')\n
float('4.13'),
# 返回(4.13, '4.13')\n
# 返回(115, 's')\n
int('1001', 2)
# 将字符串作为二进制数字,转化为数字,返回13\n
bin(13), oct(13), hex(13)
# 将整数转化为二进制/八进制/十六进制字符串,返回('1001', '0o15', '0xd')\n
\n#-- 另类字符串连接\n
name = \"wang\" \"hong\"
#单行,name = \"wanghong\"\n
name = \"wang\" \\\n
#多行,name = \"wanghong\"\n\n#-- Python中的字符串格式化实现1--字符串格式化表达式\n
基于C语言的'print'模型,并且在大多数的现有的语言中使用。\n
通用结构:%[(name)][flag][width].[precision]typecode\n
\"this is %d %s bird\" % (1, 'dead')
# 一般的格式化表达式\n
\"%s---%s---%s\" % (42, 3.14, [1, 2, 3])
# 字符串输出:'42---3.14---[1, 2, 3]'\n
\"%d...%6d...%-6d...%06d\" % (1234, 1234, 1234, 1234)
# 对齐方式及填充:\"1234...
1234...1234
...001234\"\n
\"%e | %f | %g\" % (x, x, x)
# 对齐方式:\"1. | 1.234568 | 1.23457\"\n
\"%6.2f*%-6.2f*%06.2f*%+6.2f\" % (x, x, x, x)
# 对齐方式:'
*001.23* +1.23'\n
\"%(name1)d---%(name2)s\" % {\"name1\":23, \"name2\":\"value2\"}
# 基于字典的格式化表达式\n
\"%(name)s is %(age)d\" % vars()
# vars()函数调用返回一个字典,包含了所有本函数调用时存在的变量\n
\n#-- Python中的字符串格式化实现2--字符串格式化调用方法\n
# 普通调用\n
\"{0}, {1} and {2}\".format('spam', 'ham', 'eggs')
# 基于位置的调用\n
\"{motto} and {pork}\".format(motto = 'spam', pork = 'ham')
# 基于Key的调用\n
\"{motto} and {0}\".format(ham, motto = 'spam')
# 混合调用\n
# 添加键 属性 偏移量 (import sys)\n
\"my {1[spam]} runs {0.platform}\".format(sys, {'spam':'laptop'})
# 基于位置的键和属性\n
\"{config[spam]} {sys.platform}\".format(sys = sys, config = {'spam':'laptop'})
# 基于Key的键和属性\n
\"first = {0[0]}, second = {0[1]}\".format(['A', 'B', 'C'])
# 基于位置的偏移量\n
# 具体格式化\n
\"{0:e}, {1:.3e}, {2:g}\".format(3.14159, 3.14159, 3.14159)
# 输出'3., 3.142e+00, 3.14159'\n
\"{fieldname:format_spec}\".format(......)\n
fieldname是指定参数的一个数字或关键字, 后边可跟可选的\".name\"或\"[index]\"成分引用\n
format_spec ::=
[[fill]align][sign][#][0][width][,][.precision][type]\n
&any character&
#填充字符\n
\"&\" | \"&\" | \"=\" | \"^\"
#对齐方式\n
\"+\" | \"-\" | \" \"
#符号说明\n
#字符串宽度\n
#浮点数精度\n
\"b\" | \"c\" | \"d\" | \"e\" | \"E\" | \"f\" | \"F\" | \"g\" | \"G\" | \"n\" | \"o\" | \"s\" | \"x\" | \"X\" | \"%\"\n
'={0:10} = {1:10}'.format('spam', 123.456)
# 输出'=spam
123.456'\n
'={0:&10}='.format('test')
'={0:&10}='.format('test')
# 输出'=test
'={0:^10}='.format('test')
'{0:X}, {1:o}, {2:b}'.format(255, 255, 255)
# 输出'FF, 377, '\n
'My name is {0:{1}}.'.format('Fred', 8)
# 输出'My name is Fred
动态指定参数\n\n#-- 常用列表常量和操作\n
L = [[1, 2], 'string', {}]
# 嵌套列表\n
L = list('spam')
# 列表初始化\n
L = list(range(0, 4))
# 列表初始化\n
list(map(ord, 'spam'))
# 列表解析\n
# 求列表长度\n
L.count(value)
# 求列表中某个值的个数\n
L.append(obj)
# 向列表的尾部添加数据,比如append(2),添加元素2\n
L.insert(index, obj)
# 向列表的指定index位置添加数据,index及其之后的数据后移\n
L.extend(interable)
# 通过添加iterable中的元素来扩展列表,比如extend([2]),添加元素2,注意和append的区别\n
L.index(value, [start, [stop]])
# 返回列表中值value的第一个索引\n
L.pop([index])
# 删除并返回index处的元素,默认为删除并返回最后一个元素\n
L.remove(value)
# 删除列表中的value值,只删除第一次出现的value的值\n
L.reverse()
# 反转列表\n
L.sort(cmp=None, key=None, reverse=False)
# 排序列表\n
a = [1, 2, 3], b = a[10:]
# 注意,这里不会引发IndexError异常,只会返回一个空的列表[]\n
a = [], a += [1]
# 这里实在原有列表的基础上进行操作,即列表的id没有改变\n
a = [], a = a + [1]
# 这里最后的a要构建一个新的列表,即a的id发生了变化\n
\n#-- 用切片来删除序列的某一段\n
a = [1, 2, 3, 4, 5, 6, 7]\n
a[1:4] = []
# a = [1, 5, 6, 7]\n
a = [0, 1, 2, 3, 4, 5, 6, 7]\n
del a[::2]
# 去除偶数项(偶数索引的),a = [1, 3, 5, 7]\n
\n#-- 常用字典常量和操作\n
D = {'spam':2, 'tol':{'ham':1}}
# 嵌套字典\n
D = dict.fromkeys(['s', 'd'], 8)
# {'d': 8, 's': 8}\n
D = dict(name = 'tom', age = 12)
# {'age': 12, 'name': 'tom'}\n
D = dict([('name', 'tom'), ('age', 12)])
# {'age': 12, 'name': 'tom'}\n
D = dict(zip(['name', 'age'], ['tom', 12]))
# {'age': 12, 'name': 'tom'}\n
D.values()
# 字典键、值以及键值对\n
D.get(key, default)
# get函数\n
D.update(D_other)
# 合并字典,如果存在相同的键值,D_other的数据会覆盖掉D的数据\n
D.pop(key, [D])
# 删除字典中键值为key的项,返回键值为key的值,如果不存在,返回默认值D,否则异常\n
D.popitem()
# pop字典中的一项(一个键值对)\n
D.setdefault(k[, d])
# 设置D中某一项的默认值。如果k存在,则返回D[k],否则设置D[k]=d,同时返回D[k]。\n
# 删除字典\n
del D['key']
# 删除字典的某一项\n
if key in D:
if key not in D:
# 测试字典键是否存在\n
# 字典注意事项:(1)对新索引赋值会添加一项(2)字典键不一定非得是字符串,也可以为任何的不可变对象\n\n#-- 字典解析\n
D = {k:8 for k in ['s', 'd']}
# {'d': 8, 's': 8}\n
D = {k:v for (k, v) in zip(['name', 'age'], ['tom', 12])}\n
\n#-- 字典的特殊方法__missing__:当查找找不到key时,会执行该方法\n
class Dict(dict):\n
def __missing__(self, key):\n
self[key] = []\n
return self[key]\n
dct = Dict()\n
dct[\"foo\"].append(1)
# 这有点类似于collections.defalutdict\n
dct[\"foo\"]
\n#-- 元组和列表的唯一区别在于元组是不可变对象,列表时可变对象\n
a = [1, 2, 3]
# a[1] = 0, OK\n
a = (1, 2, 3)
# a[1] = 0, Error\n
a = ([1, 2])
# a[0][1] = 0, OK\n
a = [(1, 2)]
# a[0][1] = 0, Error\n
\n#-- 元组的特殊语法: 逗号和圆括号\n
# 此时D为一个整数 即D = 12\n
D = (12, )
# 此时D为一个元组 即D = (12, )\n
\n#-- 文件基本操作\n
output = open(r'C:\\spam', 'w')
# 打开输出文件,用于写\n
input = open('data', 'r')
# 打开输入文件,用于读。打开的方式可以为'w', 'r', 'a', 'wb', 'rb', 'ab'等\n
fp.read([size])
# size为读取的长度,以byte为单位\n
fp.readline([size])
# 读一行,如果定义了size,有可能返回的只是一行的一部分\n
fp.readlines([size])
# 把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数,size是表示读取内容的总长。\n
fp.readable()
# 是否可读\n
fp.write(str)
# 把str写到文件中,write()并不会在str后加上一个换行符\n
fp.writelines(seq)
# 把seq的内容全部写到文件中(多行一次性写入)\n
fp.writeable()
# 是否可写\n
fp.close()
# 关闭文件。\n
fp.flush()
# 把缓冲区的内容写入硬盘\n
fp.fileno()
# 返回一个长整型的”文件标签“\n
fp.isatty()
# 文件是否是一个终端设备文件(unix系统中的)\n
# 返回文件操作标记的当前位置,以文件的开头为原点\n
# 返回下一行,并将文件操作标记位移到下一行。把一个file用于for … in file这样的语句时,就是调用next()函数来实现遍历的。\n
fp.seek(offset[,whence])
# 将文件打操作标记移到offset的位置。whence可以为0表示从头开始计算,1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。\n
fp.seekable()
# 是否可以seek\n
fp.truncate([size])
# 把文件裁成规定的大小,默认的是裁到当前文件操作标记的位置。\n
for line in open('data'): \n
print(line)
# 使用for语句,比较适用于打开比较大的文件\n
open('f.txt', encoding = 'latin-1')
# Python3.x Unicode文本文件\n
open('f.bin', 'rb')
# Python3.x 二进制bytes文件\n
# 文件对象还有相应的属性:buffer closed encoding errors line_buffering name newlines等\n
\n#-- 其他\n
# Python中的真假值含义:1. 数字如果非零,则为真,0为假。 2. 其他对象如果非空,则为真\n
# 通常意义下的类型分类:1. 数字、序列、映射。 2. 可变类型和不可变类型\n\n\n\"\"\"语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句\"\"\"\n\n#-- 赋值语句的形式\n
spam = 'spam'
# 基本形式\n
spam, ham = 'spam', 'ham'
# 元组赋值形式\n
[spam, ham] = ['s', 'h']
# 列表赋值形式\n
a, b, c, d = 'abcd'
# 序列赋值形式\n
a, *b, c = 'spam'
# 序列解包形式(Python3.x中才有)\n
spam = ham = 'no'
# 多目标赋值运算,涉及到共享引用\n
spam += 42
# 增强赋值,涉及到共享引用\n\n#-- 序列赋值 序列解包\n
[a, b, c] = (1, 2, 3)
# a = 1, b = 2, c = 3\n
a, b, c, d = \"spam\"
# a = 's', b = 'p'\n
a, b, c = range(3)
# a = 0, b = 1\n
a, *b = [1, 2, 3, 4]
# a = 1, b = [2, 3, 4]\n
*a, b = [1, 2, 3, 4]
# a = [1, 2, 3], b = 4\n
a, *b, c = [1, 2, 3, 4]
# a = 1, b = [2, 3], c = 4\n
# 带有*时 会优先匹配*之外的变量 如\n
a, *b, c = [1, 2]
# a = 1, c = 2, b = []\n\n#-- print函数原型\n
print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n
# 流的重定向\n
print('hello world')
# 等于sys.stdout.write('hello world')\n
temp = sys.stdout
# 原有流的保存\n
sys.stdout = open('log.log', 'a')
# 流的重定向\n
print('hello world')
# 写入到文件log.log\n
sys.stdout.close()\n
sys.stdout = temp
# 原有流的复原\n
\n#-- Python中and或or总是返回对象(左边的对象或右边的对象) 且具有短路求值的特性\n
1 or 2 or 3
# 返回 1\n
1 and 2 and 3
# 返回 3\n\n#-- if/else三元表达符(if语句在行内)\n
A = 1 if X else 2\n
A = 1 if X else (2 if Y else 3)\n
# 也可以使用and-or语句(一条语句实现多个if-else)\n
result = (a & 20 and \"big than 20\" or a & 10 and \"big than 10\" or a & 5 and \"big than 5\")\n\n#-- Python的while语句或者for语句可以带else语句 当然也可以带continue/break/pass语句\n
while a & 1:\n
# else语句会在循环结束后执行,除非在循环中执行了break,同样的还有for语句\n
for i in range(5):\n
......\n\n#-- for循环的元组赋值\n
for (a, b) in [(1, 2), (3, 4)]:
# 最简单的赋值\n
for ((a, b), c) in [((1, 2), 3), ((4, 5), 6)]:
# 自动解包赋值\n
for ((a, b), c) in [((1, 2), 3), (\"XY\", 6)]:
# 自动解包 a = X, b = Y, c = 6\n
for (a, *b) in [(1, 2, 3), (4, 5, 6)]:
# 自动解包赋值\n\n#-- 列表解析语法\n
M = [[1,2,3], [4,5,6], [7,8,9]]\n
res = [sum(row) for row in M]
# G = [6, 15, 24] 一般的列表解析 生成一个列表\n
res = [c * 2 for c in 'spam']
# ['ss', 'pp', 'aa', 'mm']\n
res = [a * b for a in [1, 2] for b in [4, 5]]
# 多解析过程 返回[4, 5, 8, 10]\n
res = [a for a in [1, 2, 3] if a & 2]
# 带判断条件的解析过程\n
res = [a if a & 0 else 0 for a in [-1, 0, 1]]
# 带判断条件的高级解析过程\n
# 两个列表同时解析:使用zip函数\n
for teama, teamb in zip([\"Packers\", \"49ers\"], [\"Ravens\", \"Patriots\"]):\n
print(teama + \" vs. \" + teamb)\n
# 带索引的列表解析:使用enumerate函数\n
for index, team in enumerate([\"Packers\", \"49ers\", \"Ravens\", \"Patriots\"]):\n
print(index, team)
# 输出0, Packers \\n 1, 49ers \\n ......\n
\n#-- 生成器表达式\n
G = (sum(row) for row in M)
# 使用小括号可以创建所需结果的生成器generator object\n
next(G), next(G), next(G)
# 输出(6, 15, 24)\n
G = {sum(row) for row in M}
# G = {6, 15, 24} 解析语法还可以生成集合和字典\n
G = {i:sum(M[i]) for i in range(3)}
# G = {0: 6, 1: 15, 2: 24}\n\n#-- 文档字符串:出现在Module的开端以及其中函数或类的开端 使用三重引号字符串\n
module document\n
def func():\n
function document\n
class Employee:\n
class document\n
print(func.__doc__)
# 输出函数文档字符串\n
print(Employee.__doc__)
# 输出类的文档字符串\n
\n#-- 命名惯例:\n
以单一下划线开头的变量名(_X)不会被from module import*等语句导入\n
前后有两个下划线的变量名(__X__)是系统定义的变量名,对解释器有特殊意义\n
以两个下划线开头但不以下划线结尾的变量名(__X)是类的本地(私有)变量\n
\"\"\"\n\n#-- 列表解析 in成员关系测试 map sorted zip enumerate内置函数等都使用了迭代协议\n
'first line' in open('test.txt')
# in测试 返回True或False\n
list(map(str.upper, open('t')))
# map内置函数\n
sorted(iter([2, 5, 8, 3, 1]))
# sorted内置函数\n
list(zip([1, 2], [3, 4]))
# zip内置函数 [(1, 3), (2, 4)]\n\n#-- del语句: 手动删除某个变量\n
del X\n\n#-- 获取列表的子表的方法:\n
x = [1,2,3,4,5,6]\n
# 前3个[1,2,3]\n
# 中间4个[2,3,4,5]\n
# 最后3个[4,5,6]\n
# 奇数项[1,3,5]\n
# 偶数项[2,4,6]\n
\n#-- 手动迭代:iter和next\n
L = [1, 2]\n
I = iter(L)
# I为L的迭代器\n
# Error:StopIteration\n
\n#-- Python中的可迭代对象\n
1.range迭代器\n
2.map、zip和filter迭代器\n
3.字典视图迭代器:D.keys()), D.items()等\n
4.文件类型\n
\"\"\"\n\n\n\"\"\"函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则\"\"\"\n\n#-- 函数相关的语句和表达式\n
myfunc('spam')
# 函数调用\n
def myfunc():
# 函数定义\n
return None
# 函数返回值\n
# 全局变量\n
nonlocal x
# 在函数或其他作用域中使用外层(非全局)变量\n
# 生成器函数返回\n
# 匿名函数\n
\n#-- Python函数变量名解析:LEGB原则,即:\n
local(functin) --& encloseing function locals --& global(module) --& build-in(python)\n
说明:以下边的函数maker为例 则相对于action而言 X为Local N为Encloseing\n
\"\"\"\n\n#-- 嵌套函数举例:工厂函数\n
def maker(N):\n
def action(X):\n
return X ** N\n
return action\n
f = maker(2)
# pass 2 to N\n
# 9, pass 3 to X\n\n#-- 嵌套函数举例:lambda实例\n
def maker(N):\n
action = (lambda X: X**N)\n
return action\n
f = maker(2)
# pass 2 to N\n
# 9, pass 3 to X\n\n#-- nonlocal和global语句的区别\n
# nonlocal应用于一个嵌套的函数的作用域中的一个名称 例如:\n
start = 100\n
def tester(start):\n
def nested(label):\n
nonlocal start
# 指定start为tester函数内的local变量 而不是global变量start\n
print(label, start)\n
start += 3\n
return nested\n
# global为全局的变量 即def之外的变量\n
def tester(start):\n
def nested(label):\n
global start
# 指定start为global变量start\n
print(label, start)\n
start += 3\n
return nested
\n#-- 函数参数,不可变参数通过“值”传递,可变参数通过“引用”传递\n
def f(a, b, c): print(a, b, c)\n
f(1, 2, 3)
# 参数位置匹配\n
f(1, c = 3, b = 2)
# 参数关键字匹配\n
def f(a, b = 1, c = 2): print(a, b, c)\n
# 默认参数匹配\n
# 默认参数匹配\n
f(a = 1, c = 3)
# 关键字参数和默认参数的混合\n
# Keyword-Only参数:出现在*args之后 必须用关键字进行匹配\n
def keyOnly(a, *b, c): print('')
# c就为keyword-only匹配 必须使用关键字c = value匹配\n
def keyOnly(a, *, b, c): ......
# b c为keyword-only匹配 必须使用关键字匹配\n
def keyOnly(a, *, b = 1): ......
# b有默认值 或者省略 或者使用关键字参数b = value\n\n#-- 可变参数匹配: * 和 **\n
def f(*args): print(args)
# 在元组中收集不匹配的位置参数\n
f(1, 2, 3)
# 输出(1, 2, 3)\n
def f(**args): print(args)
# 在字典中收集不匹配的关键字参数\n
f(a = 1, b = 2)
# 输出{'a':1, 'b':2}\n
def f(a, *b **c): print(a, b, c)
# 两者混合使用\n
f(1, 2, 3, x = 4, y = 5)
# 输出1, (2, 3), {'x':4, 'y':5}\n
\n#-- 函数调用时的参数解包: * 和 ** 分别解包元组和字典\n
func(1, *(2, 3))
func(1, 2, 3)\n
func(1, **{'c':3, 'b':2})
func(1, b = 2, c = 3)\n
func(1, *(2, 3), **{'c':3, 'b':2})
func(1, 2, 3, b = 2, c = 3)\n
\n#-- 函数属性:(自己定义的)函数可以添加属性\n
def func():.....\n
func.count = 1
# 自定义函数添加属性\n
print.count = 1
# Error 内置函数不可以添加属性\n
\n#-- 函数注解: 编写在def头部行 主要用于说明参数范围、参数类型、返回值类型等\n
def func(a:'spam', b:(1, 10), c:float) -& int :\n
print(a, b, c)\n
func.__annotations__
# {'c':&class 'float'&, 'b':(1, 10), 'a':'spam', 'return':&class 'int'&}\n
# 编写注解的同时 还是可以使用函数默认值 并且注解的位置位于=号的前边\n
def func(a:'spam'='a', b:(1, 10)=2, c:float=3) -& int :\n
print(a, b, c)\n\n#-- 匿名函数:lambda\n
f = lambda x, y, z : x + y + z
# 普通匿名函数,使用方法f(1, 2, 3)\n
f = lambda x = 1, y = 1: x + y
# 带默认参数的lambda函数\n
def action(x):
# 嵌套lambda函数\n
return (lambda y : x + y)\n
f = lambda: a if xxx() else b
# 无参数的lambda函数,使用方法f()\n\n#-- lambda函数与map filter reduce函数的结合\n
list(map((lambda x: x + 1), [1, 2, 3]))
# [2, 3, 4]\n
list(filter((lambda x: x & 0), range(-4, 5)))
# [1, 2, 3, 4]\n
functools.reduce((lambda x, y: x + y), [1, 2, 3])
functools.reduce((lambda x, y: x * y), [2, 3, 4])
\n#-- 生成器函数:yield VS return\n
def gensquare(N):\n
for i in range(N):\n
yield i** 2
# 状态挂起 可以恢复到此时的状态\n
for i in gensquare(5):
# 使用方法\n
print(i, end = ' ')
# [0, 1, 4, 9, 16]\n
x = gensquare(2)
# x是一个生成对象\n
# 等同于x.__next__() 返回0\n
# 等同于x.__next__() 返回1\n
# 等同于x.__next__() 抛出异常StopIteration\n
\n#-- 生成器表达式:小括号进行列表解析\n
G = (x ** 2 for x in range(3))
# 使用小括号可以创建所需结果的生成器generator object\n
next(G), next(G), next(G)
# 和上述中的生成器函数的返回值一致\n
#(1)生成器(生成器函数/生成器表达式)是单个迭代对象\n
G = (x ** 2 for x in range(4))\n
I1 = iter(G)
# 这里实际上iter(G) = G\n
#(2)生成器不保留迭代后的结果\n
gen = (i for i in range(4))\n
# 返回True\n
# 返回True\n
# 返回False,其实检测2的时候,1已经就不在生成器中了,即1已经被迭代过了,同理2、3也不在了\n\n#-- 本地变量是静态检测的\n
# 全局变量X的声明和定义\n
def test():\n
# 如果没有下一语句 则该句合法 打印全局变量X\n
# 这一语句使得上一语句非法 因为它使得X变成了本地变量 上一句变成了打印一个未定义的本地变量(局部变量)\n
# 即使这样的语句 也会把print语句视为非法语句 因为:\n
# Python会无视if语句而仍然声明了局部变量X\n
def test():
# 声明变量X为全局变量\n
# 打印全局变量X\n
# 改变全局变量X\n
\n#-- 函数的默认值是在函数定义的时候实例化的 而不是在调用的时候 例子:\n
def foo(numbers=[]):
# 这里的[]是可变的\n
numbers.append(9)
print(numbers)\n
# first time, like before, [9]\n
# second time, not like before, [9, 9]\n
# third time, not like before too, [9, 9, 9]\n
def foo(numbers=None):\n
if numbers is None: numbers = []\n
numbers.append(9)\n
print(numbers)\n
# 另外一个例子 参数的默认值为不可变的:\n
def foo(count=0):
# 这里的0是数字, 是不可变的\n
count += 1\n
print(count)\n
# 还是输出1\n
# 还是输出1\n
\n\n\"\"\"函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子\"\"\"\n\n
\"\"\"数学运算类\"\"\"\n
# 求绝对值,参数可以是整型,也可以是复数,若参数是复数,则返回复数的模\n
complex([real[, imag]])
# 创建一个复数\n
divmod(a, b)
# 分别取商和余数,注意:整型、浮点型都可以\n
float([x])
# 将一个字符串或数转换为浮点数。如果无参数将返回0.0\n
int([x[, base]])
# 将一个字符串或浮点数转换为int类型,base表示进制\n
long([x[, base]])
# 将一个字符串或浮点数转换为long类型\n
# 返回x的y次幂\n
range([start], stop[, step])
# 产生一个序列,默认从0开始\n
round(x[, n])
# 四舍五入\n
sum(iterable[, start])
# 对集合求和\n
# 将一个数字转化为8进制字符串\n
# 将一个数字转换为16进制字符串\n
# 返回给定int类型对应的ASCII字符\n
# 返回给定int类型的unicode\n
# 返回ASCII字符对应的整数\n
# 将整数x转换为二进制字符串\n
# 将x转换为Boolean类型\n
\"\"\"集合类操作\"\"\"\n
basestring()
# str和unicode的超类,不能直接调用,可以用作isinstance判断\n
format(value [, format_spec])
# 格式化输出字符串,格式化的参数顺序从0开始,如“I am {0},I like {1}”\n
enumerate(sequence[, start=0])
# 返回一个可枚举的对象,注意它有第二个参数\n
iter(obj[, sentinel])
# 生成一个对象的迭代器,第二个参数表示分隔符\n
max(iterable[, args...][key])
# 返回集合中的最大值\n
min(iterable[, args...][key])
# 返回集合中的最小值\n
dict([arg])
# 创建数据字典\n
list([iterable])
# 将一个集合类转换为另外一个集合类\n
# set对象实例化\n
frozenset([iterable])
# 产生一个不可变的set\n
tuple([iterable])
# 生成一个tuple类型\n
str([object])
# 转换为string类型\n
sorted(iterable[, cmp[, key[, reverse]]])
# 集合排序\n
L = [('b',2),('a',1),('c',3),('d',4)]\n
sorted(L, key=lambda x: x[1]), reverse=True)
# 使用Key参数和reverse参数\n
sorted(L, key=lambda x: (x[0], x[1]))
# 使用key参数进行多条件排序,即如果x[0]相同,则比较x[1]\n\n
\"\"\"逻辑判断\"\"\"\n
all(iterable)
# 集合中的元素都为真的时候为真,特别的,若为空串返回为True\n
any(iterable)
# 集合中的元素有一个为真的时候为真,特别的,若为空串返回为False\n
# 如果x & y ,返回负数;x == y, 返回0;x & y,返回正数\n\n
\"\"\"IO操作\"\"\"\n
file(filename [, mode [, bufsize]]) # file类型的构造函数。\n
input([prompt])
# 获取用户输入,推荐使用raw_input,因为该函数将不会捕获用户的错误输入\n
raw_input([prompt])
# 设置输入,输入都是作为字符串处理\n
open(name[, mode[, buffering]])
# 打开文件,与file有什么不同?推荐使用open\n
\"\"\"其他\"\"\"\n
callable(object)
# 检查对象object是否可调用\n
classmethod(func)
# 用来说明这个func是个类方法\n
staticmethod(func)
# 用来说明这个func为静态方法\n
dir([object])
# 不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。\n
# 返回obj的帮助信息\n
eval(expression)
# 计算表达式expression的值,并返回\n
# 将str作为Python语句执行\n
execfile(filename)
# 用法类似exec(),不同的是execfile的参数filename为文件名,而exec的参数为字符串。\n
filter(function, iterable)
# 构造一个序列,等价于[item for item in iterable if function(item)],function返回值为True或False的函数\n
list(filter(bool, range(-3, 4)))# 返回[-3, -2, -1, 1, 2, 3], 没有0\n
hasattr(object, name)
# 判断对象object是否包含名为name的特性\n
getattr(object, name [, defalut])
# 获取一个类的属性\n
setattr(object, name, value)
# 设置属性值\n
delattr(object, name)
# 删除object对象名为name的属性\n
# 返回一个描述当前全局符号表的字典\n
hash(object)
# 如果对象object为哈希表类型,返回对象object的哈希值\n
id(object)
# 返回对象的唯一标识,一串数字\n
isinstance(object, classinfo)
# 判断object是否是class的实例\n
isinstance(1, int)
# 判断是不是int类型\n
isinstance(1, (int, float))
# isinstance的第二个参数接受一个元组类型\n
issubclass(class, classinfo)
# 判断class是否为classinfo的子类\n
# 返回当前的变量列表\n
map(function, iterable, ...)
# 遍历每个元素,执行function操作\n
list(map(abs, range(-3, 4)))
# 返回[3, 2, 1, 0, 1, 2, 3]\n
next(iterator[, default])
# 类似于iterator.next()\n
property([fget[, fset[, fdel[, doc]]]])
# 属性访问的包装类,设置后可以通过c.x=value等来访问setter和getter\n
reduce(function, iterable[, initializer])
# 合并操作,从第一个开始是前两个参数,然后是前两个的结果与第三个合并进行处理,以此类推\n
def add(x,y):return x + y \n
reduce(add, range(1, 11))
# 返回55 (注:1+2+3+4+5+6+7+8+9+10 = 55)\n
reduce(add, range(1, 11), 20)
# 返回75\n
reload(module)
# 重新加载模块\n
repr(object)
# 将一个对象变幻为可打印的格式\n
slice(start, stop[, step])
# 产生分片对象\n
type(object)
# 返回该object的类型\n
vars([object])
# 返回对象的变量名、变量值得字典\n
a = Class();
# Class为一个空类\n
a.name = 'qi', a.age = 9\n
# {'name':'qi', 'age':9}\n
zip([iterable, ...])
# 返回对应数组\n
list(zip([1, 2, 3], [4, 5, 6])) # [(1, 4), (2, 5), (3, 6)]\n
a = [1, 2, 3],
b = [\"a\", \"b\", \"c\"]\n
z = zip(a, b)
# 压缩:[(1, \"a\"), (2, \"b\"), (3, \"c\")]\n
# 解压缩:[(1, 2, 3), (\"a\", \"b\", \"c\")]\n
unicode(string, encoding, errors)
# 将字符串string转化为unicode形式,string为encoded string。\n\n
\n\"\"\"模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle\"\"\"\n\n#-- Python模块搜索路径:\n
(1)程序的主目录
(2)PYTHONPATH目录 (3)标准链接库目录 (4)任何.pth文件的内容\n
\n#-- 查看全部的模块搜索路径\n
import sys\n
sys.path\n
\n#-- 模块的使用代码\n
import module1, module2
# 导入module1 使用module1.printer()\n
from module1 import printer
# 导入module1中的printer变量 使用printer()\n
from module1 imoprt *
# 导入module1中的全部变量 使用不必添加module1前缀\n\n#-- 重载模块reload: 这是一个内置函数 而不是一条语句\n
from imp import reload\n
reload(module)\n
\n#-- 模块的包导入:使用点号(.)而不是路径(dir1\\dir2)进行导入\n
import dir1.dir2.mod
# d导入包(目录)dir1中的包dir2中的mod模块 此时dir1必须在Python可搜索路径中\n
from dir1.dir2.mod import *
# from语法的包导入\n\n#-- __init__.py包文件:每个导入的包中都应该包含这么一个文件\n
该文件可以为空\n
首次进行包导入时 该文件会自动执行\n
高级功能:在该文件中使用__all__列表来定义包(目录)以from*的形式导入时 需要导入什么\n
\n#-- 包相对导入:使用点号(.) 只能使用from语句\n
from . import spam
# 导入当前目录下的spam模块(错误: 当前目录下的模块, 直接导入即可)\n
from .spam import name
# 导入当前目录下的spam模块的name属性(错误: 当前目录下的模块, 直接导入即可,不用加.)\n
from .. import spam
# 导入当前目录的父目录下的spam模块\n
\n#-- 包相对导入与普通导入的区别\n
from string import *
# 这里导入的string模块为sys.path路径上的 而不是本目录下的string模块(如果存在也不是)\n
from .string import *
# 这里导入的string模块为本目录下的(不存在则导入失败) 而不是sys.path路径上的\n
\n#-- 模块数据隐藏:最小化from*的破坏\n
# 变量名前加下划线可以防止from*导入时该变量名被复制出去\n
__all__ = ['x', 'x1', 'x2']
# 使用__all__列表指定from*时复制出去的变量名(变量名在列表中为字符串形式)\n\n#-- 可以使用__name__进行模块的单元测试:当模块为顶层执行文件时值为'__main__' 当模块被导入时为模块名\n
if __name__ == '__main__':\n
doSomething\n
# 模块属性中还有其他属性,例如:\n
# 模块的说明文档\n
# 模块文件的文件名,包括全路径\n
# 主文件或者被导入文件\n
__package__
# 模块所在的包\n
\n#-- import语句from语句的as扩展\n
import modulename as name\n
from modulename import attrname as name\n
\n#-- 得到模块属性的几种方法 假设为了得到name属性的值\n
M.__dict__['name']\n
sys.modules['M'].name\n
getattr(M, 'name')\n
\n\n\"\"\"类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象\"\"\"\n\n#-- 最普通的类\n
class C1(C2, C3):\n
# 数据属性\n
def __init__(self, name):
# 函数属性:构造函数\n
self.name = name\n
def __del__(self):
# 函数属性:析构函数\n
print(\"goodbey \", self.name)
I1 = C1('bob')\n
\n#-- Python的类没有基于参数的函数重载\n
class FirstClass:\n
def test(self, string):\n
print(string)\n
def test(self):
# 此时类中只有一个test函数 即后者test(self) 它覆盖掉前者带参数的test函数\n
print(\"hello world\")\n\n#-- 子类扩展超类: 尽量调用超类的方法\n
class Manager(Person):\n
def giveRaise(self, percent, bonus = .10):\n
self.pay = int(self.pay*(1 + percent + bonus))
# 不好的方式 复制粘贴超类代码\n
Person.giveRaise(self, percent + bonus)
# 好的方式 尽量调用超类方法\n\n#-- 类内省工具\n
bob = Person('bob')\n
bob.__class__
# &class 'Person'&\n
bob.__class__.__name__
# 'Person'\n
bob.__dict__
# {'pay':0, 'name':'bob', 'job':'Manager'}\n
\n#-- 返回1中 数据属性spam是属于类 而不是对象\n
I1 = C1('bob'); I2 = C2('tom')
# 此时I1和I2的spam都为42 但是都是返回的C1的spam属性\n
C1.spam = 24
# 此时I1和I2的spam都为24\n
I1.spam = 3
# 此时I1新增自有属性spam 值为2 I2和C1的spam还都为24\n
\n#-- 类方法调用的两种方式\n
instance.method(arg...)\n
class.method(instance, arg...)\n
\n#-- 抽象超类的实现方法\n
# (1)某个函数中调用未定义的函数 子类中定义该函数\n
def delegate(self):\n
self.action()
# 本类中不定义action函数 所以使用delegate函数时就会出错\n
# (2)定义action函数 但是返回异常\n
def action(self):\n
raise NotImplementedError(\"action must be defined\")\n
# (3)上述的两种方法还都可以定义实例对象 实际上可以利用@装饰器语法生成不能定义的抽象超类\n
from abc import ABCMeta, abstractmethod\n
class Super(metaclass = ABCMeta):\n
@abstractmethod\n
def action(self): pass\n
x = Super()
# 返回 TypeError: Can't instantiate abstract class Super with abstract methods action\n
\n#-- # OOP和继承: \"is - a\"的关系\n
class A(B):\n
isinstance(a, B)
# 返回True, A是B的子类 a也是B的一种\n
# OOP和组合: \"has- a\"的关系\n
# OOP和委托: \"包装\"对象 在Python中委托通常是以\"__getattr__\"钩子方法实现的, 这个方法会拦截对不存在属性的读取\n
# 包装类(或者称为代理类)可以使用__getattr__把任意读取转发给被包装的对象\n
class wrapper:\n
def __init__(self, object):\n
self.wrapped = object\n
def __getattr(self, attrname):\n
print('Trace: ', attrname)\n
return getattr(self.wrapped, attrname)\n
# 注:这里使用getattr(X, N)内置函数以变量名字符串N从包装对象X中取出属性 类似于X.__dict__[N]\n
x = wrapper([1, 2, 3])\n
x.append(4)
# 返回 \"Trace: append\" [1, 2, 3, 4]\n
x = wrapper({'a':1, 'b':2})\n
list(x.keys())
# 返回 \"Trace: keys\" ['a', 'b']\n\n#-- 类的伪私有属性:使用__attr\n
class C1:\n
def __init__(self, name):\n
self.__name = name
# 此时类的__name属性为伪私有属性 原理 它会自动变成self._C1__name = name\n
def __str__(self):\n
return 'self.name = %s' % self.__name\n
I = C1('tom')\n
# 返回 self.name = tom\n
I.__name = 'jeey'
# 这里无法访问 __name为伪私有属性\n
I._C1__name = 'jeey'
# 这里可以修改成功 self.name = jeey\n
\n#-- 类方法是对象:无绑定类方法对象 / 绑定实例方法对象\n
class Spam:\n
def doit(self, message):\n
print(message)\n
def selfless(message)\n
print(message)\n
obj = Spam()\n
x = obj.doit
# 类的绑定方法对象 实例 + 函数\n
x('hello world')\n
x = Spam.doit
# 类的无绑定方法对象 类名 + 函数\n
x(obj, 'hello world')\n
x = Spam.selfless
# 类的无绑定方法是函数 在3.0之前无效\n
x('hello world')\n\n#-- 获取对象信息: 属性和方法\n
a = MyObject()\n
# 使用dir函数\n
hasattr(a, 'x')
# 测试是否有x属性或方法 即a.x是否已经存在\n
setattr(a, 'y', 19)
# 设置属性或方法 等同于a.y = 19\n
getattr(a, 'z', 0)
# 获取属性或方法 如果属性不存在 则返回默认值0\n
#这里有个小技巧,setattr可以设置一个不能访问到的属性,即只能用getattr获取\n
setattr(a, \"can't touch\", 100)
# 这里的属性名带有空格,不能直接访问\n
getattr(a, \"can't touch\", 0)
# 但是可以用getattr获取\n\n#-- 为类动态绑定属性或方法: MethodType方法\n
# 一般创建了一个class的实例后, 可以给该实例绑定任何属性和方法, 这就是动态语言的灵活性\n
class Student(object):\n
s = Student()\n
s.name = 'Michael'
# 动态给实例绑定一个属性\n
def set_age(self, age):
# 定义一个函数作为实例方法\n
self.age = age\n
from types import MethodType\n
s.set_age = MethodType(set_age, s)
# 给实例绑定一个方法 类的其他实例不受此影响\n
s.set_age(25)
# 调用实例方法\n
Student.set_age = MethodType(set_age, Student)
# 为类绑定一个方法 类的所有实例都拥有该方法\n\n
\n\"\"\"类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题\"\"\"\n
\n#-- 多重继承: \"混合类\", 搜索方式\"从下到上 从左到右 广度优先\"\n
class A(B, C):\n
pass\n\n#-- 类的继承和子类的初始化\n
# 1.子类定义了__init__方法时,若未显示调用基类__init__方法,python不会帮你调用。\n
# 2.子类未定义__init__方法时,python会自动帮你调用首个基类的__init__方法,注意是首个。\n
# 3.子类显示调用基类的初始化函数:\n
class FooParent(object):\n
def __init__(self, a):\n
self.parent = 'I\\'m the Parent.'\n
print('Parent:a=' + str(a))\n
def bar(self, message):\n
print(message + ' from Parent')\n
class FooChild(FooParent):\n
def __init__(self, a):\n
FooParent.__init__(self, a)\n
print('Child:a=' + str(a))\n
def bar(self, message):\n
FooParent.bar(self, message)\n
print(message + ' from Child')\n
fooChild = FooChild(10)\n
fooChild.bar('HelloWorld')\n
\n#-- #实例方法 / 静态方法 / 类方法\n
class Methods:\n
def imeth(self, x): print(self, x)
# 实例方法:传入的是实例和数据,操作的是实例的属性\n
def smeth(x): print(x)
# 静态方法:只传入数据 不传入实例,操作的是类的属性而不是实例的属性\n
def cmeth(cls, x): print(cls, x)
# 类方法:传入的是类对象和数据\n
smeth = staticmethod(smeth)
# 调用内置函数,也可以使用@staticmethod\n
cmeth = classmethod(cmeth)
# 调用内置函数,也可以使用@classmethod\n
obj = Methods()\n
obj.imeth(1)
# 实例方法调用 &__main__.Methods object...& 1\n
Methods.imeth(obj, 2)
# &__main__.Methods object...& 2\n
Methods.smeth(3)
# 静态方法调用 3\n
obj.smeth(4)
# 这里可以使用实例进行调用\n
Methods.cmeth(5)
# 类方法调用 &class '__main__.Methods'& 5\n
obj.cmeth(6)
# &class '__main__.Methods'& 6\n
\n#-- 函数装饰器:是它后边的函数的运行时的声明 由@符号以及后边紧跟的\"元函数\"(metafunction)组成\n
@staticmethod\n
def smeth(x): print(x)\n
# 等同于:\n
def smeth(x): print(x)\n
smeth = staticmethod(smeth)\n
@classmethod\n
def cmeth(cls, x): print(x)\n
# 等同于\n
def cmeth(cls, x): print(x)\n
cmeth = classmethod(cmeth)\n
\n#-- 类修饰器:是它后边的类的运行时的声明 由@符号以及后边紧跟的\"元函数\"(metafunction)组成\n
def decorator(aClass):.....\n
@decorator\n
class C:....\n
# 等同于:\n
class C:....\n
C = decorator(C)\n\n#-- 限制class属性: __slots__属性\n
class Student:\n
__slots__ = ('name', 'age')
# 限制Student及其实例只能拥有name和age属性\n
# __slots__属性只对当前类起作用, 对其子类不起作用\n
# __slots__属性能够节省内存\n
# __slots__属性可以为列表list,或者元组tuple\n
\n#-- 类属性高级话题: @property\n
# 假设定义了一个类:C,该类必须继承自object类,有一私有变量_x\n
class C(object):\n
def __init__(self):\n
self.__x = None\n
# 第一种使用属性的方法\n
def getx(self):\n
return self.__x\n
def setx(self, value):\n
self.__x = value\n
def delx(self):\n
del self.__x\n
x = property(getx, setx, delx, '')\n
# property函数原型为property(fget=None,fset=None,fdel=None,doc=None)\n
# 自动调用setx方法\n
# 自动调用getx方法\n
# 自动调用delx方法\n
# 第二种方法使用属性的方法\n
@property\n
def x(self):\n
return self.__x\n
@x.setter\n
def x(self, value):\n
self.__x = value\n
@x.deleter\n
def x(self):\n
del self.__x\n
# 自动调用setter方法\n
# 自动调用x方法\n
# 自动调用deleter方法\n
\n#-- 定制类: 重写类的方法\n
# (1)__str__方法、__repr__方法: 定制类的输出字符串\n
# (2)__iter__方法、next方法: 定制类的可迭代性\n
class Fib(object):\n
def __init__(self):\n
self.a, self.b = 0, 1
# 初始化两个计数器a,b\n
def __iter__(self):\n
return self
# 实例本身就是迭代对象,故返回自己\n
def next(self):\n
self.a, self.b = self.b, self.a + self.b\n
if self.a & 100000:
# 退出循环的条件\n
raise StopIteration()\n
return self.a
# 返回下一个值\n
for n in Fib():\n
# (3)__getitem__方法、__setitem__方法: 定制类的下标操作[] 或者切片操作slice\n
class Indexer(object):\n
def __init__(self):\n
self.data = {}\n
def __getitem__(self, n):
# 定义getitem方法\n
print('getitem:', n)
return self.data[n]\n
def __setitem__(self, key, value):
# 定义setitem方法\n
print('setitem:key = {0}, value = {1}'.format(key, value))\n
self.data[key] = value\n
test = Indexer()\n
test[0] = 1;
test[3] = '3'
# 调用setitem方法\n
print(test[0])
# 调用getitem方法\n
# (4)__getattr__方法: 定制类的属性操作\n
class Student(object):\n
def __getattr__(self, attr):
# 定义当获取类的属性时的返回值\n
if attr=='age':\n
# 当获取age属性时返回25\n
raise AttributeError('object has no attribute: %s' % attr)\n
# 注意: 只有当属性不存在时 才会调用该方法 且该方法默认返回None 需要在函数最后引发异常\n
s = Student()\n
# s中age属性不存在 故调用__getattr__方法 返回25\n
# (5)__call__方法: 定制类的'可调用'性\n
class Student(object):\n
def __call__(self):
# 也可以带参数\n
print('Calling......')\n
s = Student()\n
# s变成了可调用的 也可以带参数\n
callable(s)
# 测试s的可调用性 返回True\n
(6)__len__方法:求类的长度\n
def __len__(self):\n
return len(self.data)\n
\n#-- 动态创建类type()\n
# 一般创建类 需要在代码中提前定义\n
class Hello(object):\n
def hello(self, name='world'):\n
print('Hello, %s.' % name)\n
h = Hello()\n
# Hello, world\n
type(Hello)
# Hello是一个type类型 返回&class 'type'&\n
# h是一个Hello类型 返回&class 'Hello'&\n
# 动态类型语言中 类可以动态创建 type函数可用于创建新类型\n
def fn(self, name='world'):
# 先定义函数\n
print('Hello, %s.' % name)\n
Hello = type('Hello', (object,), dict(hello=fn)) \n
# 创建Hello类 type原型: type(name, bases, dict)\n
h = Hello()
# 此时的h和上边的h一致\n\n\n\"\"\"异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关\"\"\"\n
\n#-- #捕获异常: \n
# 捕获所有的异常 等同于except Exception:\n
except name:
# 捕获指定的异常\n
except name, value:
# 捕获指定的异常和额外的数据(实例)\n
except (name1, name2):\n
except (name1, name2), value:\n
except name4 as X:\n
# 如果没有发生异常\n
# 总会执行的部分\n
# 引发异常: raise子句(raise IndexError)\n
raise &instance&
# raise instance of a class, raise IndexError()\n
raise &class&
# make and raise instance of a class, raise IndexError\n
# reraise the most recent exception\n\n#-- Python3.x中的异常链: raise exception from otherException\n
except Exception as X:\n
raise IndexError('Bad') from X\n
\n#-- assert子句: assert &test&, &data&\n
assert x & 0, 'x must be negative'\n
\n#-- with/as环境管理器:作为常见的try/finally用法模式的替代方案\n
with expression [as variable], expression [as variable]:\n
with open('test.txt') as myfile:\n
for line in myfile: print(line)\n
# 等同于:\n
myfile = open('test.txt')\n
for line in myfile: print(line)\n
finally:\n
myfile.close()\n\n#-- 用户自定义异常: class Bad(Exception):.....\n
Exception超类 / except基类即可捕获到其所有子类\n
Exception超类有默认的打印消息和状态 当然也可以定制打印显示:\n
class MyBad(Exception):\n
def __str__(self):\n
return '定制的打印消息'\n
except MyBad as x:\n
print(x)\n
\n#-- 用户定制异常数据\n
class FormatError(Exception):\n
def __init__(self, line ,file):\n
self.line = line\n
self.file = file\n
raise FormatError(42, 'test.py')\n
except FormatError as X:\n
print('Error at ', X.file, X.line)\n
# 用户定制异常行为(方法):以记录日志为例\n
class FormatError(Exception):\n
logfile = 'formaterror.txt'\n
def __init__(self, line ,file):\n
self.line = line\n
self.file = file\n
def logger(self):\n
open(self.logfile, 'a').write('Error at ', self.file, self.line)\n
raise FormatError(42, 'test.py')\n
except FormatError as X:\n
X.logger()\n\n#-- 关于sys.exc_info:允许一个异常处理器获取对最近引发的异常的访问\n
# 此时sys.exc_info()返回一个元组(type, value, traceback)\n
# type:正在处理的异常的异常类型\n
# value:引发的异常的实例\n
# traceback:堆栈信息\n
\n#-- 异常层次\n
BaseException\n
+-- SystemExit\n
+-- KeyboardInterrupt\n
+-- GeneratorExit\n
+-- Exception\n
+-- StopIteration\n
+-- ArithmeticError\n
+-- AssertionError\n
+-- AttributeError\n
+-- BufferError\n
+-- EOFError\n
+-- ImportError\n
+-- LookupError\n
+-- MemoryError\n
+-- NameError\n
+-- OSError\n
+-- ReferenceError\n
+-- RuntimeError\n
+-- SyntaxError\n
+-- SystemError\n
+-- TypeError\n
+-- ValueError\n
+-- Warning\n\n
\n\"\"\"Unicode和字节字符串---Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串\"\"\"\n\n#-- Python的字符串类型\n
\"\"\"Python2.x\"\"\"\n
# 1.str表示8位文本和二进制数据\n
# 2.unicode表示宽字符Unicode文本\n
\"\"\"Python3.x\"\"\"\n
# 1.str表示Unicode文本(8位或者更宽)\n
# 2.bytes表示不可变的二进制数据\n
# 3.bytearray是一种可变的bytes类型\n\n#-- 字符编码方法\n
\"\"\"ASCII\"\"\"
# 一个字节,只包含英文字符,0到127,共128个字符,利用函数可以进行字符和数字的相互转换\n
# 字符a的ASCII码为97,所以这里返回97\n
# 和上边的过程相反,返回字符'a'\n
\"\"\"Latin-1\"\"\"
# 一个字节,包含特殊字符,0到255,共256个字符,相当于对ASCII码的扩展\n
# 返回一个特殊字符:?\n
\"\"\"Unicode\"\"\"
# 宽字符,一个字符包含多个字节,一般用于亚洲的字符集,比如中文有好几万字\n
\"\"\"UTF-8\"\"\"
# 可变字节数,小于128的字符表示为单个字节,128到0X7FF之间的代码转换为两个字节,0X7FF以上的代码转换为3或4个字节\n
# 注意:可以看出来,ASCII码是Latin-1和UTF-8的一个子集\n
# 注意:utf-8是unicode的一种实现方式,unicode、gbk、gb2312是编码字符集\n
\n#-- 查看Python中的字符串编码名称,查看系统的编码\n
import encodings\n
help(encoding)\n
import sys\n
sys.platform
# 'win64'\n
sys.getdefaultencoding()
# 'utf-8'\n
sys.getdefaultencoding()
# 返回当前系统平台的编码类型\n
sys.getsizeof(object)
# 返回object占有的bytes的大小\n
\n#-- 源文件字符集编码声明: 添加注释来指定想要的编码形式 从而改变默认值 注释必须出现在脚本的第一行或者第二行\n
\"\"\"说明:其实这里只会检查#和coding:utf-8,其余的字符都是为了美观加上的\"\"\"\n
# _*_ coding: utf-8 _*_\n
# coding = utf-8\n
\n#-- #编码: 字符串 --& 原始字节
#解码: 原始字节 --& 字符串\n\n#-- Python3.x中的字符串应用\n
# 构建一个str对象,不可变对象\n
b = b'...'
# 构建一个bytes对象,不可变对象\n
s[0], b[0]
# 返回('.', 113)\n
s[1:], b[1:]
# 返回('..', b'..')\n
B = B\"\"\"\n
# B = b'\\nxxxx\\nyyyy\\n'\n
# 编码,将str字符串转化为其raw bytes形式:\n
str.encode(encoding = 'utf-8', errors = 'strict')\n
bytes(str, encoding)\n
# 编码例子:\n
S = 'egg'\n
S.encode()
# b'egg'\n
bytes(S, encoding = 'ascii')
# b'egg'\n
# 解码,将raw bytes字符串转化为str形式:\n
bytes.decode(encoding = 'utf-8', errors = 'strict')\n
str(bytes_or_buffer[, encoding[, errors]])\n
# 解码例子:\n
B = b'spam'\n
B.decode()
# 'spam'\n
# \"b'spam'\",不带编码的str调用,结果为打印该bytes对象\n
str(B, encoding = 'ascii')# 'spam',带编码的str调用,结果为转化该bytes对象\n
\n#-- Python2.x的编码问题\n
u = u'汉'\n
print repr(u)
# u'\\xba\\xba'\n
s = u.encode('UTF-8')\n
print repr(s)
# '\\xc2\\xba\\xc2\\xba'\n
u2 = s.decode('UTF-8')\n
print repr(u2)
# u'\\xba\\xba'\n
# 对unicode进行解码是错误的\n
s2 = u.decode('UTF-8')
# UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)\n
# 同样,对str进行编码也是错误的\n
u2 = s.encode('UTF-8')
# UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)\n\n#-- bytes对象\n
B = b'abc'\n
B = bytes('abc', 'ascii')\n
B = bytes([97, 98, 99])\n
B = 'abc'.encode()\n
# bytes对象的方法调用基本和str类型一致 但:B[0]返回的是ASCII码值97, 而不是b'a'\n
\n#-- #文本文件: 根据Unicode编码来解释文件内容,要么是平台的默认编码,要么是指定的编码类型\n
# 二进制文件:表示字节值的整数的一个序列 open('bin.txt', 'rb')\n
\n#-- Unicode文件\n
s = 'A\\xc4B\\xe8C'
# s = 'A?BèC'
len(s) = 5\n
#手动编码\n
l = s.encode('latin-1')
# l = b'A\\xc4B\\xe8C'
len(l) = 5\n
u = s.encode('utf-8')
# u = b'A\\xc3\\x84B\\xc3\\xa8C'
len(u) = 7\n
#文件输出编码\n
open('latindata', 'w', encoding = 'latin-1').write(s)\n
l = open('latindata', 'rb').read()
# l = b'A\\xc4B\\xe8C'
len(l) = 5\n
open('uft8data', 'w', encoding = 'utf-8').write(s)\n
u = open('uft8data', 'rb').read()
# u = b'A\\xc3\\x84B\\xc3\\xa8C'
len(u) = 7\n
#文件输入编码\n
s = open('latindata', 'r', encoding = 'latin-1').read()
# s = 'A?BèC'
len(s) = 5\n
s = open('latindata', 'rb').read().decode('latin-1')
# s = 'A?BèC'
len(s) = 5\n
s = open('utf8data', 'r', encoding = 'utf-8').read()
# s = 'A?BèC'
len(s) = 5\n
s = open('utf8data', 'rb').read().decode('utf-8')
# s = 'A?BèC'
len(s) = 5\n
\n\n\"\"\"其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他\"\"\"\n
\n#-- 60个字符解决FizzBuzz:\n
\"\"\"写一个程序, 打印数字1到100, 3的倍数打印“Fizz”来替换这个数, 5的倍数打印“Buzz”, 既是3又是5的倍数的打印“FizzBuzz”\"\"\"\n
for x in range(101):\n
print(\"fizz\"[x%3*4::]+\"buzz\"[x%5*4::] or x)
# 解释:最主要用到列表(字符串)的子表\n
\n#-- Python实现任意深度的赋值 例如a[0] = 'value1'; a[1][2] = 'value2'; a[3][4][5] = 'value3'\n
class MyDict(dict):\n
def __setitem__(self, key, value):
# 该函数不做任何改动 这里只是为了输出\n
print('setitem:', key, value, self)\n
super().__setitem__(key, value)\n
def __getitem__(self, item):
# 主要技巧在该函数\n
print('getitem:', item, self)
# 输出信息\n
# 基本思路: a[1][2]赋值时 需要先取出a[1] 然后给a[1]的[2]赋值\n
if item not in self:
# 如果a[1]不存在 则需要新建一个dict 并使得a[1] = dict\n
temp = MyDict()
# 新建的dict: temp\n
super().__setitem__(item, temp)
# 赋值a[1] = temp\n
return temp
# 返回temp 使得temp[2] = value有效\n
return super().__getitem__(item)
# 如果a[1]存在 则直接返回a[1]\n
test = MyDict()\n
test[0] = 'test'\n
print(test[0])\n
test[1][2] = 'test1'\n
print(test[1][2])\n
test[1][3] = 'test2'\n
print(test[1][3])\n\n#-- Python中的多维数组\n
lists = [0] * 3
# 扩展list,结果为[0, 0, 0]\n
lists = [[]] * 3
# 多维数组,结果为[[], [], []],但有问题,往下看\n
lists[0].append(3)
# 期望看到的结果[[3], [], []],实际结果[[3], [3], [3]],原因:list*n操作,是浅拷贝,如何避免?往下看\n
lists = [[] for i in range(3)]
# 多维数组,结果为[[], [], []]\n
lists[0].append(3)
# 结果为[[3], [], []]\n
lists[1].append(6)
# 结果为[[3], [6], []]\n
lis

我要回帖

更多关于 matplotlib 动态折线 的文章

 

随机推荐