python——面向对象——知识汇总一

面向对象技术简介

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

  • 方法:类中定义的函数。

  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。

  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。

  • 局部变量:定义在方法中的变量,只作用于当前实例的类。

  • 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。

  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
               例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。

  • 实例化:创建一个类的实例,类的具体对象。

  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

 

 

 

 

 

面向对象中,常用术语包括:

  • 类:可以理解是一个模板,通过它可以创建出无数个具体实例。比如,前面编写的 tortoise 表示的只是乌龟这个物种,通过它可以创建出无数个实例来代表各种不同特征的乌龟(这一过程又称为类的实例化)。

  • 对象:类并不能直接使用,通过类创建出的实例(又称对象)才能使用。这有点像汽车图纸和汽车的关系,图纸本身(类)并不能为人们使用,通过图纸创建出的一辆辆车(对象)才能使用。

  • 属性:类中的所有变量称为属性。例如,tortoise 这个类中,bodyColor、footNum、weight、hasShell 都是这个类拥有的属性。

  • 方法:类中的所有函数通常称为方法。不过,和函数所有不同的是,类方法至少要包含一个 self 参数(后续会做详细介绍)。
              例如,tortoise 类中,crawl()、eat()、sleep()、protect() 都是这个类所拥有的方法,类方法无法单独使用,只能和类的对象一起使用。

 

 

 

 

 

 

 

 

复制代码
class tortoise:
    bodyColor = "绿色"
    footNum = 4
    weight = 10
    hasShell = True
    #会爬
    def crawl(self):
        print("乌龟会爬")
    #会吃东西
    def eat(self):
        print("乌龟吃东西")
    #会睡觉
    def sleep(self):
        print("乌龟在睡觉")
    #会缩到壳里
    def protect(self):
        print("乌龟缩进了壳里")

# 实例化类
x = tortoise()

# 访问类的属性和方法
print(x.bodyColor)
print(x.footNum)
print(x.weight)
print(x.hasShell)
print("===================================")
x.crawl()
x.eat()
x.sleep()
x.protect()
复制代码

 

 

 

 

 

 

 

 

 

============================================================================

 

 

 

 

 

 

 

 

 

定义类

 

 

 

 

 

 

类定义

语法格式如下:

 
class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

 

class 类名:
    多个(≥0)类属性...
    多个(≥0)类方法...

 

注意,无论是类属性还是类方法,对于类来说,它们都不是必需的,可以有也可以没有。另外,Python 类中属性和方法所在的位置是任意的,即它们之间并没有固定的前后次序。

和变量名一样,类名本质上就是一个标识符,因此我们在给类起名字时,必须让其符合 Python 的语法。

因此,在给类起名字时,最好使用能代表该类功能的单词,例如用“Student”作为学生类的类名;甚至如果必要,可以使用多个单词组合而成,例如初学者定义的第一个类的类名可以是“TheFirstDemo”。
 

注意,如果由单词构成类名,建议每个单词的首字母大写,其它字母小写。

 
给类起好名字之后,其后要跟有冒号(:),表示告诉 Python 解释器,下面要开始设计类的内部功能了,也就是编写类属性和类方法。
 

其实,类属性指的就是包含在类中的变量;而类方法指的是包含类中的函数。
 
 
换句话说,类属性和类方法其实分别是包含类中的变量和函数的别称。
 
 
需要注意的一点是,同属一个类的所有类属性和类方法,要保持统一的缩进格式,通常统一缩进 4 个空格。
 
 

类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 =============================================================================

 

 

 

 

 

 

 

 

 

 

Python的   __init__()   类构造方法

 

 

 

 

 在创建类时,我们可以手动添加一个 __init__() 方法,该方法是一个特殊的类实例方法,称为构造方法(或构造函数)。

 

 构造方法用于创建对象时使用,每当创建一个类的实例对象时,Python 解释器都会自动调用它。Python 类中,手动添加构造方法的语法格式如下:

 

 

def __init__(self,...):
    代码块

 

 

 注意,此方法的方法名中,开头和结尾各有 2 个下划线,且中间不能有空格。Python 中很多这种以双下划线开头、双下划线结尾的方法,都具有特殊的意义

 

 

 _init__() 方法可以包含多个参数,但必须包含一个名为 self 的参数,且必须作为第一个参数。

 

 

也就是说,类的构造方法最少也要有一个 self 参数。

 

 

例如,仍以 TheFirstDemo 类为例,添加构造方法的代码如下所示:

 

 

 

复制代码
class TheFirstDemo:
    '''这是一个学习Python定义的第一个类'''

    #构造方法
    def __init__(self):
        print("调用构造方法")

    # 下面定义了一个类属性
    add = 'http://c.biancheng.net'


    # 下面定义了一个say方法
    def say(self, content):
        print(content)
复制代码

 

 

 注意,即便不手动为类添加任何构造方法,Python 也会自动为类添加一个仅包含 self 参数的构造方法。

 

仅包含 self 参数的 __init__() 构造方法,又称为类的默认构造方法。

 

 

 

 

 

 显然,在创建 zhangsan 这个对象时,隐式调用了我们手动创建的 __init__() 构造方法。

 

 

 

 

 

 

 不仅如此,在 __init__() 构造方法中,除了 self 参数外,还可以自定义一些参数,参数之间使用逗号“,”进行分割。

 

 

例如,下面的代码在创建 __init__() 方法时,额外指定了 2 个参数:

 

 

 

 

 注意,由于创建对象时会调用类的构造方法,如果构造函数有多个参数时,需要手动传递参数,

 

 

可以看到,虽然构造方法中有 self、name、add 3 个参数,但实际需要传参的仅有 name 和 add,也就是说,self 不需要手动传递参数。

 

 

 

 

 

 

 

Python类的实例化

 

 

我们已经学会如何定义一个类,但要想使用它,必须创建该类的对象。创建类对象的过程,又称为类的实例化。

 

 

对已定义好的类进行实例化,其语法格式如下:          类名(参数)

 

 

定义类时,如果没有手动添加 __init__() 构造方法,又或者添加的 __init__() 中仅有一个 self 参数,则创建类对象时的参数可以省略不写。

 

 

 

 

 

在上面的程序中,由于构造方法除 self 参数外,还包含 2 个参数,且这 2 个参数没有设置默认参数,

 

因此在实例化类对象时,需要传入相应的 name 值和 add 值(self 参数是特殊参数,不需要手动传值,Python 会自动传给它值)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Python类对象的使用

 

 

 

 

定义的类只有进行实例化,也就是使用该类创建对象之后,才能得到利用。总的来说,实例化后的类对象可以执行以下操作:

  • 访问或修改类对象具有的实例变量,甚至可以添加新的实例变量或者删除已有的实例变量;
  • 调用类对象的方法,包括调用现有的方法,以及给类对象动态添加方法。

类对象访问变量或方法

使用已创建好的类对象访问类中实例变量的语法格式如下:

类对象名.变量名

 

 

 

使用类对象调用类中方法的语法格式如下:

对象名.方法名(参数)

 

 

注意,对象名和变量名以及方法名之间用点 "." 连接。

 

 

复制代码
class CLanguage :

    # 下面定义了2个类变量

    name = "C语言中文网"

    add = "http://c.biancheng.net"

    def __init__(self,name,add):
        #下面定义 2 个实例变量
        self.name = name
        self.add = add
        print(name,"网址为:",add)

    # 下面定义了一个say实例方法
    def say(self, content):
        print(content)


# 将该CLanguage对象赋给clanguage变量
clanguage = CLanguage("C语言中文网","http://c.biancheng.net")


#输出name和add实例变量的值
print(clanguage.name,clanguage.add)


#修改实例变量的值
clanguage.name="Python教程"
clanguage.add="http://c.biancheng.net/python"

#调用clanguage的say()方法
clanguage.say("人生苦短,我用Python")

#再次输出name和add的值
print(clanguage.name,clanguage.add)
复制代码

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Python self用法详解

 

 

在定义类的过程中,无论是显式创建类的构造方法,还是向类中添加实例方法,都要求将 self 参数作为方法的第一个参数。

 

事实上,Python 只是规定,无论是构造方法还是实例方法,最少要包含一个参数,并没有规定该参数的具体名称。

 

之所以将其命名为 self,只是程序员之间约定俗成的一种习惯,遵守这个约定,可以使我们编写的代码具有更好的可读性(大家一看到 self,就知道它的作用)。


那么,self 参数的具体作用是什么呢?

 

打个比方,如果把类比作造房子的图纸,那么类实例化后的对象是真正可以住的房子。

 

根据一张图纸(类),我们可以设计出成千上万的房子(类对象),每个房子长相都是类似的(都有相同的类变量和类方法),但它们都有各自的主人,那么如何对它们进行区分呢?



当然是通过 self 参数,它就相当于每个房子的门钥匙,可以保证每个房子的主人仅能进入自己的房子(每个类对象只能调用自己的类变量和类方法)。

 

 

也就是说,同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,

换句话说,Python 会自动绑定类方法的第一个参数指向调用该方法的对象。如此,Python解释器就能知道到底要操作哪个对象的方法了。

 

 

 

 

 

 

 

总之,无论是类中的构造函数还是普通的类方法,实际调用它们的谁,则第一个参数 self 就代表谁。

 

 

 

 

 

 

 

 

 

 

 

 

 

===================================================================================

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Python类变量和实例变量(类属性和实例属性)

 

 

无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们。

 

我们可以将类看做一个独立的空间,则类属性其实就是在类体中定义的变量,类方法是在类体中定义的函数。



在类体中,根据变量定义的位置不同,以及定义的方式不同,类属性又可细分为以下 3 种类型:

1、类体中、所有函数之外:此范围定义的变量,称为类属性或类变量;

 

2、类体中,所有函数内部:以“self.变量名”的方式定义的变量,称为实例属性或实例变量;

 

3、类体中,所有函数内部:以“变量名=变量值”的方式定义的变量,称为局部变量。

 

 

 

 

复制代码
class CLanguage :
    # 下面定义了2个类变量
    name = "C语言中文网"
    add = "http://c.biancheng.net"
    # 下面定义了一个say实例方法
    def say(self, content):
        print(content)




#使用类名直接调用
print(CLanguage.name)
print(CLanguage.add)

print("================================================")

#修改类变量的值
CLanguage.name = "Python教程"
CLanguage.add = "http://c.biancheng.net/python"


print(CLanguage.name)
print(CLanguage.add)

print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++")

print("修改前,各类对象中类变量的值:")
clang1 = CLanguage()
print(clang1.name)
print(clang1.add)
clang2 = CLanguage()
print(clang2.name)
print(clang2.add)


print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&")

print("修改后,各类对象中类变量的值:")

CLanguage.name = "Python教程"
CLanguage.add = "http://c.biancheng.net/python"

print(clang1.name)
print(clang1.add)

print(clang2.name)
print(clang2.add)
复制代码

 

 

 

 

 

类变量(类属性)

 

类变量指的是在类中,但在各个类方法外定义的变量。举个例子:

 

class CLanguage :
    # 下面定义了2个类变量
    name = "C语言中文网"
    add = "http://c.biancheng.net"
    # 下面定义了一个say实例方法
    def say(self, content):
        print(content)

 

 

上面程序中,name 和 add 就属于类变量。

类变量的特点是,所有类的实例化对象都同时共享类变量,也就是说,类变量在所有实例化对象中是作为公用资源存在的。

 

类方法的调用方式有 2 种,既可以使用类名直接调用,也可以使用类的实例化对象调用。

 

通过类名不仅可以调用类变量,也可以修改它的值。

 

当然,也可以使用类对象来调用所属类中的类变量(此方式不推荐使用)。

 

注意,因为类变量为所有实例化对象共有,通过类名修改类变量的值,会影响所有的实例化对象。

 

注意,通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量

 

 

 

 

 

 

 

实例变量(实例属性)

 

 

实例变量指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象。

 

另外,实例变量只能通过对象名访问,无法通过类名访问。

 

 

 

 

 

通过类对象可以访问类变量,但无法修改类变量的值。

 

这是因为,通过类对象修改类变量的值,不是在给“类变量赋值”,而是定义新的实例变量。

 

类中,实例变量和类变量可以同名,但这种情况下使用类对象将无法调用类变量,它会首选实例变量,这也是不推荐“类变量使用对象名调用”的原因。

 

 

 

 

 

 

 

注意:和类变量不同,通过某个对象修改实例变量的值,不会影响类的其它实例化对象,更不会影响同名的类变量。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

============================================================================================

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Python实例方法、静态方法和类方法

 

 

和类属性一样,类方法也可以进行更细致的划分,具体可分为类方法、实例方法和静态方法。

和类属性的分类不同,区分这 3 种类方法是非常简单的,即采用

 

@classmethod 修饰的方法为类方法;

 

@staticmethod 修饰的方法为静态方法;

 

不用任何修改的方法为实例方法。

 

 

 

 

 

 

Python类实例方法

 

 

通常情况下,在类中定义的方法默认都是实例方法。类的构造方法理论上也属于实例方法,只不过它比较特殊。

 

实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。

 

实例方法通常会用类对象直接调用。

 

 

 

 

 

 

 

 

 

 

 

 

 

Python类方法

 

 

Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。

 

也就是说,我们在调用类方法时,无需显式为 cls 参数传参。

 

和 self 一样,cls 参数的命名也不是规定的(可以随意命名),只是 Python 程序员约定俗称的习惯而已。

 

和实例方法最大的不同在于,类方法需要使用@classmethod修饰符进行修饰。

 

 

 

 

注意,如果没有 @classmethod,则 Python 解释器会将 fly() 方法认定为实例方法,而不是类方法。

 

类方法推荐使用类名直接调用,当然也可以使用实例对象来调用(不推荐)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Python类静态方法

 

静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。

静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法。

静态方法需要使用@staticmethod修饰

 

静态方法的调用,既可以使用类名,也可以使用类对象。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

===============================================================================

 

 

 

 

 

 

 

 

 

Python类调用实例方法

 

实例方法的调用方式其实有 2 种,既可以采用

 

1、类对象调用;

 

 

2、类名调用。

 

 

 

 

如果想通过类名直接调用实例方法,就必须手动为 self 参数传值。

 

PS:通过手动将 clang 这个类对象传给了 self 参数,使得程序得以正确执行。实际上,这里调用实例方法的形式完全是等价于 clang.info()

 

总的来说,Python 中允许使用类名直接调用实例方法,但必须手动为该方法的第一个 self 参数传递参数,这种调用方法的方式被称为“非绑定方法”。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

========================================================================================

 

 

 

 

 

 

 

 

 

Python描述符详解

 

 

 PS:就是类的封装,类似于java中的getter、setter方法,这样就明白了。

 

本质上看,描述符就是一个类,只不过它定义了另一个类中属性的访问方式。换句话说,一个类可以将属性管理全权委托给描述符类。

 

 

描述符是 Python 中复杂属性访问的基础,它在内部被用于实现 property、方法、类方法、静态方法和 super 类型。

 

 

描述符类基于以下 3 个特殊方法,换句话说,这 3 个方法组成了描述符协议:

  • __set__(self, obj, type=None):在设置属性时将调用这一方法(本节后续用 setter 表示);
  • __get__(self, obj, value):在读取属性时将调用这一方法(本节后续用 getter 表示);
  • __delete__(self, obj):对属性调用 del 时将调用这一方法。

 

 

其中,实现了 setter 和 getter 方法的描述符类被称为数据描述符;反之,如果只实现了 getter 方法,则称为非数据描述符。


实际上,在每次查找属性时,描述符协议中的方法都由类对象的特殊方法 __getattribute__() 调用(注意不要和 __getattr__() 弄混)。

 

也就是说,每次使用类对象.属性(或者 getattr(类对象,属性值))的调用方式时,都会隐式地调用 __getattribute__(),它会按照下列顺序查找该属性:

    1. 验证该属性是否为类实例对象的数据描述符;
    2. 如果不是,就查看该属性是否能在类实例对象的 __dict__ 中找到;
    3. 最后,查看该属性是否为类实例对象的非数据描述符。

 

 

下面这个调用了 其getter方法:

 

 

 

 

下面这个调用了setter方法赋值:

 

posted @   小白龙白龙马  阅读(28)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2023-02-25 java——spring boot集成RabbitMQ——如何实现手动ack
2023-02-25 java——spring boot集成RabbitMQ——spring boot实现路由模式——生产者
2023-02-25 java——spring boot集成RabbitMQ——spring boot实现路由模式——消费者
2023-02-25 java——spring boot集成RabbitMQ——spring boot实现发布订阅模式——生产者
2023-02-25 java——spring boot集成RabbitMQ——spring boot实现发布订阅模式——消费者
2023-02-25 java——spring boot集成RabbitMQ——windows本地安装和运行
2023-02-25 java——spring boot集成RabbitMQ——topics模式——实现消费者
点击右上角即可分享
微信分享提示