分类目录归档: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基础14-面向对象编程

从这篇起我们开始学习一些python面向对象的编程知识,面向对象编程是一种编程方式,这种编程方式是基于类和对象的使用,当然除了面向对象这种方式还有我们知道的面向过程编程方式,在这里不多展开说了,大家只要知道现在主流的编程语言都是面向对象语言就可以了,例如java,C++等,在Python设计之出就是一门面向对象语言,但它不强制你必须写OO的程序,但在java中,万物皆类,必须用OO的方式来编程, 我理解这可能也是Python入门容易的一个方面, 在我们之前写的程序都是用函数来实现的,我们没讲太多的概念, 但要学java, 必须先过OO这关,否则根本没法继续, 在正式开始介绍面向对象编程前我们先了解下面向对象的一些术语:

  • 类:对具有相同数据和方法的一组对象的描述或定义。
  • 对象:对象是一个类的实例。
  • 实例化:创建一个类的实例,类的具体对象
  • 实例属性(instance attribute):一个对象的数据或函数元素
  • 实例方法(instance method):所有存取或者更新对象某个实例一条或者多条属性的函数的集合。
  • 类属性(classattribute):属于一个类中所有对象的属性,仅与其被定义的类相绑定
  • 类方法(classmethod):那些无须特定的对性实例就能够工作的从属于类的函数。

除了基本术语,面向对象还有三大特性: 继承(Inheritance)、封装(Encapsulation)和多态(Polymorphism),概念太多就不全部展开说了,因为就单单面向对象的知识就够写本书了,有的小伙伴可能觉得面向对象的理论知识太多了,能不学吗?或者说面向对象编程重要吗? 在这我给一个肯定的答复:面向对象编程非常重要,如果你想要深入学习编程,面向对象是必须要了解的,因为现在一些开源的项目或者稍微大点的项目基本都是面向对象思路,如果你不懂,那些代码你根本没法看,就是硬着头皮看我估计也很难理清作者的编程思路,看到吐血直到自己放弃,在刚开始我们用不到,但当我们做一些项目时我们就要用到面向对象的方式去设计我们的代码实现了, 所以这也就是为什么面向对象编程在一些书里属于高级部分的原因,后续如果有时间我可以分享下我是如何阅读别人代码的。

上面讲的比较抽象,下面我通过一些大白话来理解下类和对象,那如何定义类,什么时候需要定义类呢?根据我们前面的概念,一个类就是具有相同属性和方法的对象定义或描述,例如我们人就是一个类,因为每个人都是人,但每个人又有不同,肤色,名字,性别等,这些就是人的属性,人还会走,跑,这些就是人的方法,所以如果一个事物有共性的部分,我们就可以抽象出来定义成一个类,另一个例子 比如我们现在经常看到的满大街的ofo 和摩拜自行车,从类的概念理解,每个自行车都有颜色,轮子等属性, 而自行车行走,停止就是自行车的方法,我用通过调用这些方法来控制自行车的行为,通过颜色、公司属性来定义一个具体的自行车,这就是类和对象,先定义类,然后类实例化一个对象,每个对象是具体的事物,他们有共同点又有不同点; 我们再来说一个项目中的例子,我们用到的数据库类, 里面的数据库名称,DBIP, 连接的用户名,密码都是属性, 而对数据库的查询,更新就是方法,例子就说这些, 大家应该都理解了, 这篇就写到这里吧,具体代码操作我们放下篇,我们看如何定义类、实例化和调用实例化方法。

 

 

 

python基础13-正则表达式

正则表达式是我们运维工作中比较常用,在工作中用的比较多的应该就是配合grep命令从某个文本中匹配出我们需要的内容,Python中集成了正则模块,可以直接调用正则调用来实现正则匹配,今天这篇我们就来介绍下Python的正则使用,因为正则表达式系统的展开说都够写一本书了,因为咱们主要介绍Python,  所以在这里我只介绍在python下的使用,不会系统的介绍什么是正则表达式和正则表达式的规则,不过本篇中的所有正则内容我都会解释,保证你看这篇文章无任何障碍。

python中集成正则模块re,所以我们使用就是Import re就可以了,import后就可以直接使用re模块的函数了,我们先来看第一个re.match的用法:

re.match函数从字符串的起始部分进行模式匹配,如果匹配成功就返回匹配对象,看个例子:

其中m是返回的匹配对象,group()是匹配对象的方法,返回整个匹配对象,刚才说了mach只能匹配字符串的开头,所以如果可以看一个匹配不成功的例子:

大家可以看到匹配不成功是,m就变成了None.

其实,我们大多数搜索特定字符串都在一个字符串的中间部门,这时候match就不行了,这时候就需要用到search()了,它的工作方式跟match一样,不同的是它可以搜索字符串的任意位置,匹配到就算成功,还用刚才的例子:

显示匹配成功,这里顺便介绍2个参数:

re.M:表示^和$分别匹配目标字符串的起始和结尾,而不是严格匹配整个字符串本身的起始和结束。

re.I表示不区分大小写

search()是搜索字符串中第一次出现的正则表达式的模式,所以让我们稍微修改下上面的例子:

明明有二个please,为什么只匹配了一个,这个没错,看我们刚说的功能介绍就明白了,那如果我想要都匹配呢,那就要用另一个函数findal()了,这个函数查找字符串中所有不是重复出现的正则模式,然后返回一个列表,看清楚,它是直接返回一个列表,还是刚才的例子:

除了字符串查询匹配,还有个一个分割函数也非常有用split,我们都知道字符串本身也带一个split方法,也能进行字符串分割,那它们有什么不同呢,其实如果不适用特殊的正则表达式进行模式匹配,它们的工作方式相同,但re.split适用于更复杂的的分割处理,我们来个例子看看re.split的厉害之处:

这么看它们基本是的功能是一样的,正则里\s表示空格,*表示0个或多个, 但我们遇到一个不完全规则的字符串,比如以不固定的字符或数字来分割,例如:line = ‘abc12def34ghi’, 要求这个以2个数字来分割,这个时候就要用到re.split了,看个例子:

正则里\d匹配任何十进制数字。

关于re的函数方法我们就介绍到这里,接下来我们说一下匹配对象的group和groups方法的区别,因为这2个会使人比较迷惑,我们来看个网上例子:

首先这例子里有2个问题需要去理解:

1.首先是match的问题.match是从开头匹配,为什么会匹配到c3呢?
2.group(0)是整个匹配项,为什么groups()中没有呢?

这里我说一下我的解释,match匹配从头匹配没错,但如果加上数字参数,它就可以显示特定子组的,第二个问题,没有的原因是groups()是列出从编号1开始的所有group,所以没有group(0), 因为这里只有一个分组,所以编号1就是c3,官方解释:

 

写在最后,grep命令是我们用来过滤某些字段信息的必备工具,我们就来实现一个简单的grep功能的脚本,代码如下:

这个脚本配合argparse模块,可以指定关键字和要搜索的文件内容,最后显示出匹配的行。

截止目前我们已经了解了Python大部分的功能,一路跟过来的小伙伴我想也应该能写些自己的脚本了,所以基本的内容就到这里了,下篇开始我们要讲解python的面向对象编程了,下篇见。

 

python基础12-系统操作

这篇我们介绍下跟操作系统相关的一些内容, 操作系统的技能算是我们运维人的基本功了,因为如果连敲命令都吃力的话也提谈不上什么自动化了, 在linux里我们经常用的命令比如, cp,  mv, mkdir, chown,chmod等基本一天下来也就这几个命令反复使用,其实只看这些体现不出来运维的能力,真正体现运维能力的地方是出现问题时如何分析解决,这是难点,这也跟经验有关, 在一个复杂的问题面前,这时候基本功就显得尤为重要,对操作系统理解的深度体现了解决问题的能力差别,如果你想在在操作系统层面理解的更深一点,我推荐你读一下《现代操作系统》这本书,读完这本书你在操作系统层面的认知会有一个比较大的提升,按照运维技术能力的发展,在理解操了操作系统的基础上这个时候我们一般开始接触学习shell编程了, 在这里我说一下做为一个Linux系统管理员,shell是你必须要掌握的技能,虽然Python都能实现,但我仍不建议你跳过shell这个重要阶段,因为如果你做运维,你不可能避免接触shell,就算你不写,你也避免不了去看别人写的shell,还有就是公司不可能就你一个运维,你不用不代表别人不用,你想想如果大家在一个团队里工作,如果都互相看不懂别人的脚本,大家还怎么配合工作?

搞定上面shell阶段后,出于对自己更高的要求(其实想多挣点钱),了解到了现在公司招聘都需要Python,就开始看书发奋学习,在看过书后,开始上手写一些功能脚本,很快就会发现用python很麻烦,不如用shell直接操作方便,不过这也难不倒我们,一顿搜索之后发现了一个宝贝,os.system(), 这个函数可以直接调用shell命令来执行,从那一刻起就像手中有了亚瑟大宝剑,所有需要shell执行的部分全部用这个函数来完成, 等写完某个脚本后感觉非常有成就感,而且感觉自己python水平与日俱增,自我感觉非常良好,但你实际去看写的每个脚本,你发现不到100行的Python代码里有,有一半以上的行都是os.system()调用的shell命令, 好好的shell命令硬生生的在外面包了一层python代码,每当我看到这些代码,我都无语,如果你也在写这种脚本,我建议你尽快停掉这种方式吧,因为你即使写一万行这种代码,对你学习python基本没有质的提升,何必呢,看着都累。

写在最后,因为关于操作系统方面的内容比较基础,我也没准备什么例子去展示,不过为了大家进一步的了解,我列了下一些系统方面的操作供大家参考学习:

判断目录存在和是否文件:

部分常用系统命令:

文件匹配,glob模块使用:

在操作系统层面还有对日期时间的处理可以看我之前的文章。

当然有时避免不了要调用shell命令,但我建议用这种方式,os.system()方式以后就取消了。