python函數(shù)引發(fā)的多態(tài)思考

# -*- coding: utf-8 -*-

"""

Created on Fri May 20 01:48:27 2017

@author: zhangll

"""

? ? 函數(shù)也是p對(duì)象,學(xué)過java的同學(xué)都知道“方法”的概念载城,“方法”在java的表現(xiàn)中是指一段程序流程的封裝,而python函數(shù)可以在這個(gè)概念上與java的“方法”概念相呼應(yīng)。但是java

方法調(diào)用的參數(shù)分為實(shí)參和形參赴肚,java中并沒有傳遞“方法”參數(shù)這一說法,一般是通過

包裝好的類、變量作為參數(shù)來實(shí)現(xiàn)程序的轉(zhuǎn)移的。在python中卻可以利用“函數(shù)”作為參數(shù)來傳遞的荚斯,可以說python把“函數(shù)”作為一個(gè)“對(duì)象”來考慮的。如下:我們看一個(gè)簡單的例子:

def pythagorean(a,b):

? ? ? ? return sum((a**2,b**2))**0.5

def pythagoreandouble(funcation,c):

? ? ? ? return funcation(c[0]*2,c[1]*2)

if__name__=='__main__':

? ? ? ? pythagoreandouble(pythagorean,(3,4))

其中pythagorean是勾股定理查牌,我們把pythagorean函數(shù)作為一個(gè)參數(shù)傳入pythagoreandouble(計(jì)算勾股的兩倍)函數(shù)中事期,作為一個(gè)函數(shù)來使用,結(jié)果為纸颜,擴(kuò)充了一倍兽泣,結(jié)果:

Out[361]: 10.0

接下來對(duì)python函數(shù)做幾個(gè)補(bǔ)充,希望對(duì)大家在之后的學(xué)習(xí)中有所幫助:

1.函數(shù)基本組成

由“def”關(guān)鍵字作為定義頭:def(define)相當(dāng)于是一個(gè)定義胁孙,

格式為---------------------------------

def(arg1,arg2,...,argn):

? ? ? ? [function body]

? ? ? ? [return object]

跟絕大多數(shù)語言一樣唠倦,都是以

? ? ? ? ? ? ? ? 方法名(參數(shù))(方法體)[返回值(可有可無)]

構(gòu)成的称鳞。一般情況下在不賦值的情況下,會(huì)生成一個(gè)“匿名對(duì)象”牵敷,而一旦以

? ? ? ? ? ? ? ? ?place=方法名(參數(shù))

如上表達(dá)式出現(xiàn)的時(shí)候胡岔,python就會(huì)產(chǎn)生一個(gè)新的“p對(duì)象”法希,并把這個(gè)對(duì)象“賦值”給place枷餐。place在這里就成了一個(gè)變量,是一個(gè)特殊的對(duì)象苫亦,該對(duì)象具有指向“p對(duì)象”的指針毛肋。

2.把“函數(shù)”作為一個(gè)對(duì)象來使用,因此“函數(shù)”的編寫可以處于代碼模塊中的任何一個(gè)位置屋剑,這種寫法非常自由润匙,可以說秉承了python里一切都是對(duì)象的邏輯。舉個(gè)栗子:

test=True

if test:

? ? ? ? def funct1(a,b):

? ? ? ? return sum((a**2,b**2))**0.5

else:

? ? ? ? def funct2(a,b):

? ? ? ? return sum((a**2,b**2))**1

如果運(yùn)行這段代碼唉匾,根據(jù)test==true的邏輯孕讳,只有funct1被加載了,而funct2并未被加載(為被定義)巍膘,這樣大家可以靈活使用python函數(shù)厂财,編寫自己想要的結(jié)構(gòu)模式。

3.python的函數(shù)傳遞的是任何類型的對(duì)象“引用”峡懈,一旦對(duì)象在函數(shù)體中處于被操作修改璃饱,那么被傳遞進(jìn)去的源“對(duì)象”將被修改,甚至只要對(duì)象符合函數(shù)體中的計(jì)算邏輯運(yùn)算肪康,那么所傳遞的參數(shù)對(duì)象并不受數(shù)據(jù)類型(int荚恶,list,tuple磷支,dict谒撼,array)的限制,這個(gè)比Java函數(shù)定義寬容了許多雾狈,比如下面這段代碼:

def funct3(a,b):

? ? ? ? return a*b

if __name__='__main__':

? ? ? ? funct3(1,2) ? ? ? ? ? ?#Out[*]: 2

? ? ? ? funct3("c",2) ? ? ? ? #Out[*]: 'cc'

也就是說"*"操作不僅可以作為整數(shù)之間的“乘法”作用廓潜,也可以作為整數(shù)與字符串之間的合并操作,這個(gè)是一種python“多態(tài)”的行為箍邮。但這種“多態(tài)”與java中的“多態(tài)”卻不一樣茉帅。我們知道java是強(qiáng)類型語言,注定與python這種弱類型語言在語法上的規(guī)定有著較大的差異锭弊。

java的多態(tài)體現(xiàn)在下面三個(gè)條件上

? ? ? ? 1.繼承

? ? ? ? 2.重寫

? ? ? ? 3.父類引用指向子類對(duì)象

三種條件完備的情況下堪澎,才能稱為java“多態(tài)”,符合第1味滞、2條件的語言頂多叫做“基于對(duì)象”的語言樱蛤,而真正能夠?qū)崿F(xiàn)第三個(gè)條件的才能在真正意義上來講屬于“面向?qū)ο蟆钡恼Z言钮呀。而且第1、2兩點(diǎn)是第三點(diǎn)(最重要特性)的基礎(chǔ)昨凡,這樣才能出現(xiàn)“多態(tài)”的特征爽醋。

多態(tài)相關(guān)內(nèi)容看http://www.cnblogs.com/tanqiantot/archive/2013/03/27/3126818.html

而python中的“變量”首先是弱類型定義的,就在先天無法實(shí)現(xiàn)第三個(gè)條件便脊,即無法實(shí)現(xiàn)父類變量的聲明來指向子類的對(duì)象蚂四。那么即使這樣,難道python就不具有“多態(tài)”特性了嗎哪痰?讓我們繼續(xù)分析一下遂赠,我們知道python本身是可以實(shí)現(xiàn)繼承和重寫的,如下例子:

class Animal:

def __init__(self, name):

? ? ? ? self.name = name

def talk(self):

? ? ? ? raise NotImplementedError("Subclass must implement abstractmethod")

def eat(self):

? ? ? ? return '吃飯了'

class Cat(Animal):

def talk(self):

? ? ? ? return 'Meow!'

class Dog(Animal):

def talk(self):

? ? ? ? return 'Woof! Woof!'

if __name__='__main__':

? ? ? ? animals = [Cat('Missy'),Cat('Mr. Mistoffelees'),Dog('Lassie')]

? ? ? ? for animal in animals:

? ? ? ? ? ? ? ? ? print animal.name + ': ' + animal.talk()

? ? ? ? ? ? ? ? ? print animal.name + ': ' + animal.eat()

輸出結(jié)果:

Missy: Meow!

Missy:吃飯了

Mr. Mistoffelees: Meow!

Mr. Mistoffelees:吃飯了

Lassie: Woof! Woof!

Lassie:吃飯了

在Cat和Dog類中并沒有聲明eat函數(shù)晌杰,但是我們用Cat(父類)的方式實(shí)現(xiàn)了子類對(duì)父類的繼承跷睦,所以子類本身就具有了eat函數(shù)功能,就想父親需要吃飯一樣肋演,繼承的子類也需要有吃的動(dòng)作抑诸。

? ? 然而通過查看python的一些學(xué)習(xí)手冊(cè)和編程指南以及各位python大咖對(duì)python程序的設(shè)計(jì)心得方面的內(nèi)容,始終無法找到能夠滿足第三個(gè)條件特性代碼爹殊,有些人覺得python因?yàn)闊o法體現(xiàn)第三個(gè)條件而認(rèn)為python沒有“多態(tài)”的特性蜕乡,更有甚者認(rèn)為python缺乏多態(tài)特性而認(rèn)為python并不是一個(gè)面向?qū)ο蟮某绦蛟O(shè)計(jì)語言。

? ? 通過wiki對(duì)多態(tài)解釋來了解一下什么是多態(tài)(polymorphism)边灭,個(gè)人也傾向于wiki的解釋异希,其認(rèn)為對(duì)同一操作的行為(*,len())的合理性意義會(huì)根據(jù)傳遞的對(duì)象類型的不同來判斷的绒瘦〕撇荆或者用多態(tài)的原意:同一操作作用于不同對(duì)象,可以有不同的解釋惰帽,生成不一樣的結(jié)果憨降。這樣的描述同樣適用于java多態(tài)的第三個(gè)條件:即同一類(父類)引用不同的對(duì)象(不同子類,但是子類有相同方法)该酗,對(duì)父類的同一操作(方法)實(shí)質(zhì)是作用于不同對(duì)象授药,得到不一樣的結(jié)果。這視乎很繞呜魄,但是我們要理解”多態(tài)“的本質(zhì)悔叽,就比較容易。當(dāng)初定義”多態(tài)“爵嗅,其實(shí)是為“程序設(shè)計(jì)”作服務(wù)的娇澎,因?yàn)橛辛诉@個(gè)概念,才能很好地實(shí)現(xiàn)java中的父類引用指向子類對(duì)象的程序設(shè)計(jì)睹晒,才能理解并自己開發(fā)這樣的程序趟庄。同樣的括细,基于此,我們對(duì)python的”多態(tài)“理解也是為了python程序設(shè)計(jì)需求而提出的一種概念戚啥,我以三種不同的程序流來表示python的”多態(tài)“概念:

a) ? ?利用*號(hào)做運(yùn)算(就如我們剛才提到的勾股定理程序)奋单,我們可以輸入1*10得到10,也可以輸入“a”*3得到“aaa”猫十,前者做了類似于相加的運(yùn)算览濒,而后者做了相當(dāng)于拼接字符的運(yùn)算,雖然我們做了同樣的操作卻得到了不同地解釋或運(yùn)算方式炫彩,而這種不同依據(jù)傳入的對(duì)象的數(shù)據(jù)類型的不同而表現(xiàn)出不同的特性匾七。

b) ? ?利用len()函數(shù)分別對(duì)元組(1絮短,2江兢,3)和列表[1,2丁频,3]

? ? ? ?len((1,2,3)) ? ?#Out[6]: 3

? ? ? ?len([1,2,3]) ? ?#Out[7]: 3

其實(shí)質(zhì)是元組和列表本身就帶有__len__的特殊方法杉允,實(shí)現(xiàn)了不同的計(jì)算原則,而len函數(shù)(同一操作)調(diào)用了不同對(duì)象的__len__方法所存儲(chǔ)的值席里,實(shí)現(xiàn)了對(duì)不同數(shù)據(jù)類型對(duì)象的同一操作(讀仁辶住)的功能,而并沒有做計(jì)數(shù)的操作奖磁。這里我們也發(fā)現(xiàn)改基,一般使用內(nèi)置函數(shù)比自己編寫函數(shù)效率高的原因通過這個(gè)方法的理解可見一斑。

c)通過定義不同類來實(shí)現(xiàn)對(duì)不同對(duì)象做同一操作:(分別定義三個(gè)類咖为,每個(gè)類中都有eat函數(shù)秕狰,并通過循環(huán)對(duì)不同對(duì)象進(jìn)行操作)

class A:

? ? ? ? def eat(self):

? ? ? ? ? ? ? ?return "A"

class B:

? ? ? ? def eat(self):

? ? ? ? ? ? ? ? return "B"

class C:

? ? ? ? def eat(self):

? ? ? ? return "C"

if __name__='__main__':

? ? ? ? list1=[A(),B(),C()]

? ? ? ? [x.eat() for x in list1] ? ? ? ?#Out[11]: ['A', 'B', 'C']

如上三個(gè)例子充分地展現(xiàn)了python的“多態(tài)”針對(duì)的是“同一操作”可以對(duì)不同對(duì)象產(chǎn)生不一樣的結(jié)果,而java等語言的“操作”更偏向于正對(duì)“同一父類”使用相同操作實(shí)現(xiàn)不一樣的方式躁染,而本質(zhì)上這“同一父類”其實(shí)指向的是不同子類對(duì)象鸣哀。在這個(gè)層面上來說,python可以被認(rèn)為是具有“多態(tài)”特性的吞彤。

4.形參與實(shí)參的概念

一般計(jì)算機(jī)語言把定義函數(shù)或方法(被調(diào)用函數(shù)或方法)上(括號(hào)中所包含的定義)關(guān)鍵字

5.函數(shù)的參數(shù)*args與**kwargs的區(qū)別


后續(xù)更新吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末我衬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子饰恕,更是在濱河造成了極大的恐慌挠羔,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件埋嵌,死亡現(xiàn)場離奇詭異破加,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)莉恼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門拌喉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來速那,“玉大人,你說我怎么就攤上這事尿背《搜觯” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵田藐,是天一觀的道長荔烧。 經(jīng)常有香客問我,道長汽久,這世上最難降的妖魔是什么鹤竭? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮景醇,結(jié)果婚禮上臀稚,老公的妹妹穿的比我還像新娘。我一直安慰自己三痰,他們只是感情好吧寺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著散劫,像睡著了一般稚机。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上获搏,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天赖条,我揣著相機(jī)與錄音,去河邊找鬼常熙。 笑死纬乍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的症概。 我是一名探鬼主播蕾额,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼彼城!你這毒婦竟也來了诅蝶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤募壕,失蹤者是張志新(化名)和其女友劉穎调炬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舱馅,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缰泡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棘钞。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缠借,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宜猜,到底是詐尸還是另有隱情泼返,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布姨拥,位于F島的核電站绅喉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叫乌。R本人自食惡果不足惜柴罐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望憨奸。 院中可真熱鬧革屠,春花似錦、人聲如沸膀藐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽额各。三九已至,卻和暖如春吧恃,著一層夾襖步出監(jiān)牢的瞬間虾啦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國打工痕寓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留傲醉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓呻率,卻偏偏與公主長得像硬毕,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子礼仗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • # 第一優(yōu)先級(jí)規(guī)則聲明: # 除了夢(mèng)境吐咳,每一個(gè)意識(shí)主進(jìn)程都必須與一個(gè)身體參與的機(jī)械進(jìn)程相匹配,否則結(jié)束意識(shí)主進(jìn)程元践。...
    李洞BarryLi閱讀 3,860評(píng)論 0 1
  • 1.1面向?qū)ο?面向?qū)ο?object-oriented ;簡稱: OO)至今還沒有統(tǒng)一的概念 我這里把它定義為:...
    TENG書閱讀 567評(píng)論 0 0
  • http://python.jobbole.com/85231/ 關(guān)于專業(yè)技能寫完項(xiàng)目接著寫寫一名3年工作經(jīng)驗(yàn)的J...
    燕京博士閱讀 7,575評(píng)論 1 118
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法韭脊,類相關(guān)的語法,內(nèi)部類的語法单旁,繼承相關(guān)的語法沪羔,異常的語法,線程的語...
    子非魚_t_閱讀 31,631評(píng)論 18 399
  • 黑豆性平,味甘越除,有活血清熱节腐、補(bǔ)虛烏發(fā)、清熱解毒摘盆、祛風(fēng)的功效翼雀。明代李時(shí)珍在《本草綱目》中說:「黑豆入腎功多,故能治水...
    平原女王閱讀 426評(píng)論 0 1