Python 中的面向对象编程 – 第 1 部分

Python中的面向对象编程
什么是 OOP(面向对象编程)?

AI吧Python

面向对象编程是一种编程范式,它在编程阶段创建“对象”,试图从需要解决的问题中对实体进行建模。

“对象”包含字段形式的数据(也称为属性)并定义了操作(称为方法)。“对象”具有类型定义,在编程术语中称为类。“对象”是类的一个实例。

当我们讨论 OOP(也称为 OOP 的三大支柱)时,有 3 个关键的事情要讨论:

  • 封装 ——意味着将数据和与类中的数据交互的方法锁定在一个单元中。这很有用,因为模型的内部结构只能通过它公开的方法来改变,其他实体(对象)不能修改另一个实体(对象)的内部状态。
  • 继承 ——通常当我们构建关于现实世界问题的模型时,我们最终会得到大型对象层次结构。这些模型(类)之间存在关系。模型层次结构中的 “是”关系是使用 OOP 中的继承实现的,这意味着存在于一个模型(或对象)中的特征也将存在于派生的模型中。
    示例: 假设您想要建立自己的网上商店并且想要销售小工具。小工具具有属性,如电池容量、重量、内存量、操作系统等。如果您想在您的网店销售平板电脑,您可以说, 平板电脑是一个小工具,并且在代码中实现这些时,您可以使用继承将 Gadget 类的所有属性和功能传递给 Tablet 类。
  • 多态性 ——被称为对象根据其具有的子类型以不同方式表现的可能性。多态性与继承有关。
    示例: 假设您也想在网上商店销售智能手表。智能手表是一种小工具 . 所有的小工具都可以重新启动,这可以是小工具的操作(或方法)。由于(平板电脑和智能手表)都从小工具继承(它们有一个关系),它们也继承了重启操作,但是智能手表上的重启操作与平板电脑的重启操作不同。因此,如果我们重新启动智能手表和平板电脑,我们使用通用操作(重新启动),但每个模型都以自己的方式执行操作,基本上,从更抽象的层面来看,我们有 2 个小工具,它们有执行重启操作时的多态行为(基于它们的类型)。

什么是 Python?

Python 是一种动态类型的通用高级编程语言。它由 Guido van Rossum设计和开发, 并于 1991 年公开发布。如今,它非常流行,主要用于 Web 开发以及广泛的 Web 框架,如 django 、  flask 、  bottlepy 和 pyramid 。该语言的名称来源于  Guido 非常喜欢的Monty Python 的飞行马戏团。

我应该使用哪个版本,2.x 还是 3.x?

Python 的 2.7.x 版本将正式支持到 2020 年。该语言的核心开发团队确认不会有该语言的 2.8 版本。他们只会为 2.x 分支提供安全更新和错误修复。3.x 分支于 2000 年发布,一开始有问题,但现在非常好。由于大多数 linux 发行版仍然附带 2.x 版,因此很难过渡到新版本。这背后的主要原因是向后兼容;有很多使用分支 2.x 编写的应用程序,人们不想破坏现有的应用程序。除了 2.x 之外,分支 3.x 可以轻松安装,并且可以毫无问题地使用。

有关 Python 2.x 和 3.x 分支的差异、优缺点的更详细说明,请阅读以下 2 篇文章:

Python 中的类

如上所述,类是对象的类型定义。Python 中的类声明是使用 class 关键字完成的。python中有一个编码约定,通常一个 .py 文件只包含一个类定义。可能有例外,但这是一个很好的做法。这是我之前谈到的 Gadget 类的示例:

class Gadget:
    weight = 100
    operating_system = None
    battery_capacity = 2000
    screen_size = 1
 
my_iphone = Gadget()

Gadget类  有 4 个属性(weight、  battery_capacity、  operating_system 和screen_size)。我们可以使用类名和括号——Gadget() 创建类的新实例。如果看一下类的默认值,如果考虑到 iPhone 的技术参数,这些似乎是不正确的。我们需要一个方法或函数来指定给定类实例的值是什么。有助于创建类的新实例的方法称为构造函数。您可以在下面看到Python 中构造函数 ( __init__ ) 的实现。__init__ _  创建新实例后立即调用方法。构造函数的第一个参数称为 self。这是另一个代码约定。第一个参数表示新创建的新创建新实例的对象。如您所见,我们在构造函数中设置了 self 的属性。

class Gadget:
    weight = 100
    operating_system = None
    battery_capacity = 2000
    screen_size = 1
 
    def __init__(self, weight, operating_system, battery_capacity, screen_size):
        self.weight = weight
        self.operating_system = operating_system
        self.battery_capacity = battery_capacity
        self.screen_size = screen_size
 
 
my_iphone = Gadget(weight = 128, operating_system="iOS", battery_capacity=2800, screen_size=4)

如果我们想看看我们的新对象有什么值,我们可以打印这些值:

my_iphone = Gadget(weight = 128, operating_system="iOS", battery_capacity=2800, screen_size=4)
 
print(my_iphone.weight)
print(my_iphone.operating_system)
print(my_iphone.battery_capacity)
print(my_iphone.screen_size)

这种方法有一个问题,我们违反了 封装 规则。我们可以直接访问 my_iphone对象的内部状态,我们可以简单地为 screen_size operating_system 属性 分配 新值 。该模型的当前实现允许这样做。我们应该通过使用属性和隐藏当前类成员不让公共访问来改变这些。

class Gadget:
    """A class used for modelling Gadgets in a web shop."""
    __weight = 100
    __operating_system = None
    __battery_capacity = 2000
    __screen_size = 1
 
    def __init__(self, weight, operating_system, battery_capacity, screen_size):
        self.__weight = weight
        self.__operating_system = operating_system
        self.__battery_capacity = battery_capacity
        self.__screen_size = screen_size
 
    def get_weight(self):
        return self.__weight
 
    def set_weight(self, weight):
        self.__weight = weight
 
    weight = property(get_weight, set_weight)
 
    @property
    def operating_system(self):
        return self.__operating_system
 
    @operating_system.setter
    def operating_system(selg, new_os):
        self.__operating_system = new_os

如果我们使用 __[attribute_name] 语法声明它们,我们可以隐藏属性(将它们设为私有)(有关这些约定的更多详细信息,请阅读 Python 的 PEP 8 样式指南),我们可以创建 setter 和 getter 方法来访问私有属性。使用 getter 和 setter 方法很好,但它提供了类似 Java 的编码体验,其中可以使用 get 和 set 方法设置类变量。对开发人员更友好的方法是使用属性。我创建了 2 个属性(用于 weight 和 operating_system),每个属性都以不同的方式实现。

在实现 weight的属性时,我使用 weight = property(get_weight, set_weight) 方法来创建 weight 属性。这种语法可以很容易地应用于 python 类,其中首先实现了类似 Java 的 get/set 方法方法,并且使用 property(get…, set…) 方法,我们可以使用属性扩展类。

在为操作系统实现属性时,  我使用了另一种方法,即所谓的基于注释/装饰器的方法。在这里,我首先定义了get方法,但是我省略了get关键字(请注意用@property修饰的方法operating_system只有一个参数self);之后我创建了setter,它具有相同的方法名称(operating_system),但有2个参数,self的值和需要设置的新值(称为 new_os)。

>>> from Gadget import Gadget

>>> my_iphone = Gadget(240,'iOS',1980,4)

>>> my_iphone.weight

240

>>> my_iphone.weight = 255

>>> my_iphone.weight

255

>>>

>>>

>>> my_iphone.operating_system

'iOS'

>>> my_iphone.operating_system = 'iOS 8.1'

>>> my_iphone.operating_system

'iOS 8.1'

>>>

使用这些属性相当容易,这里有一些例子。基本上属性的行为方式与公共成员相同,但是通过 getter 和 setter,我们可以选择验证新设置的值(在这种情况下我没有进行任何验证,但可以毫无问题地完成)。

Python 中的 OOP – 第 2 部分即将推出。本文最初发布于http://readings.grelution.com?p=325

发表评论

邮箱地址不会被公开。 必填项已用*标注