Python系列教程(三十九):类的基本概念

    今天开始进入面向对象的世界,以一种新的思维,一种借鉴现实世界的理念去认识编程。
在学习面向对象的时候,有很多理论上的概念,非常抽象,所以我们可以借鉴现实世界的例子去解读面向对象,这样非常有助于我们理解和学习。

  一、面向对象概述  

1、编程语言的分类

      面向机器:

        比较底层的、接近机器能理解的编程语言,比如汇编语言,最早接触汇编的时候还是在做一些免杀脱壳和加壳的时候,汇编就是各种指令,非常底层的CPU指令集,所以非常不适合企业级快速的开发。

      面向过程:

        在处理业务需求的时候,把事情的处理分为各个阶段,按照流程规范进行解决,先解决什么,再解决什么,一步一步的解决然后达到我们的目的,最常见的就是C语言和shell了。这种编程理念比较好理解,就跟人做事一样去解决业务问题。

      面向对象:

        面向对象的编程思想是相对比较高级的,它借鉴了我们现实世界的当中的理念,对事物的抽象和具体这种概念带进了编程的世界。以一种更加贴近人类的思想去编程,最具代表的就是C++,java,python。它更适合当今这种软件工程发展和快速开发的模式。

2、什么是面向对象

    面向对象,重点是对象这两个字,这里的对象就不是男女朋友的对象了,这里的对象指的是从某个抽象的概念实例化出一个具体的东西,感觉这么描述还是有点抽象,但是你要知道的是,对象就是一个具体的,实实在在的东西。

    我们针对这个具体的对象去做编程,或者说,我们的编程就是围绕怎么去构建这个对象,比如给这个对象赋予什么属性或者方法,这样就可以实现我们的功能。

    类:class,一个虚拟的抽象的概念,和我们现实世界中的类是一个意思,就是具有共同特征的一类事物的集合,比如说人类,鸟类,汽车类等等。一个类中最重要的就是属性和方法,这里的属性就好比如人类中的头发颜色,皮肤颜色等等,而方法就好比如人类的能力,比如会跑,会跳,会搞事等等。

    对象:从类实例化而来,是一个具体的概念,一个实实在在的东西,它是一个一个实体,就好比如人类实例化出了张三李四,他们最重要的也是属性和方法,他们的属性和方法都是从类而来,但是张三和李四是两个不同的人,张三可能有自己的头发颜色,李四也有可能自己的头发颜色。

3、面向对象的三要素

    封装:在面向对象编程中,最显而易见的特征就是封装,我们在定义一个类的时候,对这个类添加了很多属性和方法,但是我们在调用的时候,一般不会直接去调用类里面的方法或者属性的,而是通过实例化出一个具体对象,通过对象去调用,所以类的第一个作用就是可以把数据和方法封装起来,对外只暴露可以调用的接口。

    继承:类的继承和人类血缘关系的继承也是很类似的,祖类的方法继承给了父类,父类就同样拥有这个方法,而不需要再去编写一个一样的方法,所以跟函数一样,也可以实现代码复用的功能,这就是类的第二个作用。

    多态:子类继承不同的父类,就会拥有不同的方法和能力

  二、Python类的基本概念  

1、类的定义

class ClassName:
    语句块

    说明:

    ① 定义类的关键字:class

    ② 类的名字使用大驼峰(单词首字母大写)命名方式

    ③ 定义一个类之后,就产生了一个类对象,和前面学的函数对象是一样的,而我们的类名就是标识符,指向定义的这个类对象。

    示例:

class Connect:
    name = 'jimmy'
    
    def __init__(self, ip):
        self.ip = ip
        
    def ssh_connect(self):
        pass

2、类的基本概念

    类对象:指的是类本身,把整个类看成一个整体,它就是一个对象

    类的属性:一般指的是类的变量或者类的方法,还有以双下划线开头和结尾的特殊属性,都叫类的属性

    类的变量:比如上面示例中的变量‘name’,它定义在类中,所以是类的变量

    类的方法:比如上面示例中的方法‘ssh_connect’,它定义在类中,所以它已经不是普通的函数,它是类的方法,类的方法的第一个参数必然是self(self只是惯例名称,可以使用其他名称),他指的是当前实例本身,因为类的方法是给类的实例调用的,当类的实例调用类的方法时,会自动的把当前实例本身传入这个self当中,我们就可以在这个类的方法中,拿到这个实例进行一些操作。

    类的实例:定义一个类之后,肯定是要实例化一个对象的,类是抽象的,对象才的具体的。所以我们一般叫类的实例或者类的对象,都是指具体的某个对象。

3、__init__方法

    说明:在类中,以双下划线开头和结尾的方法,一般具体特殊意义,称为魔法方法,后面会详细介绍,这里先介绍第一个最最常用的__init__,它的作用就是每实例化一个对象时,自动调用该方法,所以我们很多初始化操作都会放在init这个方法中实现。

    ① __init__方法不是必须的,如果没有定义,则不调用,可以正常实例化对象

    ② __init__方法可以定义多个参数,它也是类的方法,所以第一个参数仍然是self,这个会自动传入,而其他参数就必须在实例化对象的时候传入,和我们的函数调用类似。

    ③ __init__方法不能有返回值,也就只能是None

#定义一个类,并且定义__init__初始化方法
class Connect:
    def __init__(self, ip, username, password, timeout=10, try_times=1):
        self.ip = ip
        self._username = username
        self._password = password
        self._ssh = None
        self._timeout = timeout
        self._try_times = try_times
        self.ssh_connect()
    
    def ssh_connect(self):
        pass

4、实例对象

    类定义完成之后,就需要实例化对象,实例化多少个对象看实际需求,一般是一个类,会实例化多个对象,而且每个实例对象都是独立的,有自己的属性,叫做对象属性

     实例化对象:

#根据上面定义的类,实例化多个对象
host1 = Connect('10.10.11.1', 'root', 'root123')
host2 = Connect('10.10.11.2', 'root', 'root123')
host3 = Connect('10.10.11.3', 'root', 'root123')

    实例对象调用类的方法:

#实例调用类的方法
host1.ssh_connect()
host2.ssh_connect()

    关于self的说明:

    我们在定义类的方法的时候,第一个参数都会默认保留给self,而在调用的时候,也不用手动传入参数,这个self指的就是每个实例对象本身,比如这里的host1,host2,host3,当用host1调用ssh_conncet()时,Python会自动的把host1这个实例对象传入第一个参数,也就是self。

    实例对象属性:

    实例化一个对象后,这个对象就可以拥有自己私有的属性,也叫对象变量,这些属性是绑定到每一个对象上的,比如host1和host2,这里的ip,就是属于每个对象本身的变量,因为在init初始化方法中,我们指定了self.ip,这就是将ip这个变量绑定到对象上了。

>>> print(host1.ip)
10.10.11.1
>>> print(host2.ip)
10.10.11.2

5、实例对象属性的查找顺序

    从上面的介绍当中,可以了解到,实例对象有自己的属性,类也有属性,那么当我们需要获取一个属性的时候,应该优先从哪里获取呢?

    在这之前,先认识两个特殊属性:

    __class__:对象的类型,可以知道对象是哪个类的实例化的,比如host1.__class__就是Connect

    __dict__:对象的属性字典,可以知道对象有哪些属性,这个非常有用。

#实例对象的类型
>>> print(host1.__class__)
<class '__main__.Connect'>

#实例对象的属性
>>> print(host1.__dict__)
{'ip': '10.10.11.1', '_username': 'root', '_password': 'root123', '_ssh': None, '_timeout': 10, '_try_times': 1}

#类对象的属性
>>> print(Connect.__dict__)
{'__module__': '__main__', '__init__': <function Connect.__init__ at 0x7fa888706730>, 'ssh_connect': <function Connect.ssh_connect at 0x7fa888706a60>, '__dict__': <attribute '__dict__' of 'Connect' objects>, '__weakref__': <attribute '__weakref__' of 'Connect' objects>, '__doc__': None}

    示例演示:

class Person:
    #定义两个类的属性
    age = 10
    height = 170
    
    def __init__(self, name, age=19):
        #定义两个对象的属性
        self.name = name 
        self.age = age

#分别实例化两个对象        
>>> tom = Person('Tom')
>>> jerry = Person('Jerry', 20)        

#修改类的属性,不影响对象的属性
>>> Person.age, tom.age, jerry.age
(10, 19, 20)
>>> Person.age = 100
>>> Person.age, tom.age, jerry.age
(100, 19, 20)

#修改类的属性,对象的属性也变化
>>> Person.height, tom.height, jerry.height
(170, 170, 170)
>>> Person.height = 200
>>> Person.height, tom.height, jerry.height
(200, 200, 200)

    实例说明:

    ① 当类的属性和对象的属性同时存在时,优先使用对象的属性,并且修改类的属性,不会影响对象的属性。

    ② 当对象没有这个属性时,会去找类的属性,如果有就使用类的属性,这个时候如果修改了类的属性,那么访问的时候,自然也就会随之变化。

6、类和实例对象的总结

    ① 一定要分清楚类的属性和实例对象的属性。

    ② 类的属性有变量和方法,而对象的属性只有变量,所以方法都是属于类的

    ③ 查看一个对象有哪些属性,可以使用特殊变量__dict__,类对象查看类的属性,实例对象查看实例的属性。

    ④ 类的属性是所有实例共享的,实例的属性是属于每个实例独有的

    ⑤ 属性的访问优先使用实例的,如果没有再找类的。

    ⑥ 类中的self,它是一个名称符号,指的是每个具体实例对象,通过操作self,可以给每个实例对象绑定属性

Jimmy's Blog ,版权所有丨如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权,转载请注明转自:https://www.xjimmy.com/python-39-class1.html

Leave a Comment