python函数引发的多态思考

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

"""

Created on Fri May 20 01:48:27 2017

@author: zhangll

"""

    函数也是p对象,学过java的同学都知道“方法”的概念,“方法”在java的表现中是指一段程序流程的封装,而python函数可以在这个概念上与java的“方法”概念相呼应。但是java

方法调用的参数分为实参和形参,java中并没有传递“方法”参数这一说法,一般是通过

包装好的类、变量作为参数来实现程序的转移的。在python中却可以利用“函数”作为参数来传递的,可以说python把“函数”作为一个“对象”来考虑的。如下:我们看一个简单的例子:

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函数作为一个参数传入pythagoreandouble(计算勾股的两倍)函数中,作为一个函数来使用,结果为,扩充了一倍,结果:

Out[361]: 10.0

接下来对python函数做几个补充,希望对大家在之后的学习中有所帮助:

1.函数基本组成

由“def”关键字作为定义头:def(define)相当于是一个定义,

格式为---------------------------------

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

        [function body]

        [return object]

跟绝大多数语言一样,都是以

                方法名(参数)(方法体)[返回值(可有可无)]

构成的。一般情况下在不赋值的情况下,会生成一个“匿名对象”,而一旦以

                 place=方法名(参数)

如上表达式出现的时候,python就会产生一个新的“p对象”,并把这个对象“赋值”给place。place在这里就成了一个变量,是一个特殊的对象,该对象具有指向“p对象”的指针。

2.把“函数”作为一个对象来使用,因此“函数”的编写可以处于代码模块中的任何一个位置,这种写法非常自由,可以说秉承了python里一切都是对象的逻辑。举个栗子:

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

如果运行这段代码,根据test==true的逻辑,只有funct1被加载了,而funct2并未被加载(为被定义),这样大家可以灵活使用python函数,编写自己想要的结构模式。

3.python的函数传递的是任何类型的对象“引用”,一旦对象在函数体中处于被操作修改,那么被传递进去的源“对象”将被修改,甚至只要对象符合函数体中的计算逻辑运算,那么所传递的参数对象并不受数据类型(int,list,tuple,dict,array)的限制,这个比Java函数定义宽容了许多,比如下面这段代码:

def funct3(a,b):

        return a*b

if __name__='__main__':

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

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

也就是说"*"操作不仅可以作为整数之间的“乘法”作用,也可以作为整数与字符串之间的合并操作,这个是一种python“多态”的行为。但这种“多态”与java中的“多态”却不一样。我们知道java是强类型语言,注定与python这种弱类型语言在语法上的规定有着较大的差异。

java的多态体现在下面三个条件上

        1.继承

        2.重写

        3.父类引用指向子类对象

三种条件完备的情况下,才能称为java“多态”,符合第1、2条件的语言顶多叫做“基于对象”的语言,而真正能够实现第三个条件的才能在真正意义上来讲属于“面向对象”的语言。而且第1、2两点是第三点(最重要特性)的基础,这样才能出现“多态”的特征。

多态相关内容看http://www.cnblogs.com/tanqiantot/archive/2013/03/27/3126818.html

而python中的“变量”首先是弱类型定义的,就在先天无法实现第三个条件,即无法实现父类变量的声明来指向子类的对象。那么即使这样,难道python就不具有“多态”特性了吗?让我们继续分析一下,我们知道python本身是可以实现继承和重写的,如下例子:

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()

输出结果:

Missy: Meow!

Missy:吃饭了

Mr. Mistoffelees: Meow!

Mr. Mistoffelees:吃饭了

Lassie: Woof! Woof!

Lassie:吃饭了

在Cat和Dog类中并没有声明eat函数,但是我们用Cat(父类)的方式实现了子类对父类的继承,所以子类本身就具有了eat函数功能,就想父亲需要吃饭一样,继承的子类也需要有吃的动作。

    然而通过查看python的一些学习手册和编程指南以及各位python大咖对python程序的设计心得方面的内容,始终无法找到能够满足第三个条件特性代码,有些人觉得python因为无法体现第三个条件而认为python没有“多态”的特性,更有甚者认为python缺乏多态特性而认为python并不是一个面向对象的程序设计语言。

    通过wiki对多态解释来了解一下什么是多态(polymorphism),个人也倾向于wiki的解释,其认为对同一操作的行为(*,len())的合理性意义会根据传递的对象类型的不同来判断的。或者用多态的原意:同一操作作用于不同对象,可以有不同的解释,生成不一样的结果。这样的描述同样适用于java多态的第三个条件:即同一类(父类)引用不同的对象(不同子类,但是子类有相同方法),对父类的同一操作(方法)实质是作用于不同对象,得到不一样的结果。这视乎很绕,但是我们要理解”多态“的本质,就比较容易。当初定义”多态“,其实是为“程序设计”作服务的,因为有了这个概念,才能很好地实现java中的父类引用指向子类对象的程序设计,才能理解并自己开发这样的程序。同样的,基于此,我们对python的”多态“理解也是为了python程序设计需求而提出的一种概念,我以三种不同的程序流来表示python的”多态“概念:

a)    利用*号做运算(就如我们刚才提到的勾股定理程序),我们可以输入1*10得到10,也可以输入“a”*3得到“aaa”,前者做了类似于相加的运算,而后者做了相当于拼接字符的运算,虽然我们做了同样的操作却得到了不同地解释或运算方式,而这种不同依据传入的对象的数据类型的不同而表现出不同的特性。

b)    利用len()函数分别对元组(1,2,3)和列表[1,2,3]

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

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

其实质是元组和列表本身就带有__len__的特殊方法,实现了不同的计算原则,而len函数(同一操作)调用了不同对象的__len__方法所存储的值,实现了对不同数据类型对象的同一操作(读取)的功能,而并没有做计数的操作。这里我们也发现,一般使用内置函数比自己编写函数效率高的原因通过这个方法的理解可见一斑。

c)通过定义不同类来实现对不同对象做同一操作:(分别定义三个类,每个类中都有eat函数,并通过循环对不同对象进行操作)

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']

如上三个例子充分地展现了python的“多态”针对的是“同一操作”可以对不同对象产生不一样的结果,而java等语言的“操作”更偏向于正对“同一父类”使用相同操作实现不一样的方式,而本质上这“同一父类”其实指向的是不同子类对象。在这个层面上来说,python可以被认为是具有“多态”特性的。

4.形参与实参的概念

一般计算机语言把定义函数或方法(被调用函数或方法)上(括号中所包含的定义)关键字

5.函数的参数*args与**kwargs的区别


后续更新吧

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

推荐阅读更多精彩内容

  • # 第一优先级规则声明: # 除了梦境,每一个意识主进程都必须与一个身体参与的机械进程相匹配,否则结束意识主进程。...
    李洞BarryLi阅读 3,853评论 0 1
  • 1.1面向对象 面向对象(object-oriented ;简称: OO)至今还没有统一的概念 我这里把它定义为:...
    TENG书阅读 565评论 0 0
  • http://python.jobbole.com/85231/ 关于专业技能写完项目接着写写一名3年工作经验的J...
    燕京博士阅读 7,566评论 1 118
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,612评论 18 399
  • 黑豆性平,味甘,有活血清热、补虚乌发、清热解毒、祛风的功效。明代李时珍在《本草纲目》中说:「黑豆入肾功多,故能治水...
    平原女王阅读 422评论 0 1