Python运维基础 (7) 面向对象

基础概念

(1)类: 用来描述具有相同的属性方法对象的集合。它定义了该集合中每个对象所共有的属性和方法对象是类的实例,世间万物,皆可分类。
(2)一切皆为对象
(3)对象:类的实体。eg..\一个叫Amy的可爱小女孩
(4)方法:人会走,会思考\狗会叫,会咬人\即定义一个类的各个功能(类中定义的函数)
(5)继承:即一个派生类继承基类。继承也允许把一个派生类的对象作为一个基类对象对待。
(6)方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写。
(7)实例化:创建一个类的实例,类的具体对象

创建类

eg:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def talk(self, msg=0):
        self.msg = msg
        if self.msg != 0:
            print("My name is %s, i'm %s years old." % (self.name, self.age))
        else:
            print("hahaha")


p = Person("zhuzhuzhu", "18")
p.talk("Hello, My name is %s " % p.name)

init()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
类的方法与普通的函数有一个特别的区别——它必须传入一个额外的参数名称, 一般大家习惯传入self,self代表类的实例,虽然在调用时不需要传入对应的参数,但是在定义类时是必须要有的

创建实例对象以及访问属性

类的实例化过程类似于函数的调用,我们可以通过类的名称来进行类的实例化~
eg:

对于上例中创建的类,我们来进行类的实例化
#  创建Person类的第一个实例对象
p1 = Person("zhuzhuzhu", "18")
#  创建Person类的第二个实例对象
p2 = Person("yanyanyan", "16")
之后,我们可以通过点号·来访问对象属性,也可对类的属性进行修改,删除,添加等操作
p1.talk()
p2.talk()
p1.salary = 10000  # 增加了“salary”这个属性
p1.salary  =20000  # 对该属性进行修改
del p1.salary  # 删除salary属性

另外,我们还可以使用以下函数的形式来访问属性

getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) :检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。

hasattr(p1, 'salary')    # 如果存在 'salary' 属性返回 True。
getattr(p1, 'salary')    # 返回 'salary' 属性的值
setattr(p1, 'salary', 10000) # 添加属性 'salary' 值为 10000
delattr(p1, 'salary')    # 删除属性 'salary'

类的继承

eg:

class Animal:  # 定义父类
    def __init__(self):  # 调用父类构造函数
        print("我是动物")

    def talk(self):  # 调用父类方法
        print("动物叫")


class Dog(Animal):  # 定义子类
    def __init__(self):  # 调用子类构造函数
        print("我是小狗")
    def bark(self):  # 调用父类方法
        print("汪汪汪")

d = Dog()  #实例化子类
d.talk()  #调用父类方法
d.bark()  #调用子类方法

OUTPUT

我是小狗
动物叫
汪汪汪

也可以继承多个类

class A:        # 定义类 A
.....

class B:         # 定义类 B
.....

class C(A, B):   # 继承类 A 和 B
.....

方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,即当子类的方法覆盖了父类的同名方法,调用时会执行子类方法:
eg:

上例中,父类有一个方法“talk”,调用该方法会输出“动物叫”,而我的需求是让它输出“小狗叫”,则可以在子类中进行方法的重写。
class Animal:  # 定义父类
    def __init__(self):  # 调用父类构造函数
        print("我是动物")

    def talk(self):  # 调用父类方法
        print("动物叫")


class Dog(Animal):  # 定义子类
    def __init__(self):  # 调用子类构造函数
        print("我是小狗")
    def talk(self):
        print("小狗叫")
    def bark(self):  # 调用父类方法
        print("汪汪汪")

d = Dog()  #实例化子类
d.talk()  #调用重写方法
d.bark()  #调用子类方法

OUTPUT

我是小狗
小狗叫
汪汪汪

多态

要理解什么是多态,我们首先要对数据类型再作一点说明。当我们定义一个class的时候,实际上就定义了一种数据类型。

a = list()  # a是list类型
b = Dog()  # b是Dog类型

isinstance来判断某一个变量是否属于某个数据类型:
即:

isinstance(a, list)
isinstance(b, Dog)

OUTPUT1 : true
OUTPUT2 : true

但是我们发现,当输入isinstance(b, Animal)时,返回结果也为true,这就说明,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。

反过来则不成立。
这里写图片描述

接着,我们定义一个让动物叫两次的函数,调用该函数时传入Animal类型的实参,即使它接收一个Animal类型的变量:

def talk_twice(animal):
    animal.talk()
    animal.talk()
talk_twice(Animal())

OUTPUT :
动物叫
动物叫

talk_twice(Dog())

OUTPUT :
小狗叫
小狗叫

此时,若我们再定义一个从Animal类派生的类Duck:

 class Duck(Animal):
     def talk(self):
         print("鸭子叫")

OUTPUT:
鸭子叫
鸭子叫

你会发现,新增一个Animal的子类,不必对talk_twice()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态
因此,一个变量,只要确定它是Animal类或者是Animal的子类,我们就可以放心的调用Animal里的方法。
这便是多态的优势:调用方只管调用,不管细节。

开闭原则:

对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的talk_twice()等函数。

总结:

继承可以把父类中的所有方法拿来供子类使用,子类只需要添加新增的方法并且修改覆盖父类中不适合的方法即可。
有了继承,才能有多态!

类的属性与方法

类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。

类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods

eg:

class Person:
    __private = "talk"
    public = "eat"

    def __init__(self, run, smile, cry):
        self.run = run
        self.smile = smile
        self.cry = cry

    def behavior(self):
        print("I'm a good man,because I love %s." % self.smile)


zhuzhuzhu = Person("lalala", "hahaha", "wuwuwu")
zhuzhuzhu.behavior()
print(zhuzhuzhu.public)
print(zhuzhuzhu.__private)

此时会报一个错:

File “E:/python study/Code/PrivateClass.py”, line 23, in
print(zhuzhuzhu.__private)
AttributeError: ‘Person’ object has no attribute ‘__private’
Process finished with exit code 1

这是因为,实例不能访问私有变量。Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName (对象.私有类名.私有属性名)访问属性,即用以下代码来替换上例中的print(zhuzhuzhu.__private)

print(zhuzhuzhu._Person__private)

几个区别

单下划线、双下划线、头尾双下划线说明:

1__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。
2_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
3__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

猜你喜欢

转载自blog.csdn.net/in_nocence/article/details/79981058