Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c4e266a

Browse files
committed
更新类和OOP
1 parent 10b9e7a commit c4e266a

8 files changed

+146
-125
lines changed

‎Learning Python/6、类和 OOP/1. OOP:宏伟蓝图.ipynb‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"- **通过继承进行定制。**\n",
1010
"- **运算符重载。**\n",
1111
"\n",
12-
"# 概览 OOP \n",
13-
"## 属性继承搜索 \n",
12+
"# 1. 概览 OOP \n",
13+
"## 1.1 属性继承搜索 \n",
1414
"Python 中大多数 OOP 的故事,都可简化成以下表达式:\n",
1515
"```\n",
1616
"object.attribute\n",
@@ -20,20 +20,27 @@
2020
"\n",
2121
"我们称这种搜索程序为继承,树中位置较低的对象继承了树中位置较高的对象拥有的属性。当从下至上进行搜索时,连接至树中的对象就是树中所有上层对象所定义的所有属性的集合体,直到树的最顶端。 \n",
2222
"\n",
23-
"## 类和实例 \n",
23+
"## 1.2 类和实例 \n",
2424
"类和实例是两种不同的对象类型,主要差异在于,类是一种产生实例的工厂,内存中特定模块只有一个实例,对类而言,只要有需要,制作多少实例都可以。 \n",
2525
"\n",
26-
"## 类方法调用 \n",
26+
"## 1.3 类方法调用 \n",
2727
"如果 I2.w 引用是一个函数调用,其实际的含义是"调用 C3.w 函数以处理 I2"。Python 会自动将 I2.w() 调用映射为 C3.w(I2) 调用,传入该实例作为继承的函数的第一个参数。 \n",
2828
"\n",
29-
"## 编写类树 \n",
29+
"## 1.4 编写类树 \n",
3030
"- 每个 class 语句会生成一个新的类对象。\n",
3131
"- 每次类调用时,就会生成一个新的实例对象。\n",
3232
"- 实例自动连接至创建了这些实例的类。\n",
3333
"- 类连接至其超类的方式是,将超类列在类头部的括号内。其从左至右的顺序会决定树中的次序。\n",
3434
"\n",
3535
"属性通常是在 class 语句中通过赋值语句添加在类中,而不是嵌入在函数的 def 语句内;属性通常是在类内,对传给函数的特殊参数(也就是 self),做赋值运算而添加在实例中的。 "
3636
]
37+
},
38+
{
39+
"cell_type": "code",
40+
"execution_count": null,
41+
"metadata": {},
42+
"outputs": [],
43+
"source": []
3744
}
3845
],
3946
"metadata": {
@@ -52,7 +59,7 @@
5259
"name": "python",
5360
"nbconvert_exporter": "python",
5461
"pygments_lexer": "ipython3",
55-
"version": "3.6.5"
62+
"version": "3.6.8"
5663
}
5764
},
5865
"nbformat": 4,

‎Learning Python/6、类和 OOP/2. 类代码编写基础.ipynb‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44
"cell_type": "markdown",
55
"metadata": {},
66
"source": [
7-
"# 类产生多个实例对象 \n",
8-
"## 类对象提供默认行为 \n",
7+
"# 1. 类产生多个实例对象 \n",
8+
"## 1.1 类对象提供默认行为 \n",
99
"Python 类主要特性的要点:\n",
1010
"- **class 语句创建类对象并将其赋值给变量名。**\n",
1111
"- **class 语句内的赋值语句会创建类的属性。**\n",
1212
"- **类属性提供对象的状态和行为。**\n",
1313
"\n",
14-
"## 实例对象是具体的元素 \n",
14+
"## 1.2 实例对象是具体的元素 \n",
1515
"类的实例内含的重点概要:\n",
1616
"- **像函数那样调用类对象会创建新的实例对象。**\n",
1717
"- **每个实例对象继承类的属性并获得了自己的命名空间。**\n",
1818
"- **在方法内对 self 属性做赋值运算会产生每个实例自己的属性。**在类方法函数内,第一个参数(self)会引用正处理的实例对象。\n",
1919
"\n",
20-
"## 第一个例子 "
20+
"## 1.3 第一个例子 "
2121
]
2222
},
2323
{
@@ -138,7 +138,7 @@
138138
"cell_type": "markdown",
139139
"metadata": {},
140140
"source": [
141-
"# 类通过继承进行定制 \n",
141+
"# 2. 类通过继承进行定制 \n",
142142
"类可以引入新组件(子类)来进行修改,而不对现有组件进行原地的修改。由类产生的实例对象会继承该类的属性。 \n",
143143
"\n",
144144
"属性继承机制的核心观点:\n",
@@ -148,7 +148,7 @@
148148
"- **每个 object.attribute 都会开启新的独立搜索。**\n",
149149
"- **逻辑的修改是通过创建子类,而不是修改超类。**在树中层次较低的子类中重新定义超类的变量名,子类就可取代并制定所继承的行为。\n",
150150
"\n",
151-
"## 第二个例子 \n",
151+
"## 2.1 第二个例子 \n",
152152
"定义一个新的类 SecondClass,继承 FirstClass 所有变量名,并提供其自己的一个变量名:"
153153
]
154154
},
@@ -210,15 +210,15 @@
210210
"cell_type": "markdown",
211211
"metadata": {},
212212
"source": [
213-
"## 类是模块内的属性 \n",
213+
"## 2.2 类是模块内的属性 \n",
214214
"类名称总是存在于模块中,class 语句会在导入时执行已定义的变量名,而这些变量名会变成独立的模块属性。"
215215
]
216216
},
217217
{
218218
"cell_type": "markdown",
219219
"metadata": {},
220220
"source": [
221-
"# 类可以截获 Python 运算符 \n",
221+
"# 3. 类可以截获 Python 运算符 \n",
222222
"运算符重载就是让用类写成的对象,可截获并响应用在内置类型上的运算:加法、切片、打印和点号运算等。 \n",
223223
"\n",
224224
"重载运算符主要概念的概要:\n",
@@ -230,7 +230,7 @@
230230
"\n",
231231
"运算符重载是可选的功能,除非类需要模仿内置类型接口,不然应该使用更简单的命名方法。 \n",
232232
"\n",
233-
"## 第三个例子 \n",
233+
"## 3.1 第三个例子 \n",
234234
"定义 SecondClass 的子类,实现三个特殊名称的属性,让 Python 自动进行调用:\n",
235235
"- 当新的实例构造时,会调用 `__init__`(self 是新的 ThirdClass 对象)。\n",
236236
"- 当 ThirdClass 实例出现在 + 表达式中时,则会调用 `__add__`。\n",
@@ -346,7 +346,7 @@
346346
"cell_type": "markdown",
347347
"metadata": {},
348348
"source": [
349-
"# 世界上最简单的 Python 类 "
349+
"# 4. 世界上最简单的 Python 类 "
350350
]
351351
},
352352
{
@@ -572,7 +572,7 @@
572572
"cell_type": "markdown",
573573
"metadata": {},
574574
"source": [
575-
"## 类与字典的关系 \n",
575+
"## 4.1 类与字典的关系 \n",
576576
"利用类来记录属性,可以用不同的实例记录不同的数据,模拟字典的方法:"
577577
]
578578
},
@@ -605,7 +605,7 @@
605605
"name": "python",
606606
"nbconvert_exporter": "python",
607607
"pygments_lexer": "ipython3",
608-
"version": "3.6.5"
608+
"version": "3.6.8"
609609
}
610610
},
611611
"nbformat": 4,

‎Learning Python/6、类和 OOP/3. 一个更实际的例子.ipynb‎

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"- Person——创建并处理关于人员的信息的一个类\n",
99
"- Manager——一个定制的 Person,修改了继承的行为。\n",
1010
"\n",
11-
"# 步骤1:创建实例 \n",
11+
"# 1. 步骤1:创建实例 \n",
1212
"在 Python 中,模块名使用小写字母开头,类名使用一个大写字母开头:"
1313
]
1414
},
@@ -26,7 +26,7 @@
2626
"cell_type": "markdown",
2727
"metadata": {},
2828
"source": [
29-
"## 编写构造函数 \n",
29+
"## 1.1 编写构造函数 \n",
3030
"赋给实例属性第一个值的通常方法是,在 `__init__` 构造函数方法中将它们赋给 self,构造函数方法包含了每次创建一个实例的时候 Python 会自动运行的代码:"
3131
]
3232
},
@@ -50,7 +50,7 @@
5050
"source": [
5151
"job 参数在 `__init__` 函数的作用域里是一个本地变量,但是 self.job 是实例的一个属性,它暗示了方法调用的内容。 \n",
5252
"\n",
53-
"## 在进行中测试 \n",
53+
"## 1.2 在进行中测试 \n",
5454
"常见的做法是,Python 程序员使用交互式提示来进行简单的一次性测试,但是通过在包含测试对象的文件的底部编写代码来进行更多的大量测试:"
5555
]
5656
},
@@ -86,7 +86,7 @@
8686
"cell_type": "markdown",
8787
"metadata": {},
8888
"source": [
89-
"## 以两种方式使用代码 \n",
89+
"## 1.3 以两种方式使用代码 \n",
9090
"文件底部的测试代码是有用的,但是当文件作为脚本运行的时候,或者当它作为一个模块导入的时候,顶层的 print 都会运行,这不是一种很好的软件关系。"
9191
]
9292
},
@@ -131,7 +131,7 @@
131131
"cell_type": "markdown",
132132
"metadata": {},
133133
"source": [
134-
"# 步骤2:添加行为方法 \n",
134+
"# 2. 步骤2:添加行为方法 \n",
135135
"尽管类添加了结构的一个额外的层级,它们最终还是通过嵌入和处理列表及字符串这样的基本核心数据类型来完成其大部分工作。"
136136
]
137137
},
@@ -181,7 +181,7 @@
181181
"cell_type": "markdown",
182182
"metadata": {},
183183
"source": [
184-
"## 编写方法 \n",
184+
"## 2.1 编写方法 \n",
185185
"这里借用一种叫做**封装**的软件设计概念,封装的思想就是把操作逻辑包装到界面之后,这样,每种操作在我们程序里只编码一次。通过这种方式,如果将来需要修改,只需要修改一个版本。 \n",
186186
"\n",
187187
"把操作放入方法中,使得这些操作可以应用于类的任何实例,而不是仅能用于把它们硬编码来处理的那些对象。"
@@ -236,10 +236,10 @@
236236
"cell_type": "markdown",
237237
"metadata": {},
238238
"source": [
239-
"# 步骤3:运算符重载 \n",
239+
"# 3. 步骤3:运算符重载 \n",
240240
"当前,测试还是不能像所需要的那样方便——要跟踪对象,必须手动地接受和打印单个的属性。如果一次显示一个实例真的能给我们一些有用的信息,那还是不错的。但是,实例对象的默认显示格式并不是很好,它显示对象的类名及其在内存中的地址。 \n",
241241
"\n",
242-
"## 提供打印显示 \n",
242+
"## 3.1 提供打印显示 \n",
243243
"通过**运算符重载**可以很容易做得更好,使用 `__repr__` 方法,`__str__` 的双胞胎方法。 \n",
244244
"\n",
245245
"从技术上讲,`__str__` 是 print 和 str 的首选,`__repr__` 被用作这些角色和所有其他上下文中的后备。虽然这两种方法可以用于在不同的上下文中实现不同的显示,但是仅通过编写 `__repr__` 就足以在所有情况下——打印、嵌套显示和交互回显中提供显示。这仍然允许客户端提供 `__str__` 的替代显示,但仅限于有限的上下文。"
@@ -296,8 +296,8 @@
296296
"cell_type": "markdown",
297297
"metadata": {},
298298
"source": [
299-
"# 步骤4:通过子类定制行为 \n",
300-
"## 扩展方法:不好的方式 \n",
299+
"# 4. 步骤4:通过子类定制行为 \n",
300+
"## 4.1 扩展方法:不好的方式 \n",
301301
"复制和粘贴 Person 中的 giveRaise 代码。"
302302
]
303303
},
@@ -316,7 +316,7 @@
316316
"cell_type": "markdown",
317317
"metadata": {},
318318
"source": [
319-
"## 扩展方法:好的方式 \n",
319+
"## 4.2 扩展方法:好的方式 \n",
320320
"使用扩展的参数来直接调用其最初的版本:"
321321
]
322322
},
@@ -392,7 +392,7 @@
392392
"cell_type": "markdown",
393393
"metadata": {},
394394
"source": [
395-
"# 步骤5:定制构造函数 \n",
395+
"# 5. 步骤5:定制构造函数 \n",
396396
"重新定义 Manager 中的 `__init__` 方法,从而提供 mgr 字符串,通过类名的调用来运行 Person 中最初的 `__init__`,以便它仍然会初始化对象的状态信息属性。"
397397
]
398398
},
@@ -452,12 +452,12 @@
452452
"cell_type": "markdown",
453453
"metadata": {},
454454
"source": [
455-
"# 步骤6:使用内省工具 \n",
455+
"# 6. 步骤6:使用内省工具 \n",
456456
"现在仍有两个问题:\n",
457457
"- 当打印 tom 时,Manager 会把它标记为 Person。\n",
458458
"- 当前的显式格式只是显式了包含在 `__repr__` 中的属性,而没有考虑未来的目标。如果更改了在 `__init__` 中分配给对象的属性集合,那么还必须也要更新 `__repr__` 以显示新的名字。\n",
459459
"\n",
460-
"## 特殊类属性 \n",
460+
"## 6.1 特殊类属性 \n",
461461
"可以使用 Python 的**内省工具**来解决这两个问题,它们是特殊的属性和函数,允许我们访问对象实现的一些内部机制。有两个 hook 可以帮助解决问题:\n",
462462
"- 内置的 `instance.__class__` 属性提供了一个从实例到创建它的类的链接。类反过来有一个 `__name__`,还有一个 `__bases__` 序列,提供了超类的访问。\n",
463463
"- 内置的 `object.__dict__` 属性提供了一个字典,以便每个属性都附加到一个命名控件对象。"
@@ -546,7 +546,7 @@
546546
"cell_type": "markdown",
547547
"metadata": {},
548548
"source": [
549-
"## 一种通用显示工具 "
549+
"## 6.2 一种通用显示工具 "
550550
]
551551
},
552552
{
@@ -609,7 +609,7 @@
609609
"cell_type": "markdown",
610610
"metadata": {},
611611
"source": [
612-
"## 类的最终形式 "
612+
"## 6.3 类的最终形式 "
613613
]
614614
},
615615
{
@@ -673,18 +673,18 @@
673673
"cell_type": "markdown",
674674
"metadata": {},
675675
"source": [
676-
"# 步骤7:把对象存储到数据库中 \n",
676+
"# 7. 步骤7:把对象存储到数据库中 \n",
677677
"尽管类按照计划工作,但它们创建的对象还不是真正的数据库记录,如果关闭 Python,实例也将消失。Python 的一项**对象持久化**功能能让对象在创建它们的程序退出之后依然存在。 \n",
678678
"\n",
679-
"## Pickle 和 Shelve \n",
679+
"## 7.1 Pickle 和 Shelve \n",
680680
"对象持久化通过三个标准的库模块来实现:\n",
681681
"- **pickle。**任意 Python 对象和字节字符串之间的序列化\n",
682682
"- **dbm。**实现一个可通过键访问的文件系统,以存储字符串\n",
683683
"- **shelve。**使用另两个模块按照键把 Python 对象存储到一个文件中\n",
684684
"\n",
685685
"shelve 使用 pickle 把一个对象转换为其 pickle 化的字符串,并将其存储在一个 dbm 文件中的键之下;随后载入的时候,shelve 通过键获取 pickle 化的字符串,并用 pickle 在内存中重新创建最初的对象。 \n",
686686
"\n",
687-
"## 在 shelve 数据库中存储对象 \n",
687+
"## 7.2 在 shelve 数据库中存储对象 \n",
688688
"编写 makedb.py 文件:"
689689
]
690690
},
@@ -712,7 +712,7 @@
712712
"cell_type": "markdown",
713713
"metadata": {},
714714
"source": [
715-
"## 交互地探索 shelve \n",
715+
"## 7.3 交互地探索 shelve \n",
716716
"此时,当前目录下会有多个文件,名字都以"persondb"开头。"
717717
]
718718
},
@@ -886,7 +886,7 @@
886886
"cell_type": "markdown",
887887
"metadata": {},
888888
"source": [
889-
"## 更新 shelve 中的对象 \n",
889+
"## 7.4 更新 shelve 中的对象 \n",
890890
"在每次运行的时候更新一个实例。"
891891
]
892892
},
@@ -1010,7 +1010,7 @@
10101010
"name": "python",
10111011
"nbconvert_exporter": "python",
10121012
"pygments_lexer": "ipython3",
1013-
"version": "3.6.5"
1013+
"version": "3.6.8"
10141014
}
10151015
},
10161016
"nbformat": 4,

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /