我理解的“Python 一切皆对象!”

1.jpg

程序设计中“面向对象”是个老生常谈的话题,而Python则把“对象”发挥到了极致!

那究竟什么是“对象”?
我认为,一切可名状或不可名状之物皆可以称之为“对象”!世界是由对象组成的,世界本身也是一个对象。Python的世界秉承的正是这样的理念——一切皆对象——字符、数字、列表、元组、集合、字典、函数、类、模块、某种操作、甚至Python本身,等等都是对象。

在某些编程语言中,“对象”的定义较为苛刻,比如要求对象必须有“属性attribute”和“方法method”,或者对象必须可以子类化。而Python则更为宽容,没有这样那样的限制,它既包含狭义的对象,同时也将其他元素当成对象来对待。

那么Python究竟是怎么通过具体方式来体现“万物皆对象”的逻辑的呢?有没有更直观的理解方式?当然有!答案就是:

“Python, 一切都可以赋值!”

没错,一切都可以赋值!也就是可以执行‘=’操作。变量可以赋值、属性可以赋值、方法可以赋值、函数可以赋值、任何一种操作都可以赋值,即使很多时候这种赋值没有任何实际意义,但依然可以赋值!

举个例子,对于列表a=[1,2,3],a.append(4)表示调用列表方法把4加入到a的末尾作为第四个元素,它纯粹是一种操作,没有返回值。因此,如果写成b=a.append(4),除了诠释一下画蛇添足,并没有其他实际意义。然而神奇的Python告诉你:“没错,你可以这样干,因为我把a.append(4)这一操作过程也当成了对象,既然是对象,在我们Python的世界里那就是可以赋值的。不过我还想告诉你,这样的赋值对于完成你的工作没啥意义,因为这里的b啥也不是,但真的不影响我把他当对象!”。

看下面的代码显得更清楚。可见b的值是‘None’,而类型是‘None Type’,这意味着b没啥实际含义,但即使这样,Python还是一视同仁地给它分配了地址!深深地爱意,有没有?还可以继续赋值c = d,因为都是对象嘛。

>>>a = [1,2,3]
>>>b = a.append(4)
>>>print('a={},type(a):{}'.format(a,type(a)))
>>>print('b={},type(b):{}'.format(b,type(b)))
>>>print('id(b)={}'.format(id(b)))
a=[1, 2, 3, 4],type(a):<class 'list'>
b=None,type(b):<class 'NoneType'>
id(b)=1464837264

“Python,一切皆可以赋值”还有另一种表述:

“Python, 一切皆有“类型(type)”!

关于“类型”,int、string、list、tuple、set、dict、bool这些最基本的就不再啰嗦了,除此以外,还有各种各样稀奇古怪的类型,如前面提到的‘None Type’,对,它也属于一种独立的“类型”(这就好像数字0,虽然啥也没有,但它也是个数字啊)。Python对象都有“类型”,各种第三方库也都有自己各式各样的“类型”,用户甚至可以定义自己的“类型”。
在python中有一个非常有用的内置函数:type(),它可以返回对象的具体类型。
比如type(None),可见关键字‘None’的类型就是‘NoneType’。

>>>type(None)
NoneType

再比如type(type),可见函数type自己就是一个‘type’类型,这有点儿绕啊。

>>>type(type)
type

再比如内置求最大值函数“max”,从下面的代码可以看出函数‘max’本身的类型是builtin_function_or_method;而‘max()’的类型实际表示了返回值的类型;如果直接type(max())则会报错,因为没有输入,自然也无法判断输出是啥类型了。

>>>type(max)
builtin_function_or_method
>>>type(max([1,2,3]))
int
>>>type(max([1.,2.,3.]))
float
>>>type(max())
TypeError: max expected 1 arguments, got 0

注意:
(1) 在利用type()查看函数或方法时,函数名或方法名代表了函数或方法本身,而带上'()'则表示返回值的类型,如前面的type(max)和type(max())。
(2) python的部分关键字,如and、as、break、if、elif等等,确实是没有类型的,连‘NoneType’都不算。输入type(and),将得到错误信息SyntaxError: invalid syntax。可怜,这些关键字作用很大,连个对象都不算!

Python中尽量用狭义的“对象”概念进行编程

虽然Python对“对象”是宽容的,但大部分对象依然具备狭义“对象”的基本特性,即:对象有“属性attribute”和“方法method”!换句话说,操作对象可以通过点操作符“.”进行,即:

object.attribute”或“object.method()

还是举实例来直观说明。在MATLAB中对a=-1求绝对值必须用abs(a)的方式进行,因为a不是一个狭义的对象,它本身没有属性和方法,因此只能通过第三方函数进行操作。
在Python中情况就不一样了,a=-1它不仅是一个int整数,它也是一个int类型的对象,有它自己的属性和方法,取绝对值操作,不仅可以利用内置函数abs(),同样可以利用自身方法“__abs__()”,看如下代码,两者结果是完全相同的。

>>>a = -1
>>>print(abs(a))
>>>print(a.__abs__())
1
1

Python中的对象千千万,想要记住每一个对象都有啥属性和方法是不切实际的。但Python有一个非常有用的函数:dir(),它可以返回对象的基本属性和方法。如下所示,三者都输出了相同的结果,都是str对象的属性和方法,可见dir()的参数可以是类名称、变量名、实际对象等。

>>>a = 'ABC'
>>>dir(str)
>>>dir(a)
>>>dir('ABC')
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
……]

体会面向对象操作的魅力!

前面对比了“面向对象操作”与“直接利用内置函数操作”的差异,似乎没展现出“面向对象”的优点!别急,下面的例子一定会让你印象深刻!将a=[1,2,[3,-4]]中的-4取绝对值并转化为字符。
(1)利用第三方函数方法
str(abs(a[2][1]))
a[2]取出a的第三个元素[3,-4];[1]表示取出[3,-4]中的第二元素-4;abs()对-4取绝对值;str()将4转化为字符。

>>>a=[1,2,[3,-4]]
>>>str(abs(a[2][1]))
 '4'

(2)利用对象自身方法操作
a[2][1].__abs__().__str__()
首先a[2]取出[3,-4],是list对象;[1]取出-4,是int对象,它有一个__abs__()方法,返回绝对值4(依然是个int对象),int对象还有一个方法是__str__(),它将int转化为str对象,得到字符‘4’。如果想对这个字符‘4’进一步操作,则可以利用dir(str)查看str都还有哪些方法,继续加在后面便可。

>>>a=[1,2,[3,-4]]
>>>a[2][1].__abs__().__str__()
 '4'

通过比较可知,利用函数方法会出现层层包含的括号,当多个函数同时作用时,显得较为混乱。而利用“对象方法”则结构清晰,各方法从左到右逐个执行,由‘.’将各个方法分开,这种顺序结构一目了然。此外,内置函数的数量是极有限的,通常是一些通用型函数,对于很多特殊或者专门场景,无法在内置函数中找到需要的函数。通过将方法置于对象内部,既方便使用,也避免了将很多极私有的方法暴露于外部环境中,引起结构混乱。

鉴于Python的面向对象特性,编程时应利用对象的方法进行操作!

注意:
在利用对象方法进行操作时,下一个方法能从哪些方法里面选,是由上一个方法的返回值类型决定的,不能对int对象使用str对象的方法。如下例,a[0]是一个int对象,有__abs__()方法,而a[1]是一个str对象,没有__abs__()方法,会报错:

>>>a = [-1,'1']
>>>a[0].__abs__()
1
>>>a[1].__abs__()
AttributeError: 'str' object has no attribute

下面的例子中,__abs__()可以写无限个,原因在于a是一个int对象,调用自身方法__abs__()后返回的还是int对象,因此可以无限写下去,虽然没什么卵用,但有力展现了面向对象方法的特点!

>>>a= -1
>>>a.__abs__().__abs__().__abs__().__abs__().__abs__()
1
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容