Skip to content

Commit d2c6e70

Browse files
committed
p3
1 parent 7fabe93 commit d2c6e70

File tree

4 files changed

+36
-39
lines changed

4 files changed

+36
-39
lines changed

209.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,8 @@ Python 2的新式类,以及Python 3中都是按照此顺序原则搜寻属性
306306

307307
导致新式类和Python 3中继承顺序较旧式类有所变化,其原因是mro(Method Resolution Order)算法,读者对此若有兴趣,可以到网上搜索关于这个算法的内容进行了解。
308308

309-
310309
------
311310

312-
[总目录](./index.md)   |   [上节:类(3)](./208.md)   |   [下节:类(5)](./210.md)
311+
[总目录](./index.md)   |   [上节:类(4)](./238.md)   |   [下节:多态和封装](./211.md)
313312

314313
如果你认为有必要打赏我,请通过支付宝:**[email protected]**,不胜感激。

211.md

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22
33
#多态和封装
44

5-
前面讲过的“继承”,是类的一个重要特征,在编程中用途很多。这里要说两个在理解和实践上有争议的话题:多态和封装。所谓争议,多来自于对同一个现象不同角度的理解,特别是有不少经验丰富的程序员,还从其它语言的角度来诠释python的多态等
5+
“多态”和“封装”是OOP的重要特征——前面说的“继承”也是。但是,对于Python而言,对这两个的理解也有很多不同。建议读者“吃百家宴”,到网上搜一搜有关话题,不少人写了文章来讨论
66

77
##多态
88

9-
在网上搜索一下,发现对python的多态问题,的确是仁者见仁智者见智
9+
这里我仅仅针对初学者,按照自己的理解,谈谈零基础学Python的读者可以怎样理解“多态”,因为“多态”就如同其名字一样,在理解上也是“多态”的
1010

11-
作为一个初学者,不一定要也没有必要、或者还没有能力参与这种讨论。但是,应该理解python中关于多态的基本体现,也要对多态有一个基本的理解。
11+
先来看这样的例子:
1212

1313
>>> "This is a book".count("s")
1414
2
1515
>>> [1,2,4,3,5,3].count(3)
1616
2
1717

18-
上面的`count()`的作用是数一数某个元素在对象中出现的次数。从例子中可以看出,我们并没有限定count的参数。类似的例子还有:
18+
上面的`count()`的作用是数一数某个元素在对象中出现的次数。从例子中可以看出,我们并没有限定`count()`的参数类型。类似的例子还有:
1919

2020
>>> f = lambda x,y:x+y
2121

22-
还记得这个lambda函数吗?如果忘记了,请复习[函数(5)](./237.md)中对此的解释。
22+
还记得这个`lambda`函数吗?如果忘记了,请复习[函数(5)](./237.md)中对此的解释。
2323

2424
>>> f(2,3)
2525
5
@@ -28,23 +28,25 @@
2828
>>> f(["python","java"],["c++","lisp"])
2929
['python', 'java', 'c++', 'lisp']
3030

31-
在那个lambda函数中,我们没有限制参数的类型,也一定不能限制,因为如果限制了,就不是pythonic了。在使用的时候,可以给参数任意类型,都能得到不报错的结果。当然,这样做之所以合法,更多的是来自于`+`的功能强悍
31+
这里我们没有限制参数的类型,也一定不能限制,因为如果限制了,就不是pythonic了。在使用的时候,可以给参数任意类型,都能得到不报错的结果。
3232

33-
以上,就体现了“多态”。当然,也有人就此提出了反对意见,因为本质上是在参数传入值之前,python并没有确定参数的类型,只能让数据进入函数之后再处理,能处理则罢,不能处理就报错。例如:
33+
以上,就体现了“多态”——同一种行为具有不同表现形式和形态的能力,换一种说法,就是对象多种表现形式的体现。
34+
35+
当然,也有人就此提出了反对意见,因为本质上是在参数传入值之前,Python并没有确定参数的类型,只能让数据进入函数之后再处理,能处理则罢,不能处理就报错。例如:
3436

3537
>>> f("qiw", 2)
3638
Traceback (most recent call last):
3739
File "<stdin>", line 1, in <module>
3840
File "<stdin>", line 1, in <lambda>
3941
TypeError: cannot concatenate 'str' and 'int' objects
4042

41-
本教程由于不属于这种概念争论范畴,所以不进行这方面的深入探索,仅仅是告诉各位读者相关信息。并且,本教程也是按照“人云亦云”的原则,既然大多数程序员都在讨论多态,那么我们就按照大多数人说的去介绍(尽管有时候真理掌握在少数人手中)。
43+
本书由于不属于这种概念争论范畴,所以不进行这方面的深入探索,仅仅是告诉各位读者相关信息。并且,也是按照“人云亦云”的原则,既然大多数程序员都在讨论多态,那么我们就按照大多数人说的去介绍(尽管有时候真理掌握在少数人手中)。
4244

4345
“多态”,英文是:Polymorphism,在台湾被称作“多型”。维基百科中对此有详细解释说明。
4446

4547
>多型(英语:Polymorphism),是指物件導向程式執行時,相同的訊息可能會送給多個不同的類別之物件,而系統可依據物件所屬類別,引發對應類別的方法,而有不同的行為。簡單來說,所謂多型意指相同的訊息給予不同的物件會引發不同的動作稱之。
4648
47-
再简化的说法就是“有多种形式”,就算不知道变量(参数)所引用的对象类型,也一样能进行操作,来者不拒。比如上面显示的例子。在python中,更为pythonic的做法是根本就不进行类型检验。
49+
再简化的说法就是“有多种形式”,就算不知道变量(参数)所引用的对象类型,也一样能进行操作,来者不拒。比如上面显示的例子。在Python中,更为pythonic的做法是根本就不进行类型检验。
4850

4951
例如著名的`repr()`函数,它能够针对输入的任何对象返回一个字符串。这就是多态的代表之一。
5052

@@ -79,25 +81,27 @@
7981

8082
报错了。看错误提示,明确告诉了我们`object of type 'int' has no len()`
8183

82-
在诸多介绍多态的文章中,都会有这样关于猫和狗的例子。这里也将代码贴出来,读者去体会所谓多态体现。其实,如果你进入了python的语境,有时候是不经意就已经在应用多态特性呢。
84+
上述的种种多态表现,皆因为Python是一种解释型的语言,不需要进行预编译,只在运行时才确定状态。所以,Python就被认为天生是一种多态的语言。也有人持相反观点,认为Python不支持多态,在理由中,也用了上述内容。看来,看着半杯水,的确能够有不同的结论——“还有半杯水呢!”和“还剩半杯水了!”。
85+
86+
争论,让给思想者。我们,围观。
87+
88+
在诸多介绍多态的文章中,都会有这样关于猫和狗的例子。这里也将代码贴出来,读者去体会所谓多态体现。其实,如果你进入了Python的语境,有时候是不经意就已经在应用多态特性呢。
8389

8490
#!/usr/bin/env python
8591
# coding=utf-8
8692

8793
"the code is from: http://zetcode.com/lang/python/oop/"
8894

89-
__metaclass__ = type
90-
91-
class Animal:
95+
class Animal(object): #Python 3: class Animal:
9296
def __init__(self, name=""):
9397
self.name = name
9498

9599
def talk(self):
96100
pass
97101

98-
class Cat(Animal):
102+
class Cat(Animal):
99103
def talk(self):
100-
print "Meow!"
104+
print "Meow!" #Python 3: print('Meow!'),下同,从略
101105

102106
class Dog(Animal):
103107
def talk(self):
@@ -118,7 +122,11 @@
118122
Meow!
119123
Woof!
120124

121-
代码中有Cat和Dog两个类,都继承了类Animal,它们都有`talk()`方法,输入不同的动物名称,会得出相应的结果。
125+
代码中有`Cat``Dog`两个类,都继承了类`Animal`,它们都有`talk()`方法,输入不同的动物名称,会得出相应的结果。
126+
127+
根据前面已经学习过的类和继承的知识,我们知道,对于实例`c`是Cat类型的对象,`d`是Dog类型的对象,但它们也都是Animal类型的对象——类,也是一种对象类型,这样,不论是谁,也都有`Animal`类所规定的方法和属性——多态就体现在这里——继承了`Animal`的子类,实例化之后都可以具有`Animal`的表现形式。
128+
129+
对“多态”的理解,还可以在实践中慢慢增加。
122130

123131
关于多态,有一个被称作“鸭子类型”(duck typeing)的东西,其含义在维基百科中被表述为:
124132

@@ -130,32 +138,26 @@
130138

131139
##封装和私有化
132140

133-
在正式介绍封装之前,先扯个笑话。
134-
135-
>某软件公司老板,号称自己懂技术。一次有一个项目要交付给客户,但是他有不想让客户知道实现某些功能的代码,但是交付的时候要给人家代码的。于是该老板就告诉程序员,“你们把那部分核心代码封装一下”。程序员听了之后,迷茫了。
136-
137-
不知道你有没有笑。
141+
“封装”,是不是把代码写到某个东西里面,“人”在编辑器中打开,就看不到了呢?
138142

139-
“封装”,是不是把代码写到某个东西里面,“人”在编辑器中打开,就看不到了呢?除非是你的显示器坏了。
143+
除非是你的显示器坏了。
140144

141-
在程序设计中,封装(Encapsulation)是对object的一种抽象,即将某些部分隐藏起来,在程序外部看不到,即无法调用(不是人用眼睛看不到那个代码,除非用某种加密或者混淆方法,造成现实上的困难,但这不是封装)。
145+
在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,即无法调用(不是人用眼睛看不到那个代码,除非用某种加密或者混淆方法,造成现实上的困难,但这不是封装)。
142146

143147
要了解封装,离不开“私有化”,就是将类或者函数中的某些属性限制在某个区域之内,外部无法调用。
144148

145-
python中私有化的方法也比较简单,就是在准备私有化的属性(包括方法、数据)名字前面加双下划线。例如:
149+
Python中私有化的方法也比较简单,就是在准备私有化的属性(包括方法、数据)名字前面加双下划线。例如:
146150

147151
#!/usr/bin/env python
148152
# coding=utf-8
149153

150-
__metaclass__ = type
151-
152-
class ProtectMe:
154+
class ProtectMe(object): #Python 3: class ProtectMe:
153155
def __init__(self):
154156
self.me = "qiwsir"
155157
self.__name = "kivi"
156158

157159
def __python(self):
158-
print "I love Python."
160+
print "I love Python." #Python 3: print("I love Python."),下同,从略
159161

160162
def code(self):
161163
print "Which language do you like?"
@@ -201,9 +203,7 @@ python中私有化的方法也比较简单,就是在准备私有化的属性
201203
#!/usr/bin/env python
202204
# coding=utf-8
203205

204-
__metaclass__ = type
205-
206-
class ProtectMe:
206+
class ProtectMe(object): #Python 3: class ProtectMe:
207207
def __init__(self):
208208
self.me = "qiwsir"
209209
self.__name = "kivi"
@@ -214,7 +214,7 @@ python中私有化的方法也比较简单,就是在准备私有化的属性
214214

215215
if __name__ == "__main__":
216216
p = ProtectMe()
217-
print p.name
217+
print p.name #Python 3: print(p.name)
218218

219219
运行结果:
220220

@@ -227,6 +227,6 @@ python中私有化的方法也比较简单,就是在准备私有化的属性
227227

228228
------
229229

230-
[总目录](./index.md)&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;[上节:类(5)](./210.md)&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;[下节:更多属性(1)](./212.md)
230+
[总目录](./index.md)&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;[上节:类(5)](./209.md)&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;[下节:更多属性(1)](./212.md)
231231

232232
如果你认为有必要打赏我,请通过支付宝:**[email protected]**,不胜感激。

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@
7373
3. [类(3)](./208.md)==>类属性、创建实例、实例属性、self作用、类内外数据流转
7474
4. [类(4)](./238.md)==>绑定方法和非绑定方法,类方法和静态方法
7575
5. [类(5)](./209.md)==>继承,super,多重继承
76-
6. [类(6)](./210.md)==>静态方法和类方法,两者的区别,类的文档
77-
7. [多态和封装](./211.md)==>多态,封装和私有化
76+
6. [多态和封装](./211.md)==>多态,封装和私有化
7877
8. [特殊方法(1)](./212.md)==>`__dict__``__slots__`
7978
9. [特殊方法(2)](./213.md)==>`__getattr__`,`__setattr__`以及查找属性顺序,双划线解释
8079
10. [迭代器](./214.md)==>迭代器方法`__iter__`,`netx()`

index.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@
7373
3. [类(3)](./208.md)==>类属性、创建实例、实例属性、self作用、类内外数据流转
7474
4. [类(4)](./238.md)==>绑定方法和非绑定方法,类方法和静态方法
7575
5. [类(5)](./209.md)==>继承,super,多重继承
76-
6. [类(6)](./210.md)==>静态方法和类方法,两者的区别,类的文档
77-
7. [多态和封装](./211.md)==>多态,封装和私有化
76+
6. [多态和封装](./211.md)==>多态,封装和私有化
7877
8. [特殊方法(1)](./212.md)==>`__dict__``__slots__`
7978
9. [特殊方法(2)](./213.md)==>`__getattr__`,`__setattr__`以及查找属性顺序,双划线解释
8079
10. [迭代器](./214.md)==>迭代器方法`__iter__`,`netx()`

0 commit comments

Comments
 (0)