Python中万物皆对象,学会使用函数作为对象(译)

就像str,int,和dict一样,函数在Python中也是对象,掌握了这个特点可以写出更多灵活的代码

你大概已经听过,Python作为一种流行的面向对象语言,所有的都是对象。当我们谈到对象,经常是把对象指向一种数据集合,通常是作为属性,这个对象是某些预先定义好的函数,可以用于更新数据或者与其他对象交换数据。

数据类型

所有的数据类型例如数值,字符串,列表,字典在Python中都是对象。用一个实际的例子,你可以把他想象成实实在在的数据盒子。在大小方面,有些盒子较小比如intboolstr类型的数据,另外一些盒子比较大如listdict,他们的大小差别表现在计算机需要多少内存存储这些数据。除此之外,这些盒子还有其他的特征,例如颜色和材质,你可以把这些联想成他们的数据类型不同。

作为对象他们都有以下通用的含义和功能:

  • 可以赋值给变量
  • 可以作为函数的参数
  • 可以作为函数的返回值
  • 与别的对象关联,并作为其中的一部分
# 赋值给变量
a = 5

# 作为函数的参数
def add_two(a):
    return a + 2
add_two(6)

# 作为函数的返回值
def is_even(a):
    return 'even' if a % 2 == 0 else 'odd'
is_even(745)

# 与别的对象关联,并作为其中的一部分
(True, 7, 8)

在上面的代码中,你看到了Python对象的这些含义,比如intstring。甚至你不太清楚Python代码或者其他编程语言,理解起来也不是很难对吧?

然而有人说函数也可以作为对象,这点可能会有些疑惑。接下来我们一起看看为什么这么说。

函数作为对象

在我们开始讨论函数作为对象之前,让我们回顾一下函数是什么?函数是一个命名的代码块,需要0个或多个输入参数,运行以后会返回输出值

下面有一个简单的例子,组成函数的部分高亮出来了。

# 定义一个函数名为 add_two

# 函数需要一个整数作为参数
def add_two(a): 
# 这个函数把2加到输入参数上
    b = a + 2
# 函数返回求和作为输出
    return b

在上面文中,我们提到的Python数据对象的四个通用的功能,我将用几个例子一一说明函数如何具备这些功能。

赋值给变量

在下面代码中,我创建了一个叫greeting()的函数,赋值给变量say_hello,调用say_hello的输出与greeting输出一样。

def greeting(name):
    hello = 'Hello, ' + name + '!'
    return hello

print(greeting('John'))
# Hello, John!

say_hello = greeting

say_hello('Mike')
# Hello, Mike!

greetingsay_hello在内存中指向相同的对象。例如,如果你检查他们的地址,他们会有相同的输出。如果我们删除函数greeting(),这个greeting指向的函数将变成未定义,而删除操作并不会影响say_hello函数。因此,一个重要的概念是指向函数的变量和实际存储在内存中的对象是不同的

print(id(greeting))
# 4606507480
print(id(say_hello))
# 4606507480

del greeting

say_hello('Jennifer')
# Hello, Jennifer

greeting('Rachel')
# NameError: name 'greeting' is not defined

把函数作为另外函数的参数

由于函数是一个对象,我们可以把函数作为另一个函数的参数。下面的例子,我创建了3个函数:combine_two_numbers(), add_two_numbers() , multiply_two_numbers() ,后面两个函数分别是求和和求积,第一个函数combine_two_numbers()与你通常见到的函数不同,这个函数接受一个函数和一个元组作为参数。在下面的例子中你可以发现,我们将add_two_numbers , multiply_two_numbers作为参数,分别计算这个数组的和与乘积。

def combine_two_numbers(how_to, numbers):
    return how_to(numbers)

def add_two_numbers(numbers):
    a, b = numbers
    return a + b

def multiply_two_numbers(numbers):
    a, b = numbers
    return a * b

combine_two_numbers(add_two_numbers, (3, 5))
# 8

combine_two_numbers(multiply_two_numbers, (4, 6))
# 24

函数作为返回值

另外一个有意思的特点就是,Python函数可以作为另外函数的返回值。让我们看下面的例子。我写了一个函数add_number_creator(),他返回一个函数,这个函数是把一个数加到一个整型参数上。两个函数add_three()add_five() 被这个函数add_number_creator()创建出来。这两个函数分别把3和5加到整型参数上。

def add_number_creator(number):
    def add_number(a):
        return a + number
    return add_number

add_three = add_number_creator(3)
add_five = add_number_creator(5)

add_three(5)
# 8

add_five(100)
# 105

函数组成别的对象

由于函数是一个对象,我们可以创建一个函数列表,所有函数变成列表对象中的元素。接着上面的例子,我们用add_number_creator()创建3个函数,把0,1,2加到整型变量上。你可以看到我们可以遍历列表中的函数,就像操作列表中整数或字符一样。

add_functions = [add_number_creator(0), add_number_creator(1), add_number_creator(2)]

for i, func in enumerate(add_functions):
    a = 8
    print('a is 8, adding '+ str(i) + ' is' + str(func(a)))
    
# a is 8, adding 0 is 8
# a is 8, adding 1 is 9
# a is 8, adding 2 is 10

总结

这篇文章告诉你,在Python中函数就像别的对象一样,既可以赋值给变量也可以用于函数中。上文中一些简单的例子说明了这个问题,如果你碰到更多复杂的情况,你可以应用相同的规则,把函数当成普通的对象在你的Python代码中使用。

大家可以关注我的微信公众号:数学编程

原文:Everything Is an Object in Python — Learn to Use Functions as Objects

注:本文是作者第一篇译文,鉴于作者英文水平欠缺,文中多处翻译不太流畅,请见谅

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

推荐阅读更多精彩内容