Python学习笔记(8):面向对象

前面提到的操作函数和语句块是传统的面向过程编程,而编写大型程序,通常采用面向对象编程。类和对象是面向对象编程的两个主要方面,类创建一个新类型,而对象是类的实例。Python没有什么值类型与引用类型之分,它把所有事物统统看作是类。类使用class关键字来创建。

1. Self

类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候你不为这个参数赋值,Python会提供这个值。这个特别的变量指对象本身,按照惯例它的名称是self。

你一定很奇怪Python如何给self赋值以及为何你不需要给它赋值。举一个例子会使此变得清晰。假如你有一个类称为MyClass和这个类的一个实例MyObject。当你调用这个对象的方法MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method(MyObject, arg1, arg2)——这就是self的原理了。

2. 类

一个空类:

class Person:
    pass #An empty block

类的使用:

p = Person()
print(p)

3. 方法

类/对象可以拥有像函数一样的方法,这些方法与函数的区别只是一个额外的self变量。

class Person:
    def sayHi(self):
        print("Hello, how are you?")

p = Person()
p.sayHi()

注意调用sayHi方法时没有任何参数,但仍然在函数定义时有self。

4. __init__方法

在Python的类中有很多方法的名字有特殊的重要意义。像__init__,类似于构造函数。__init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的初始化 。注意,这个名称的开始和结尾都是双下划线。

class Person:
    def __init__(self, name):
        self.name = name

    def sayHi(self):
        print("Hello, my name is", self.name)


p = Person("known")
p.syaHi()

5. 域

Python有两种类型的域——类的变量对象的变量,它们根据是类还是对象拥有这个变量而区分。
类的变量由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。
对象的变量由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。

class Person:
    '''Represnets a person.'''
    population = 0

    def __init__(self, name):
        '''Initializes the person's data.'''
        self.name = name
        print("(Initializing %s)" % self.name)

        #When this person is created, he/she adds to the population
        Person.population += 1

    def __del__(self):
        '''I am dying.'''
        print("%s says bye." % self.name)

        Person.population -= 1

        if Person.population == 0:
            print("I am the last one.")
        else:
            print("There are still %d people left." % Person.population)

    def sayHi(self):
        '''Greeting by the person.
          Really, that's all it does.'''
        print("Hi, my name is %s." % self.name)

    def howMany(self):
        '''Prints the current population.'''
        if Person.population == 1:
            print("I am the only person here.")
        else:
            print("We have %d person here." % Person.population)


swaroop = Person('Swaroop')
swaroop.sayHi()
swaroop.howMany()

kalam = Person('Abdul Kalam')
kalam.sayHi()
kalam.howMany()

swaroop.sayHi()
swaroop.howMany()

del kalam
del swaroop

运行结果:

(Initializing Swaroop)
Hi, my name is Swaroop.
I am the only person here.
(Initializing Abdul Kalam)
Hi, my name is Abdul Kalam.
We have 2 persons here.
Hi, my name is Swaroop.
We have 2 persons here.
Abdul Kalam says bye.
There are still 1 people left.
Swaroop says bye.
I am the last one.

6. 继承

在类名后面跟一对圆括号,基类名写在圆括号内。

class SchoolMember:
    '''Represents any school member.'''
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print("(Initialized SchoolMember: %s)" % self.name)

    def tell(self):
        '''Tell my details.'''
        print("Name:'%s' Age:'%s'" % (self.name, self.age))

class Teacher(SchoolMember):
    '''Represents a teacher.'''
    def __init__(self, name, age, salary):
        SchoolMember.__init__(self, name, age)
        self.salary = salary
        print("(Initialized Teacher: %s)" % self.name)

    def tell(self):
        SchoolMember.tell(self)
        print("Salary: '%d'" % self.salary)

class Student(SchoolMember):
    '''Represents a student.'''
    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
        self.marks = marks
        print("(Initialized Student: %s)" % self.name)

    def tell(self):
        SchoolMember.tell(self)
        print("Marks: '%d'" % self.marks)


t = Teacher("Mrs. Shrividya", 40, 30000)
s = Student("Swaroop", 22, 75)

print() # prints a blank line

members = [t, s]
for member in members:
    member.tell() # works for both Teachers and Students

输出结果:

(Initialized SchoolMember: Mrs. Shrividya)
(Initialized Teacher: Mrs. Shrividya)
(Initialized SchoolMember: Swaroop)
(Initialized Student: Swaroop)


Name:'Mrs. Shrividya' Age:'40' Salary: '30000'
Name:'Swaroop' Age:'22' Marks: '75'

posted @ 2010-09-04 22:21 known 阅读(3540) 评论(15) 编辑 收藏

 回复 引用 查看   
#1楼 2010-09-04 23:37 大道无情      
真不知道 python这样的偏门语言什么好,语法怪怪的 空格和 和TAB 制表符不一样 会编译通不过,看年<梦断代码> 世界最牛的一群人聚在一起有微软技术经理,苹果公司操作系统核心开发人员,firefox 核心代码开发人员,莲花软件公司创始人 等等世界超级大牛 一起开发一个看似简单个人时间管理小软件(类似)outlook 耗时数年,耗资数百万 最终失败的的真实故事,因为什么选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python ,因为选择了python
 回复 引用 查看   
#2楼 2010-09-05 00:04 亚历山大同志      
@大道无情
不知道你那里去看了一段半拉子的文章就对一门各个真正计算机语言开山怪都喜欢的语言保有了如此大的偏见
用Python开发的成功项目多去了,对你的言论我只能用“井底之蛙”来形容,打上引号是因为这句话实在看来像是人身攻击,但是我实在找不出词汇来形容了


 回复 引用 查看   
#3楼 2010-09-05 00:11 亚历山大同志      
@大道无情
而且很高兴的告诉你,Python已经取代Schame成为MIT的600X系列课程的入门语言。
MIT的人都是疯子?

 回复 引用 查看   
#4楼 2010-09-05 01:51 大道无情      
引用亚历山大同志:
@大道无情
不知道你那里去看了一段半拉子的文章就对一门各个真正计算机语言开山怪都喜欢的语言保有了如此大的偏见
用Python开发的成功项目多去了,对你的言论我只能用“井底之蛙”来形容,打上引号是因为这句话实在看来像是人身攻击,但是我实在找不出词汇来形容了


-------------
用Python开发的成功项目多去了 你倒举几个大软件我看看

 回复 引用 查看   
#5楼 2010-09-05 02:15 大道无情      
python perl 主流应用 都是CGI时代的产物 那时候没有 ASP PHP这样的技术出来 现在都.NET JAVA 的天下了 还包着这种东西干什么 开发 Chandler
项目的一大堆世界级牛人 选择python 做Form UI程序 全军覆没 死得多惨, 看介绍的时候总是说 python perl 什么都能干 From UI ,socket 等等 说得多好,但真正用的时候 没有类库自己重头玩累死,比C++ 还麻烦(如果你硬要说嫌C++麻烦是因为学得不够)那也没办法,记得linux 作者了曾公开说过同样的话:(C++烦人 纠结,基本一无是处,系统底层应该用C 汇编这些语言,关系业务的企业企业开发 应该选用 JAVA C# 之类的托管类型语言,选C++的 人脑壳有包),虽然论点过激,但也代表大多人心声,python perl 本来就是同时代CGI时代的东西, 现在还有多少人用 CGI做网站? 自己合成HTML输出,每个HTTP请求都开一个进程,大网站同时有上千上万个进程跑起;光语言的时代已经过去了, 语言干的事很少,需要框架,类库,再框架,类库,稍大点的应用 都要框架支持,自己重头写 就学<梦断代码>中Chandler项目的那群牛人,再牛最后都得死, 看看Chandler项目 好多底层东西协议都是 重头写的, 还有PHP 定义声称也是可以做From UI socket通信 甚至动画之类的程序,但又有谁这么干了,每门语言都有它的适用范围,老实在自己范围内呆着,万能语言都没好下场的

 回复 引用 查看   
#6楼 2010-09-05 06:58 hoodlum1980      
@大道无情
我说你这个对C++的偏见实在是太过激了。在性能,底层方面要求高挑战性的应用场合还是C++是唯一选择。有些人拿什么C#也能开发个模仿Photoshop的事情来反驳真是幼稚和可笑。就目前的背景来看,在相当长一段时间内,C#都没有能力完全进入windows应用程序(用C#的语言来说叫做winform)开发领域。C#里面很多自作聪明的考虑,实际上已经限制了程序员的手脚,使得它们的应用和发挥空间受限。

 回复 引用 查看   
#7楼 2010-09-05 10:30 空明流转      
@大道无情
啊,高手啊。听了您的话,我决定弃暗投明了。谢谢大牛指点!楼上说Python好什么的,都是口胡扯啊,你们举几个例子给大牛看看!大牛,我可以拜你为师么?

 回复 引用 查看   
#8楼 2010-09-05 10:35 Welshem      
楼主头像好诱人啊!

 回复 引用 查看   
#9楼 2010-09-05 13:52 刀槍blue      
@大道无情
我觉得Chandler的失败不能归结於python。
和python相关的大致有如下几处:
1.当时的环境条件所限,基础设备不足,开始的大量精力投入到基础库的编写当中,却又由於设计原因经常推翻重来。
2.对於python的用法有误,最後积重难返。
读梦断代码,看Chandler team在开发开始几年之後仍然在反覆自问到底应该做什麽样的东西,在设计上举步维艰最终不得不做出很多让步,感到涉及到语言层面的部分,不过是很小的一个因素。

时至今日局面已经完全不同,开源库的丰富程度不可同日而语,开发方法也已较清晰,采用python我以为不再成为问题。

至於为什麽python应用较少,我以为作为大型项目一是效率问题,在git成熟之前python的效率难以承担起基干应用。再是习惯问题,java开发环境已经很成熟,积累很多,熟手的开发效率很高,这样的team选择python的意义不大。但用python或ruby或任何其他语言作为辅助工具编写脚本等则可以因地制宜。

而对於新手而言,我以为没有一定要反对python的理由吧。况且有Jython和IronPython可用,即使你不喜欢,多一种选择总不是坏事吧。

python的知名应用有Zope/Plone,BitTorrent等,而小型开源项目只能说太多,支持用python编写插件的程序也很多。作为网站应用,python的framework也相当丰富,且容易自行扩展,豆瓣就是基於python构建的一个例子。

有些场景选择python是非常自然的,例如如果我要做文本的简单处理,是不会出动.NET的,而会写十几行的python脚本。如果我要写一个小型网站,也会选择django来做。应用程序我会先用python写後台,最後用gtk或者qt来做ui部分,这里面有效率和可移植性的考量,我当然不会用python去写驱动程序,或者银行的基干系统,因为有其他适合的语言可以用。

我接触python时间不长,现在也在学习之中。任何语言都有不足,讨伐C++或java甚至C的言论都多过python很多,然而在某个场景下,能确实解决问题的语言,我以为是有其存在的价值的,不必因為小的瑕疵或使用习惯上的不适应就予以否定。

 回复 引用 查看   
#10楼 2010-09-06 14:07 大道无情      
hoodlum1980
=------------
C++ 的那断言论不是我说的 是linux 的作者说的, 如果哪位认为 水平,经验,阅历,悟性超过了linux的作者 倒可以去跟他反驳一下

 回复 引用 查看   
#11楼 2010-09-07 09:16 LawSong      
我上学那会也喜欢讨论语言优劣的问题.
现在不会再讨论这种问题了.

 回复 引用 查看   
#12楼 2010-09-07 09:43 二叉树      
楼主继续,我最近也在看Python。
BTW,楼主看的是什么资料,我在看 Tutorial

 回复 引用 查看   
#13楼[楼主] 2010-09-07 12:32 known      
@二叉树
我看的是Python简明教程,在网上找的。

 回复 引用 查看   
#14楼 2010-09-08 13:20 萤火虫      
@大道无情

看下来我觉得你的逻辑有点问题。
书里面是不是说由于用了python导致失败,这个我们姑且不论。如果说书里面是这样论断的话,那么在这里我很高兴的宣布这本书是破烂一堆,作者应该拉出来暴打一顿完事。
《人月神话》听说过吧?那个项目大吗?牛人多吗?最后失败了。所以原因是由于用了C对吧?

任何一个项目的失败都不是语言的因素都是人的因素,是人让它失败它才会走向失败。明白吗?

再说第二个问题,什么python是CGI时代的产物。
这句话说出来就充分说明了你不懂web,没有经历过那个时代更不明白什么是cgi。
cgi的中文比较拗口,通用网关接口。其实说白了就是服务器端技术。通俗一点,一个东西只要是基于web,那么就可以说是cgi(除非是全部静态内容不使用任何服务器端程序动态执行)。
所以你说“CGI时代”就陷入了误区。

再说类库之类的,如果你认为python的类库不够丰富而java和.net的才丰富那么你就真的是一点都不知道天高地厚。
java的jdk每次升级升级基本上都是补充各种API。所以先jdk的api充斥着低效,重复,混乱。唯一比较欣慰的是社区有很多不错library可以选择。
.net基本上除了微软官方的library之外很少有第三方的library,凤毛麟角的几家商业公司在提供各种收费的组件,而社区的力量可以说是微乎其微的小。
反观python,我不知道你是想要什么样的library找不到?

 回复 引用 查看   
#15楼 2010-09-08 14:44 .net小鸟      
学这个纯粹是出于兴趣,觉着还不错,不知道如何用来做实际的项目开发