标签归档:Python

python基础15-面向对象编程(3)

上篇我们说了类的基本概念,这篇我们谈谈类的一个很重要的概念-继承, 在工作中使用类继承非常常见,当我们编写一个类时并非每次都要从头实现一个类,如果你要实现的类在方法或属性另一个类里已经有了,这时候可以通过继承来自动 获得这个类的所有属性和方法,这个类就叫父类,继承父类的类我们叫子类,通过类的继承,可以让我们减少我们同一段代码要输入好几次的情况,Python允许子类继承多个父类,这种特性我们叫多重继承,这个不是python语言特性,c++也是一样,接下来让我们了解下如何通过代码的方式实现类的继承。

我们还用我们上次定义的Car类来说明继承关系, 代码如下:

这个类我加了一个方法,用来展示汽油用来信息, 现实中我们知道除了汽油,现在电动车也非常流行了,所以我们如果我们需要定义一个电动汽车的类,我们会发现同样在初始化类的时候也需要公司,品牌,生产时间必须的参数,因为这些信息在Car这个类在初始化的时候已经定义了,所以我们可以直接继承Car来实现我一个新的电动车的类,代码如下:

短短二行就实现了父类的继承,代码一会解释,主要是super函数,我们先看结果是否跟我们想的一样,因为根据继承的概念,如果子类继承了一个父类,就会获得父类所有的属性和方法,那接下来让我们看看是不是这样的:

打印出:

可以看到在我们子类Evcar中,我们并没有定义get_car_info这个方法,但我们一样可以直接使用,说明子类继承了父类的方法,直接调用了父类的方法打印了信息,这时候我们输出子类的__bases__属性(__bases__类属性包含了其父类的集合元组),如下:

显示父类是Car。

我们说回代码中的内容, 关于继承父类_方法,现在因为python版本出于2和3交替阶段,写法也有不同,汇总2个方法如下:

1、用super函数,这个函数的目的就是帮助程序员找出相应的父类,然后方便调用相关的属性和方法,在版本2中写法就是跟我上面的例子一样,在3中去掉了super函数中的2个参数,直接调用即可。

2、在子类中显示调用父类初始化,例如:上面的super函数行可以替换成这样:

上面我们了解到了子类和父类的概念,也了解了一个子类如何继承一个父类的属性和方法,接下来我们要看看如何覆盖父类的方法,那为什么要覆盖呢,因为有时候我们从父类中继承的一些方法,不一定能满足或适合子类使用,这时候子类就可以重新这个方法,来实现对父类方法的覆盖,例如我们的例子,petrol_used()这个方法显示不适合用在电动汽车上,那这时候我们可以在子类中重新这个方法,如下:

方法名词同父类相同, 这时候我们调用父类和子类同名的方法会得到如下信息:

从结果看子类的方法被运行了,实现了我们子类的方法覆盖了父类的方法。

关于类对基本内容就写到这里了,希望小伙伴们在了解了基本概念的基础上,多在项目中运用,逐步体会面向对象的编程思想,下篇我们谈一下python的并发编程,我们的基础内容就全部结束了,感谢大家支持。

 

python基础15-面向对象编程(2)

上篇我们介绍了Python面向对象编程的基本理论知识,这篇我们开始看如何实际定义类和如何调用类方法,在Python中定义类的关键字是class,我们就拿周边的事物说起,这样大家也比较容易理解,比如我们定义一个汽车类,如下:

以上代码我们定义了一个简单的汽车类,我们来逐行说明解释下代码, 大家知道def是用来定义一个函数的,那如果在类里定义一个函数,这个函数就称为方法,除了名字不同之外,我们之前学的关于函数的内容都适用于方法,所以在这里__init__()我们理解是一个函数,因为是在类中,所以我们叫它__init__()方法,如果是第一次接触,可能看着有点不习惯,因为这个方法前后都有二个下划线,跟我们平时看到的名称不大一样, 这种写法主要是避免Python默认方法跟自定义的方法发生冲突,所以我们可以不用管它形式,知道它本质就可以了,在Python中还有很多这种形式的特殊方法,另外__init__()方法也被称为构造器,它用于根据类的定义创建实例。

这里__init__()定义中包含四个形参,其它参数都容易理解,我们着重看第一个参数self,在Pythonl类中,self不可缺少,并且它必须放在其它参数前面,因为python在调用__init__()方法创建实例时,将自动传入实参self, self是类实例方法中引用方法所绑定的实例,它是指向实例本身的引用,让实例能够访问类中的属性和方法,当我们创建car实例时,我们只需要给后面三个参数就可以了,self因为会自动传递,所以我们不需要再传递。

接下来我们创建一个实例,看如何调用:

打印出:

我们创建一个实例my_car,  我们传递公司,品牌,时间参数, self我们并没有传递, 然后实例调用方法get_car_info()打印出了汽车实例的信息。

这个类基本是最简单的类了,大家看到在类中的方法都需要self参数,这种方法叫实例方法,在类中除了实例方法,还有一种叫静态方法,静态类方法无需传入self函数,但需要@staticmethod修饰,类和实例都可以访问静态方法。

以上我们拿生活的汽车来举例说明,在运维中的应用基本也是这个思路去实现,比如数据库类,我们可以在__init__()方法里把数据库的名称,IP,端口,数据库用户,密码等放到这个方法里,再定义一个方法根据这些去连接db,然后返回连接对象来对数据库进行操作,这个就是实现一个DB类的基本思路。

这篇我们就简单说一下类和实例内容,另外类会有父类、子类区分,那么关于子类和父类继承关系以及子类重写父类方法内容我们会放到下篇去介绍, 下篇见~

python基础10-文件读写part1

本篇主要讲解Python对文件的处理,对文件的读写是我们日常中最用的操作了,不管你是分析日志还是要将生成的结果写到文件里,都需要用到读文件的读写操作,在python下对文件非常容易,我们使用它的内建函数open()就可以打开一个文件,如果你要打开个文件一般的用法是:

这里fi是open()返回的文件对象,有的刚接触的小伙伴可能就要问了,啥叫文件对象呀,对象这是一个抽象的概念,在Python里一切都是对象,你可以理解为如果它是一个对象,那么它将有它的属性和方法, 不知道这么说清楚没有,没理解也没关系,多用就明白了, 另一个mode指明对文件的访问模式,常用模式如下:

r: 以读方式打开文件

w:以写方式打开文件

rb:以二进制读模式打开

wb:以二进制写模式打开

a:以追加模式打开

a+:以读写模式打开

这些模式基本覆盖了我们日常的对文件操作,当然除了这些还有一些其他模式,想深入了解的可以去自己学习下,如果是对运维来说这些基本够了。

首先我们来了解读文件的方法:

1、read()方法,这个方法不多介绍了,因为它有个硬伤就是它会一次将读入文件的所有内容,所以读大文件,会把你内存吃满。

2、readline()方法:这个函数在某些场景有估计会用到,它的作用就是每次从文件中读取一行出来,我们看个例子:

这个是每次读取一行,所以需要用到while 循环,用if来判断文件是否已经结束,如果结束就跳出,否则打印改行。

3、readlines()方法:这个方法我用的不多,因为它也有个硬伤就是它返回一个列表,所以当文件足够大的时候,返回的列表就会异常的大,就会非常慢,不过它的好处就是可以快速释放文件资源,我们了解下就可以,对付一般文件还是可以的,例子如下:

4、采用文件迭代的方式访问文件,这种方式应该是最常用的读取文件方式了,因为我们可以直接迭代文件对象,例子如下:

 

以上就是读取文件的方法了,掌握了这几种基本就可以了,现在我们来看看如何将我们程序的结果写入到文件中, 写文件就用write()方法,不过有很多细节需要注意,我们先来看个简单的,就是我们把读出的文件写入到另一个文件里,如下:

因为要生成一个新文件,所以需要打开一个新文件用来写入。

刚才为什么write()方法有些小细节呢,就是日常我们操作做,会出现往文件中写入中文的情况,如果你不进行编码,写入的中文是无法识别的,这时候就需要在写入前进行将字符串编码,例如将字符串编码为gb2312或utf-8,

 

当然如果是脚本,需要在脚本头部加上:

这篇就到这里吧,本来想把CSV文件如何生成也一起写了,但发现篇幅有点长,就留到下篇吧,当然这篇算是基础中的基础了,关于读出的行如何进行处理,我并没有写任何逻辑去深入展开,因为涉及一些正则方面的知识,后续可以跟正则一起介绍。

python基础9-模块和包、标准库

python中的模块其实就是一个.py结尾的文件,也许有的小伙伴不太理解为什么我们需要模块,其实在在我们日常编程中,有很多功能是重复的,在下次我们编写一个新的需求时没必要从头开始,这时候我们就可以重用我们之前写的代码块,这样经过长时间积累把一些常用的功能以文件的方式保存起来,等需要的时候直接引用,不必从零开始实现某些功能,所以说代码写的越多就会发现复制粘贴真是人类一项伟大的发明。

那按上面说的模块就是一个文件,那照这么说我也能写一个模块喽,没错,只要你愿意每个人都可以写自己的模块,我们来个简单的例子,我们vi 一个文件,命名为mymodule.py,代码只有很简单的二行代码:

这个就是我们自己写的模块了,接下来我们看如何使用:

import语句我们待会说,主要大家先了解下如何使用我们定义的模块,如果你觉得这么简单会不会是个假模块,那接下来看看这些输出:

是不是有点似曾相识的感觉,所以说写一个自己专属的模块并不困难,那问题来了,既然模块这么简单,你写一个,我写一个,很容易会重名呀,那如果重名了,导入的时候不就出问题了吗?是的,没错,所以要解决模块名字冲突的问题,就引入的包了的概念。

包是一个有层次的文件目录结构,所以它不是一个单独的文件,它要比模块结构复杂,模块可以是一个文件,但包是一个目录结构,它可以包含N个模块,同时它还可以包含多个子包,子包下还可以有N个模块,包的目录里一定有这个__init__.py文件,这样这个目录结构才会被识别成包,简单的包目录结构如下:

所以可以通过把模块放入不同的包里,这样只要包名不冲突,里面的模块名冲突了也不会有问题。

到这我们就把模块和包的基本概念说完了,下面我们看如何在代码中使用他们,我们把模块和包的导入归类,一般有如下几种方式:

1、import 模块名

2、from 模块名  import  name….

3、import 模块名 as 别名  # 作用就是给导入的模块另起一个名字,一般是原模块名太长或名字你在变量里用了这个名字冲突了,所以必须要起一个不一样的名字。

包的导入:

1、import 包名

2、from 包名  import 模块名

3、from 包名 import *      #用这种方式需要注意,这就用到我们刚才说的包里__init__.py文件了,这个文件一般为空,也可以写代码,__init__.py定义了很重要的变量叫__all__的列表变量,导入时只有它包含的模块名字的列表将被导入,如果__all__列表变量没有定义,这条语句不会导入所有的包的子模块,只导入了包自己。

模块和包的导入方式相对简单,还有其它一些方式,在日后大家碰到了基本看几次就明白了,说完了包我们该说最核心的标准库了。

前面为什么要花这么长篇幅说模块和包,因为理解了这些,理解python的标准库就简单多了,因为标准库就是以模块和包的形式存在的,稍微了解Python的小伙伴都知道,Python本身自己带有大量的标准库,这些库在安装python的时候也安装了,所以我们可以在代码里直接import 使用就可以了,除了标准库我们还经常听到一些第三方库,第三方库也是模块或包,之所以叫第三方是因为我们无法直接使用,使用前需要先安装,才能import,否则会提示没有这个模块,都说python有大量的库文件可以使用,这真不是吹的,撇开第三方库不说,就标准库就够吓人的,参考地址:

python自带这么多标准库自然对我们编程是好事,但问题也来了,这么多库我们要怎么学习呢,别说看第三方库,就标准库全学一遍也得几个月,在这里我谈一下我自己的一些学习心得:

1、首先可以肯定的是我们没必要精通每个标准库的模块,因为在实际的编程中你会发现有些第三方库比标准库更好,所以用你最想用的。

2、根据你工作内容来学习,就是你工作中用到那些就要深入学习那些,一些用不到的只要了解就可以了。

3、标准库和第三方库的使用选择,这个看个人,如果有比较成熟的第三方库比标准库更好,为何不用呢,比如: requests

就说这三点吧,如果大家有需要交流的可以给我留言。

最后推荐一本书《python标准库》,这本书很厚,里面有大量的代码实例来讲解Python标准模块使用,引用作者一句话:没有什么比给一段代码去更快的学习python标准库了。这边书大家可以放在案头当参数书使用, 如果有需要电子版的可以在后台发给我邮箱我单独发给大家,不过是英文版的,当然本书是以代码为主的,一点也不影响阅读效果,:)

python基础8-函数

函数的概念我估计每个人都不陌生,我们在学习C语言的时候就知道怎么定义一个函数了,那为什么要定义函数呢? 一般情况是第一你为了让主逻辑更清晰,第二是为了代码重用, 经常写shell脚本的人应该都有自己的函数库,在Python下也类似,很多功能可以复用,了解完这些我们来看看Python下的函数定义和调用。

1、函数定义和调用

在python下定义一个函数要以def开头,然后跟上函数名称和一个括号,最后加上冒号,然后回车空格来写代码块,我们来看一个最简单的函数:

这里定义了一个叫show的函数名称,函数体就包含了一个执行命令,调用方式是在函数名称后加小括号,在函数名称后的括号可以加入参数传给到函数体内,例如:

这里我们定义了另一个add函数,传入2参数,然后打印两个数的和。

在函数体内除了用print打印我们需要看的内容,还有非常重要的return语句,这个是返回函数处理完的结果,例如我之前写的生成安全组Json格式的函数,完整代码请看这里:

这个函数功能就是将一个字典转成json格式的然后返回。

函数的参数除了上面我们说的基本参数外还有不定长参数,就是你的参数数量不确定,这是我们要在传入的参数前加一个“*”来表示,我们来个例子:

这里传入的*vartuple就是一个不定长的变量,可以没有,也可以是多个,如果多个在函数体内就做一个元组来处理,你要问你怎么知道是作为一个元组来处理呢,我们来测试下看看:

代码没变,我只加了一句,最后输入的就是一个元组类型,也就说明不管你后传入多少参数,统一作为一个元组来处理,相当于传入一个元组。

除了元组可变长参数,还有一种是关键字参数(字典),j这种方式可以将一个Key=value作为参数传入函数中,参数的表示方式是在变量前加两个“**”,关键字参数应该是函数的最后一个参数,例子如下:

最后说一下,我们说的这些参数并不是单一使用的,它们完全可以放到一个函数中,例如:

函数要根据传入的参数进行对应的处理。

 

前面讲的都是我们需要定义名字的函数,在python里还有一种函数叫匿名函数lambda,它的格式非常简答,但它不太容易理解,它的用法格式如下:

lambda 参数:表达式

例如:

另一个有趣的例子:

当然除了这些python内置了很多有用的函数想map(),reduce(),filter()等,这个后续我们可以单独说这几个函数。

最后我们要说一下函数的变量作用域,变量分局部变量和全局变量,当python解释语句时,先从局部变量开始搜索,如果局部变量没有,就会在全局变量里找,在函数体内定义的是局部变量,函数外的变量是全局变量,那这里就有一个问题,如果全局变量跟函数体内定义的变量名称相同,那在执行时全局变量就会被覆盖,因为在局部变量找到了就不会再全局变量里找了,所以函数要引用一个全局变量就必须用global语句,例如:

global语句的作用是让函数体直接使用全局变量,而无需在函数体内再定义个新局部变量了。

再说最后一个问题,那就是有时候我们经常会在python里看到以两个下划线(__)开头的和结束的名词,大家也不用觉得很奇怪,这些都是python自己保留的用法,所以我们在自定义的变量中是不能用的,例如function.__name__就是函数的名词,function.__doc__就是函数的文档字符串可以简单理解为注释内容。

函数部分就到这里,关于函数的内容真的非常多,我这里说的也基本是很入门的内容,一些高级的内容像闭包,装饰器等实在无法展开写,因为每个都够写几篇的,所以这些后续我们单独去详细讨论,当然如果是初学者,这两个东西搞不懂也不影响你学习,等你用到了在学都来得及,前期主要是把这些基本的打扎实,在此基础上去理解一些概念就会非常简单,最后感谢大家阅读本文章,喜欢的朋友请帮忙转发下吧~