Pythong面向对象编程 1

来源:互联网 发布:日本深夜节目软件 编辑:程序博客网 时间:2024/06/06 13:58

Python是一种多泛型语言-它并不限定我们以何种方式编程。它支持过程式编程,面向对象,以及函数式编程。对于短小的程序来说(比如,不超过500行),我们当然可以以过程式编程来编写任何代码,这当然没有任何问题。但是,对于大多数函数,尤其是中等规模,甚至是大规模的程序而言,面向对象编程的优势是显著的。本章将涵盖所有使用Python进行面向对象编程的诸多基础概念和技术。对于新手抑或是专注于过程式编程语言的同学,第一节是专为你们准备的。本节将通过列举一些过程式编程中可能碰到的一些问题,这些问题能够被面向对象式编程很好的解决。接下来,将介绍Python实现面向对象的方法,并介绍一些相关术语。随后将是本章主要的两节。第二节将介绍如果创建只包含单个元素的定制数据类型,虽然该单个元素本身可能包含若干属性。在第三节中将介绍包含多个元素的定制数据类型。


面向对象的方法

在本节中,我们将研究在使用纯粹的过程式编程来表示一个圆时可能碰到的一系列问题。要表达一个圆,我们需要其圆心(x, y)及其半径。我们可以使用一个三元组来表示,比如:
circle = (11, 60, 8)
这种方法有几个显著缺陷
  1. 我们并不能很清晰的看出三元组的每个元素的含义是什么。对于上述三元组,我们可以解释为 (x, y, radius) 或者 (radius, x, y)。
  2. 我们只能通过位置索引来访问三元组的元素。比如我们有两个函数分别为:distance_from_origin(x, y) 和 edge_distance_from_origin(x, y, radius),我们将需要使用元组分拆将圆作为参数传递给函数调用。
distance = distance_from_origin (*circle[:2])
distance = edge_distance_from_origin(*circle)

以上两者皆假设表示圆的元组的结构为 (x, y, radius)。为避免上述两个缺陷,我们可以使用命名数组:
import collections
Circle = collection.nametuple("Circle", "x y radius")
circle = Circle(13, 84, 9)
distance = distance_from_origin(circle.x, circle.y)

通过创建命名三元组(元组的每个元素代表圆不同属性)来表达一个圆,我们可以使用属性的名称来访问这些属性,从而使得函数调用更易于理解。
但是,问题有来了。比如,我们无法阻止创建一个不合法的圆,比如:
circle = Circle(33, 56, -5) # 半径不能为负值

通过这种方法我们可以成功创建一个圆,没有任何exception会发生。那么这个不合理的半径值也许只有我们在调用函数edge_distance_from_origin的时候才可能被发现,而且前提是该函数会检查半径值是否为负值。在创基对象时无法对其合法性进行检查也许是过程式编程最不利的一面。

如果我们希望圆是可修改的,由此我们可以通过修改圆心的坐标或者通过修改圆的半径来调整圆的大小,我们可以通过调用命名元组的私有方法 collections.namedtuple._replace()方法来实现:

circle = circle._replace(radius=12)

就像我们在前面创建圆一样,我们无法阻止我们为圆设置一个非法属性。 

如果我们需要对圆进行大量的修改,为便宜行事,我们可能会选择使用列表(list):

circle = [36, 77, 8]

这同样也无法确保非法值的引入, 在这种情况下我们所能做的最多也就是使用常量如, circle[RADIUS] = 5。使用列表会引入其他的问题,比如我们可以光明正大的使用circle.sort()。使用字典也许是另一个可选项,如, circle = dict(x=36, y=77, radius=8),然而我们仍然无法回避非法输入以及非法调用的问题。
0 0