CodeGym /Java 课程 /Python SELF ZH /一切皆对象

一切皆对象

Python SELF ZH
第 15 级 , 课程 1
可用

1.1 对象与类

今天我们会聊聊Python里的典型程序是如何构成的。而最重要的消息是: 每个Python程序都是由类和对象构成的。 Python是面向对象的语言,所有东西都是对象:数字、字符串、函数,甚至类本身也是对象。

那么,类到底是什么呢?

我先来举个例子。假设你想造一艘小船。首先你需要一个设计图,然后把设计图交给工厂,他们会根据这个设计图造出小船,或者造十艘,甚至无数艘。重点是,每个船都是依据同一个设计图造出来的。

编写Python程序的过程也是类似的。

设计图

程序员就像一个设计师。设计师画设计图,而Python程序员则写类。根据设计图做零件,而根据类就可以创建对象。

我们先写类(画设计图),然后在程序运行时,Python会根据这个类创建出对象。就像船是根据设计图造出来的一样。

一个设计图可以造很多船。船可能不太一样,比如名字不一样,装载的货物不一样。但它们都遵循同一个设计,具备相似的结构,可以完成类似的任务。

再举个例子...

蚁巢

蚁巢是一个很好的展示对象协作的例子。在最简单的一个蚁巢里,可能会有三类蚂蚁:蚁后、兵蚁和工蚁。

每类蚂蚁的数量都不同。蚁后只有一个,兵蚁有几十只,而工蚁可能有上百只。这三种不同的类共同构成了蚁巢,它们之间以固定的规则互动协作。

这就是一个完美的例子。在典型的程序中,一切也是类似的。有一个主对象,用来创建其他类的所有对象。对象之间会相互作用,也会和程序的“外部世界”产生交互。每个对象都根据某种规则被编写好了行为。

这两个例子其实是一体两面的。一个是讲类与其对象之间的关系,这里的类可以看作是设计图;另一个是讲对象在程序运行时的协作关系。

首先你需要为程序中的所有对象编写类,然后再描述它们之间的协作方式。听起来似乎有点复杂,但其实比你想象的简单。

在Python中,程序运行时的所有实体都是对象,编写程序就是在描述对象之间的各种交互方式。对象通过方法相互调用传递数据。

文档

那怎么知道要传递哪些数据给方法呢?这个其实已经被设计好了。

通常每个类都会有一个说明,描述它的用途。同样,类中每个公开方法也有描述:这个方法是干嘛的,需要传入什么数据。

使用一个类时,你只需要了解它的大致功能,还有每个方法的具体用途。不需要知道它是如何实现的,就像魔法一样。

来看看代码吧——文件复制的例子:


src = open('source.txt', 'r')
dst = open('destination.txt', 'w')
            
for line in src:
    dst.write(line)
            
src.close()
dst.close()
        

如果逐行阅读这个代码,基本可以猜测出它的作用。不过这需要一些经验和实践。一段时间后,这段代码就会变得熟悉简单。

1.2 程序设计

设计程序是一种艺术。它既简单又复杂。简单是因为没有什么硬性规则:不被禁止的都可以做。复杂是因为有太多的方式可以实现同一件事,找到最优解并不容易。

设计程序就像写一本书。一方面,你只是写下字母、单词和句子。另一方面,情节、角色、矛盾、冲突、叙述风格和悬念都需要考虑。

最重要的是要知道你的代码是写给谁看的。记住,代码是写给其他程序员的。

开发任何产品都是在不断修改:这里加一点,那里删一点,反复迭代。慢慢地,就会诞生巨大的项目。

对代码的最基本要求是: 代码必须对其他程序员是易于理解的 错误但清晰的代码是可以被修正的正确但晦涩难懂的代码无从改进。这样的代码只能被抛弃。

那如何写出清晰优质的代码呢?

你需要做三件事:

  • 在方法内写出清晰优质的代码——这是最基本的。
  • 确定程序中应该有哪些实体。
  • 正确地将程序划分为逻辑部分。

这些概念的实际含义是什么呢?

在方法内写出优质代码

如果你的英语水平过得去,你可能注意到,有些代码读起来像英文句子:

  • class Cat(Pet) – 猫类继承自宠物类。
  • while stream: – 当数据流不为空时...
  • a if a < b else b – 如果 a 小于 b,返回 a,否则返回 b

这都是特意设计的。Python是少数几个可以较轻松地编写自文档化代码(无需注释也能理解的代码)的语言之一。好的Python代码,很多方法读起来就像英文句子。

写代码时,要尽量让代码简单、简洁。想想代码是否易于阅读,你就会逐渐走上正轨。

在Python社区,写可读性高的代码是常规做法。最好让每个方法的代码不超过屏幕一页(通常20-30行)。这已经是社区的共识了。 如果代码可以优化,那它就该被优化

学写好代码最好的方式就是多实践。多写代码,多读别人的代码,请有经验的同事帮忙审核你的代码。记住,只要你说出“就这样吧”,你的进步就停止了。

确定程序中应该有哪些实体

代码需要让其他程序员看得懂。如果10个程序员中,9个在设计时都会引入类A、B和C,那么你也应该在你的程序中做到这一点。要写出所有人能看懂的代码。

优秀、高效但非常独特的代码,只会是糟糕的代码。

学习别人的项目是最好的方法:它是最快、最轻松的方式,能够传承几十年来IT行业积累的智慧。

而且,你手边就有一个很棒的、流行的、文档完善的项目——Python SDK。从这里开始入门吧。

研究类和类的结构。思考为什么有些方法是静态的,而有些不是。为什么方法的参数是这样,而不是那样。为什么这些方法存在,为什么类名称是这样,为什么它们在这些包中。

当你能理解这些问题的答案时,你就能写出大家都能看懂的代码了。

但也要注意: 别尝试研究Python SDK方法的代码。很多方法为了极致优化速度,舍弃了一部分可读性。

正确地将程序划分为逻辑部分

通常,程序会被划分为不同的部分或模块。每一部分负责程序的某个方面。

比如,电脑有主机、显示器、键盘,这些是独立的、互不依赖的部分。而且它们的交互是标准化的:USB、HDMI等。所以如果键盘进水了,你可以直接洗干净晾干继续用。

但如果是笔记本电脑,那就是一种更紧密耦合的设计。虽然逻辑部分依然存在,但结合得更为紧密。比如清洁Macbook Pro的键盘可能需要拆掉半个笔记本。而如果往笔记本上倒了咖啡,可能直接得换台新机了。

1.3 创建自己的类

刚开始编程时,重要的是从小的事情入手——学会创建自己的类。

你可能以前已经创建过类了,但现在需要学会理解一个程序应该有哪些类,它们该怎么命名,应该有哪些方法,以及它们如何交互。

实体列表

如果你不知道从哪开始,那就从最基础的开始。

在程序设计的初期,可以先列一张清单,列出程序中需要的实体(对象)。然后按照“每个实体——一个类”的原则去实现这些对象。

例子

假如你想写一个国际象棋游戏。你会需要以下实体:棋盘和6种类型的棋子。棋子走法不同,价值不同——很合理将每种棋子设计为一个类。而初期,类越多越好。

很少会见到初学程序员写了10个类而不是2个。但写2个类甚至1个类代替10个,这可是初学者的通病。所以,程序员们,请多写类吧!你的代码会变得更清晰易懂,除了可能你自己 😛

国际象棋

比如我们决定为国际象棋写几个类:这些类会是什么样的?

棋盘是不是一个8x8的二维数组?最好把它设计成一个独立的类,并在内部保存对数组的引用。这样就可以为“棋盘”类添加很多有用的方法,比如检查某个格子是空的还是被占用的。

简而言之,最初可以遵循这样的原则:程序有各种实体,而实体有特定类型。这个“类型”就是类。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION