Python全栈开发(四)——python面向对象编程

简介: Python全栈开发(四)——python面向对象编程

前言

我们前面讲完了全栈开发的第一部分——基础,今天我们说说第二部分——面向对象编程。我们从什么是类,什么是对象,以及面向对象的三要素等方面来说说。


面向对象

 

首先需要明确,面向对象编程不是python独有的;

面向对象是一种编程思想;

在面向对象的思想中

万物都是对象


面向对象的简单理解:

面向对象是把一组数据结构和处理他们的方法组成对象,把具有相同行为的对象归纳成类,通过封装隐藏类的内部细节,通过继承使类得到泛化,通过多态实现基于对象类型的动态分类。


类是什么

类表示一组(或一类)对象,每个对象都属于特定的类,并被称为该类的实例。

在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。

编写类时,你定义一大类对象都有的通用行为。基于类创建 对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。根据类来创建对象被称为 实例化,这让你能够使用类的实例

在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法;对象由属性和方法组成。属性不过是属于对象的变量,而方法是存储在属性中的函数。


  • python中类的创建

示例如下

class Person():
    def __init__(self):
        pass
    def set_name(self, name):
        self.name = name
    def get_name(self):
        return self.name
    def greet(self):
        print("Hello, world! I'm {}.".format(self.name))

Person是类的名称,包含三个方法定义, class 语句创建独立的命名空间,用于在其中定义函数。参数 self 指向对象本身。

方法 init() 是一个特殊的方法,每当创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。

self 很有用,甚至必不可少。如果没有它,所有的方法都无法访问对象本身——要操作的属性所属的对象;

默认情况下,可从外部访问对象的属性。若让属性不能从对象外部访问,可将属性定义为私有。私有而只能通过存取器方法来访问

Python没有为私有属性提供直接的支持,要让方法或属性成为私有的(不能从外部访问),只需让其名称以两个下划线打头即可


对象是什么

对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的概念。对象有以下特点:

对象具有属性和行为。

对象具有变化的状态。

对象具有唯一性。


对象都是某个类别的实例。

对象就是通过类定义的数据结构实例

person = Person()


python对象中的类成员

类的成员主要包括:

字段

方法

属性


字段:

字段包括:普通字段和静态字段,使用和定义都是不一样,其最本质的区别就是内存中保存的位置不同。

普通字段属于对象

静态字段属于类


class Person():
    type = 'ren' #静态字段
    def __init__(self):
        #普通字段
        self.name = 'mingzi'
        pass
    def set_name(self, name):
        self.name = name
p = Person()
p.type = 'woman'
p.name = 'man'
print(Person.type)
print(p.name)

在以上示例代码中:

type是静态字段,可通过类名之间调用

name是普通字段,需要通过实例对象调用

通常情况下我们都使用普通字段,当一个变量在类的所有对象中共同使用,而且数据共享的时候,我们就可以使用静态字段。


方法

方法包括:普通方法、静态方法和类方法。

普通方法:由对象调用;包含一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;

类方法:由类调用; 包含一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;使用@classmethod装饰器

静态方法:由类调用;没有默认参数;使用@staticmethod装饰器


代码示例:

class Human:
    count = 0
    def __init__(self, name, age):
        self.name = name
        self.age = age
    #普通方法
    def setName(name):
       self.name=name
    @classmethod
    def add_count(cls):
        cls.count += 1       # 可以通过类名修改类属性
    @classmethod
    def get(cls):
        return cls.count
    @staticmethod
    def static_func():      # 静态方法
        print("普通函数")

普通方法中可以直接使用对象的普通字段

类方法中可以直接使用静态字段

静态方法中不能直接使用普通字段和静态字段


属性

python中的属性就是普通方法的变种,就是将一个方法伪装成一个属性;

  • 属性定义的两种方式:

装饰器:在方法上应用装饰器

静态字段:在类中定义值为property对象的静态字段


面向对象三要素

封装:

通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。


继承:

继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。


多态:

多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。


封装

执行以下代码:

class Person():
    def __init__(self):
        pass
    def set_name(self, name):
        self.__name = name
    def get_name(self):
        return self.__name
    def greet(self):
        print("Hello, world! I'm {}.".format(self.name))
p = Person()
p.set_name('test')
print(p.get_name())

继承

继承是一种创建新类的方式,在python中,新建的类可以继承一个父类(单继承)或多个父类(多继承)

代码示例:

class Person():
    def __init__(self):
        pass
    def set_name(self, name):
        self.name = name
    def get_name(self):
        return self.name
    def greet(self):
        print("Hello, world! I'm {}.".format(self.name))
class Boy(Person):
    def run(self):
        print('i can run')
    def greet(self):
        print('i am subclass boy')
b =Boy()
b.name = '张三'
b.greet()

多态

  • 多态性的本质在于不同的类中定义有相同的方法名,这样我们就可以不用考虑而统一用一种方式去使用对象,可以通过在父类引入抽象类的概念来硬性限制子类必须有某些方法名:
  • 多态已封装和为前提继承

在上面代码基础上新增以下代码:

class Girl(Person):
    def say(self):
        print('i can good girl')
    def greet(self):
        print('i am subclass Girl')

Boy,Girl都继承自Person,三个对象都有同样的方法名greet();

Boy和Girl重写了父类的方法,实现不同的输出。



创建类

首先,我们创建一个类,示例如下。


创建一个类:

# -*- coding: UTF-8 -*-
from random import choice
class Divergence:
    def __init__(self,name='robot'):
        self.name = name
        pass
    def getChoice(self,name=None):
        if name is not None:
            self.name = name
        self.__lists = ['剪刀','石头','布']
        result = choice(self.__lists)
        print(self.name,':选择了>',result)

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


在上面的代码中,由于构造方法除 self 参数外,还包含 name参数,且设置了默认参数,因此在实例化类对象时,按需传入相应的 name 值(self 参数是特殊参数,不需要手动传值,Python 会自动传给它值)


类对象的使用

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


访问或修改类对象具有的实例变量,甚至可以添加新的实例变量或者删除已有的实例变量;

调用类对象的方法,包括调用现有的方法,以及给类对象动态添加方法。


下面验收如何使用:

#实例化对象的时候传递name参数
d = Divergence('A')
d.getChoice()
#实例化时不传递参数
d = Divergence()
#调用方法时传递
d.getChoice('A')

我们通过实例来说明如何创建对象。

创建点对象,有多种方式创建一个类的实例,我们称一个点的x、y、z都一样的点为对角点。

# -*- coding: UTF-8 -*-
class Point:
    # TODO(You): 添加代码支持类的创建
if __name__ == '__main__':
    points = []
    # TODO(You): 批量创建1000个对角点,第i个点的坐标是 (i,i,i)
    for point in points:
        print(point)

可以这样补全代码

class Point:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
if __name__ == '__main__':
    points = []
    for i in range(1000):
        points.append(Point(i,i,i))

抽象类

抽象类概念:

抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化,需要借助python模块实现;

抽象类是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。

抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法


python中的abc模块

  • python中需要利用abc模块实现抽象类
  • 抽象类的本质仍是类,指的是一组类的类似性,包括数据属性(如all_type)和函数属性;
  • 抽象类是一个介于类和接口之间的一个概念,同时具有类和接口的部分特性



下面通过具体python题目说明抽象类的概念

使用 abc 库,创建抽象 BasePoint 类,创建 Point 子类,实现 dot 抽象方法,计算内积

# -*- coding: UTF-8 -*-
import abc
# TODO(You): 请实现抽象类 BasePoint
class Point(BasePoint):
    def __init__(self, x, y, z) -> None:
        super().__init__(x, y, z)
    def dot(self, right):
        return self.x*right.x+self.y*right.y+self.z*right.z
if __name__ == '__main__':
    p1 = Point(0, 1, 2)
    p2 = Point(2, 4, 6)
    assert p1.dot(p2) == 16
    p1 = BasePoint(0, 1, 2)
    p2 = BasePoint(2, 4, 6)
    assert p1.dot(p2) is None

补全代码如下

class BasePoint:
    def __init__(self, x, y, z) -> None:
        self.x = x
        self.y = y
        self.z = z
    @abc.abstractmethod
    def dot(self, right):
        pass


访问限制

为什么要做访问限制

做访问限制,是为了程序的健壮性。如果可以从外部对函数里面重要的属性进行任意修改,有可能程序崩溃只是因为一次不经意地参数修改。

  • 通过定义私有属性做访问限制

默认情况下,可从外部访问对象的属性。若让属性不能从对象外部访问,可将属性定义为私有。

私有属性只能通过存取器方法来访问

Python没有为私有属性提供直接的支持,要让方法或属性成为私有的(不能从外部访问),只需让其名称以两个下划线打头即可



class Apple(): 
    def name(self,name):
       self.__name = name
    def getName(self):
        return self.__name
  • 通过定义私有函数做访问限制;

与属性一样,只需要在函数名前面添加两个下划线打头既可实现私有函数;


class Apple(): 
    def __setAge(self,age):
       self.__age = age
    def getName(self):
        return self.__name
    def info(self,age):
      self.__setAge(age);
  • 特殊情况:

在Python中,以双下划线开头,并且以双下划线结尾的变量是特殊变量如__name__,特殊变量是可以直接访问的;

按照约定俗成的规定,以一个下划线开头的实例变量名(例如_category) 外部也是可以直接访问的,但是这个形式的变量表达的意思是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”


下次我们说说MYSQL数据库。  


相关文章
|
3月前
|
存储 监控 算法
淘宝买家秀 API开发实录Python(2025)
本文讲述了作者在电商开发领域,尤其是对接淘宝买家秀 API 接口过程中所经历的挑战与收获。从申请接入、签名验证、频率限制到数据处理和实时监控,作者分享了多个实战经验与代码示例,帮助开发者更高效地获取和处理买家秀数据,提升开发效率。
|
6月前
|
API C++ 开发者
PySide vs PyQt:Python GUI开发史诗级对决,谁才是王者?
PySide 和 PyQt 是 Python GUI 开发领域的两大利器,各有特色。PySide 采用 LGPL 协议,更灵活;PyQt 默认 GPL,商业使用需授权。两者背后团队实力雄厚,PySide 得到 Qt 官方支持,PyQt 由 Riverbank Computing 打造。API 设计上,PySide 简洁直观,贴近原生 Qt;PyQt 增加 Pythonic 接口,操作更高效。性能方面,两者表现优异,适合不同需求的项目开发。选择时可根据项目特点与开源要求决定。
576 20
|
2月前
|
设计模式 人工智能 API
AI智能体开发实战:17种核心架构模式详解与Python代码实现
本文系统解析17种智能体架构设计模式,涵盖多智能体协作、思维树、反思优化与工具调用等核心范式,结合LangChain与LangGraph实现代码工作流,并通过真实案例验证效果,助力构建高效AI系统。
408 7
|
3月前
|
算法 程序员 API
电商程序猿开发实录:淘宝商品python(2)
本文分享了开发者在对接淘宝商品详情API过程中的真实经历,涵盖权限申请、签名验证、限流控制、数据解析及消息订阅等关键环节,提供了实用的Python代码示例,帮助开发者高效调用API,提升系统稳定性与数据处理能力。
|
4月前
|
数据采集 存储 数据库
Python爬虫开发:Cookie池与定期清除的代码实现
Python爬虫开发:Cookie池与定期清除的代码实现
|
5月前
|
人工智能 搜索推荐 数据可视化
用 Python 制作简单小游戏教程:手把手教你开发猜数字游戏
本教程详细讲解了用Python实现经典猜数字游戏的完整流程,涵盖从基础规则到高级功能的全方位开发。内容包括游戏逻辑设计、输入验证与错误处理、猜测次数统计、难度选择、彩色输出等核心功能,并提供完整代码示例。同时,介绍了开发环境搭建及调试方法,帮助初学者快速上手。最后还提出了图形界面、网络对战、成就系统等扩展方向,鼓励读者自主创新,打造个性化游戏版本。适合Python入门者实践与进阶学习。
624 1
|
5月前
|
Linux 数据库 数据安全/隐私保护
Python web Django快速入门手册全栈版,共2590字,短小精悍
本教程涵盖Django从安装到数据库模型创建的全流程。第一章介绍Windows、Linux及macOS下虚拟环境搭建与Django安装验证;第二章讲解项目创建、迁移与运行;第三章演示应用APP创建及项目汉化;第四章说明超级用户创建与后台登录;第五章深入数据库模型设计,包括类与表的对应关系及模型创建步骤。内容精炼实用,适合快速入门Django全栈开发。
225 1
|
6月前
|
数据采集 自然语言处理 Java
Playwright 多语言一体化——Python/Java/.NET 全栈采集实战
本文以反面教材形式,剖析了在使用 Playwright 爬取懂车帝车友圈问答数据时常见的配置错误(如未设置代理、Cookie 和 User-Agent),并提供了 Python、Java 和 .NET 三种语言的修复代码示例。通过错误示例 → 问题剖析 → 修复过程 → 总结教训的完整流程,帮助读者掌握如何正确配置爬虫代理及其它必要参数,避免 IP 封禁和反爬检测,实现高效数据采集与分析。
388 3
Playwright 多语言一体化——Python/Java/.NET 全栈采集实战
|
7月前
|
程序员 测试技术 开发工具
怎么开发Python第三方库?手把手教你参与开源项目!
大家好,我是程序员晚枫。本文将分享如何开发Python第三方库,并以我维护的开源项目 **popdf** 为例,指导参与开源贡献。Popdf是一个PDF操作库,支持PDF转Word、转图片、合并与加密等功能。文章涵盖从fork项目、本地开发、单元测试到提交PR的全流程,适合想了解开源贡献的开发者。欢迎访问[popdf](https://gitcode.com/python4office/popdf),一起交流学习!
257 21
怎么开发Python第三方库?手把手教你参与开源项目!
|
5月前
|
存储 算法 数据可视化
用Python开发猜数字游戏:从零开始的手把手教程
猜数字游戏是编程入门经典项目,涵盖变量、循环、条件判断等核心概念。玩家通过输入猜测电脑生成的随机数,程序给出提示直至猜中。项目从基础实现到功能扩展,逐步提升难度,适合各阶段Python学习者。
344 0

推荐镜像

更多