关闭

帮Python找“对象”

5039人阅读 评论(3) 收藏 举报
分类:

引言:你一定会感叹:Python还缺找对象? 毕竟“一切皆对象”是人家Python的哲学理念。不过,Python 
允许程序员以纯粹的面向过程的方式来使用它,所以人们有时会忽视它那颗“找对象”的心。其实无论是面向过程,还是函数式编程,都是特殊的对象模拟出的效果。 
本文选自《从Python开始学编程》。让我们通过帮Python找对象,来学习Python这一语言。

  说是要“找对象”,我们第一个看的却是个叫作“类”的语法结构。这里的类其实和我们日常生活中的“类”的概念差不多。日常生活中,我们把相近的东西归为一类,而且给这个类起一个名字。比如说,鸟类的共同属性是有羽毛,通过产卵生育后代。任何一只特别的鸟都是建立在鸟类的原型基础上的。 
  下面我们用Python 语言来记录上面的想法,描述鸟类:

class Bird(object):
feather = True
reproduction = "egg"

  在这里,我们用关键字class 来定义一个类。类的名字就是鸟(Bird)。括号里有一个关键词object,也就是“东西”的意思,即某一个个体。在计算机语言中,我们把个体称为对象。一个类别下,可以有多个个体。鸟类就可以包括邻居老王养的金丝雀、天边正飞过的那只乌鸦,以及家里养的一只小黄鸡。 
  冒号和缩进说明了属于这个类的代码。在隶属于这个类别的程序块中,我们定义了两个量,一个用于说明鸟类有羽毛(feather),另一个用于说明鸟类的繁殖方式(reproduction),这两个量称为类的属性(attribute)。我们定义鸟类的方法很粗糙,鸟类只不过是“有毛能产蛋”的东西。要是生物学家看到了大概会暗自摇头,但我们毕竟迈出了模拟世界的第一步。 
  我们除了用数据性的属性来分辨类别外,有时也会根据这类东西能做什么事情来区分。比如说,鸟会移动。这样,鸟就和房屋的类别就区分开了。这些动作会带来一定的结果,比如移动导致位置的变化。这样的一些“行为”属性称为方法(method)。Python 中,一般通过在类的内部定义函数来说明方法。

class Bird(object):
feather = True
reproduction = "egg"
def chirp(self, sound):
print(sound)

  我们给鸟类新增一个方法属性,就是表示鸟叫的方法chirp()。方法chirp()看起来很像一个函数。它的第一个参数是self,是为了在方法内部引用对象自身,我将在后面详细解释。需要强调的是,无论该参数是否用到,方法的第一个参数必须是用于指代对象自身的self。剩下的参数sound 是为了满足我们的需求设计的,它代表了鸟叫的内容。方法chirp()会把sound 打印出来。

对象

  我们定义了类,但和函数定义一样,这还只是打造兵器的过程。为了使用这个利器,我们需要深入到对象的层面。通过调用类,我们可以创造出这个类下面的一个对象。比如说,我养了一只小鸡,叫summer。它是个对象,且属于鸟类。我们使用前面已经定义好的鸟类,产生这个对象:

summer = Bird()

  通过这一句创建对象,并说明summer 是属于鸟类的一个对象。现在,我们就可以使用鸟类中已经写好的代码了。作为对象的summer 将拥有鸟类的属性和方法。对属性的引用是通过对象.属性(object.attribute)的形式实现的。比如说:

print(summer.reproduction) # 打印'egg'

  用上面的方式,我们得到summer 所属类的繁殖方式。 
  此外,我们还可以调用方法,让summer 执行鸟类允许的动作。比如:

summer.chirp("jijiji") # 打印'jijiji'

  在调用方法时,我们只传递了一个参数,也就是字符串”jijiji”。这正是方法与函数有所区别的地方。尽管在定义类的方法时,我们必须加上这个self 参数,但self 只用能在类定义的内部,所以在调用方法时不需要对self 传入数据。通过调用chirp()方法,我的summer 就可以叫了。 
  到现在为止,描述对象的数据都存储于类的属性中。类属性描述了一个类的共性,比如鸟类都有羽毛。所有属于该类的对象会共享这些属性。比如说,summer 是鸟类的一个对象,因此summer 也有羽毛。当然,我们可以通过某个对象来引用某个类属性。 
  对于一个类下的全部个体来说,某些属性可能存在个体差异。比如说,我的summer 是黄色的,但并非所有的鸟儿都是黄色的。再比如说人这个类。性别是某个人的一个性质,不是所有的人类都是男,或者都是女。这个性质的值随着对象的不同而不同。李雷是人类的一个对象,性别是男。韩美美也是人类的一个对象,性别是女。 
  因此,为了完整描述个体,除了共性的类属性外,我们还需要用于说明个性的对象属性。在类中,我们可以通过self 来操作对象的属性。现在我们拓展Bird 类:

class Bird(object):
def chirp(self, sound):
print(sound)
def set_color(self, color):
self.color = color


summer = Bird()
summer.set_color("yellow")
print(summer.color) # 打印'yellow'

  在方法set_color()中,我们通过self 参数设定了对象的属性color。和类属性一样,我们能通过对象.属性的方式来操作对象属性。由于对象属性依赖于self,所以我们必须在某个方法内部才能操作类属性。因此,对象属性没办法像类属性一样,在类下方直接赋初值。 
  但Python 还是提供了初始化对象属性的办法。Python 定义了一系列特殊方法。特殊方法又被称为魔法方法(Magic Method)。特殊方法的方法名很特别,前后有两个下画线,比如init()、add()、dict()等。程序员可以在类定义中设定特殊方法。Python 会以特定的方式来处理各个特殊方法。对于类的init()方法,Python 会在每次创建对象时自动调用。因此,我们可以在init()方法内部来初始化对象属性:

class Bird(object):
def __init__(self, sound):
self.sound = sound
print("my sound is:", sound)
def chirp(self):
print(self.sound)


summer = Bird("ji")
summer.chirp() # 打印'ji'

  在上面的类定义中,我们通过init()方法说明了这个类的初始化方式。每当对象建立时,比如创建summer 对象时,init()方法就会被调用。它会设定sound 这个对象属性。在后面的chirp()方法中,就可以通过self 调用这一对象属性。除了设定对象属性外,我们还可以在init()中加入其他指令。这些指令会在创建对象时执行。在调用类时,类的后面可以跟一个参数列表。这里放入的数据将传给init()的参数。通过init()方法,我们可以在创建对象时就初始化对象属性。 
  除了操作对象属性外,self 参数还有另外一个功能,就是能让我们在一个方法内部调用同一类的其他方法,比如:

class Bird(object):
def chirp(self, sound):
print(sound)

def chirp_repeat(self, sound, n):
for i in range(n):
self.chirp(sound)

summer = Bird()
summer.chirp_repeat("ji", 10) # 重复打印'ji'10 次

  在方法chirp_repeat()中,我们通过self 调用了类中的另一个方法chirp()。

  Python的对象很多也很有趣,比如前面的文章《那些Python意想不到的对象》。若与这些对象深入交往,你会发现Python更多的魔力。更多内容可见《从Python开始学编程》一书。

  本文选自《从Python开始学编程》,点此链接可在博文视点官网查看此书。 
                     

图片描述

  想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                              图片描述

1
0
查看评论

HDU 2.1.6 找新朋友

找新朋友 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2681 Accepted Submission(s): 12...
  • hwj_wayne
  • hwj_wayne
  • 2016-03-10 18:18
  • 516

设计模式大杂烩之一

模式是不断重复发生的问题、以及该问题的解决方案的核心的总和;而面向对象设计模式是在面向对象设计中对要你过来在特定场景下解决一般设计问题的类和互相通信的对象的描述。在面向对象设计中,万物皆为对象,每个对象都拥有其类型,类型即类,也就是说每个对象都是某个类的一个实例。使用面向对象编程语言编写的程序是对象...
  • tantian189
  • tantian189
  • 2016-07-22 17:04
  • 203

帮朋友找实习生

帮朋友找实习生(2~3个,在广州) 要求:1、大专以上学历、计算机相关专业2、有一定的软件测试理论基础知识3、熟悉数据库4、最好掌握自动化测试工具 如果有需要的可联系:allencnj#126.com 
  • Testing_is_believing
  • Testing_is_believing
  • 2010-04-11 11:01
  • 1435

作业帮前端

盒模型 移动端自适应 定位 实现划过区域显示信息 事件代理
  • echody
  • echody
  • 2017-09-12 22:45
  • 514

帮朋友找网站漏洞

朋友的网站被黑了,居然把数据库的内容全都删除了!来找我看看代码打开源文件一看,倒!到处都是漏洞,代码的不严谨造成了所谓黑客的攻击手段!首先说新闻部分xxx.com/article_view.asp?id=556里边由于没有过滤代码则造成xxx.com/article_view.asp?id=556&...
  • fucjp
  • fucjp
  • 2005-08-16 17:31
  • 867

帮房东找到了租客

我们新找了新房子,所以准备推掉旧的租新的。他们俩都感觉新房子比老房子好很多。我却感觉房租更贵却更小离公司更远了。不过新房子也有很多好处。设施比老房子好很多,都很新,厨房,热水器,都好用很多。离海边近,等天热了,可以去海里游泳。想一想我只穿个游泳裤从家里穿街过巷跑到海边去。在公司新闻组发了贴子帮原先的...
  • SunYong11
  • SunYong11
  • 2010-03-20 23:16
  • 364

如何抓取作业帮的问题数据?

作业帮可以说是最快做学生课程问答方面的APP,但是却没有网页版,只有手机APP,那么现在问题来了,我要如何抓取作业帮的数据呢?
  • fhg12225
  • fhg12225
  • 2017-03-16 17:21
  • 858

python+opencv实现简单的图片搜索功能

原文地址 http://www.pyimagesearch.com/2014/12/01/complete-guide-building-image-search-engine-python-opencv/一、图片搜索中的概念解释: 图片搜索引擎有三种不同的模式 1.Search by Met...
  • funny75
  • funny75
  • 2016-03-19 22:36
  • 1833

在C++中使用类模板帮助用户创建类实例

在C++中使用类模板帮助用户创建类实例问题的产生最近工作中使用C++遇到一个问题,我创建了一个管理线程的类ThreadCenter,这个类中包含一个存放Thread类指针的向量,而Thread是一个虚基类,我需要在ThreadCenter类中帮助用户创建他们的派生类实例,以便确保管理的每个Threa...
  • u012515915
  • u012515915
  • 2016-05-24 22:05
  • 487

车托帮APP的顽固残留清除

我用的是华为畅玩3手机,每次清理空间的时候在应用残留下都能看见车托帮APP的残留。在设置-应用程序管理里看不到车托帮应用,也没有任何桌面图标。并且我没有主动下载过车托帮,所以推断车托帮是个流氓软件。 下来就是如何卸载车托帮,华为本身的手机管家并不能卸载软件,应用程序管理里也找不到,我又不想安装其他...
  • some_man
  • some_man
  • 2016-06-03 17:05
  • 14724
    个人资料
    • 访问:3919388次
    • 积分:56460
    • 等级:
    • 排名:第57名
    • 原创:1462篇
    • 转载:83篇
    • 译文:1篇
    • 评论:3786条
    博客专栏
    文章存档
    最新评论