Python中的函数是一等对象吗?

5

我正在学习有关Python的教程。它解释了在Python中函数是一等公民对象的概念。

def foo():
        pass
print(foo.__class__)

print(issubclass(foo.__class__,object))

我得到的上述代码的输出是:
<type 'function'>
True

这个程序旨在证明在Python中,函数是一等对象。我的问题如下:

  1. 上面的代码如何证明函数是一等对象?
  2. 一等对象的属性是什么?
  3. function.__class__表示什么?它返回一个元组<type, function>,这没有什么意义?

3
它具有类别这一事实使其成为一种一流对象。 - Wolph
Python 中的所有东西都有 class 成员吗?而输出 <type,'function> 表示它是一个函数对象的类型吗? - liv2hak
5个回答

12

以下是Guido在他的博客中关于一等对象的说法:

Python的一个目标就是使所有对象都成为“一等”。这意味着,语言中可以命名的所有对象(例如整数、字符串、函数、类、模块、方法等)具有平等的地位。也就是说,它们可以被分配给变量、放置在列表中、存储在字典中、作为参数传递等。

整篇博客文章都值得一读。

在您发布的示例中,该教程可能正在强调一等对象通常是“object”类的后代。


7

一等公民指的是函数可以被视为值——也就是说,您可以将它们分配给变量,从函数中返回它们,并将它们作为参数传递。因此,您可以编写以下代码:

>>> def say_hi():
        print "hi"
>>> def say_bye():
        print "bye"
>>> f = say_hi
>>> f()
hi
>>> f = say_bye
>>> f()
bye

这是有用的,因为您现在可以像普通变量一样将函数分配给变量:

>>> for f in (say_hi, say_bye):
        f()
hi
bye

或者编写高阶函数(接受函数作为参数):
>>> def call_func_n_times(f, n):
        for i in range(n):
            f()
>>> call_func_n_times(say_hi, 3)
hi
hi
hi
>>> call_func_n_times(say_bye, 2)
bye
bye

关于Python中的__class__告诉你所拥有的对象的type。例如,如果在Python中定义列表对象:a = [1,2,3],那么a.__class__将是<type 'list'>。如果你有一个日期时间(from datetime import datetime,然后d = datetime.now()),那么d实例的类型将是<type 'datetime.datetime'>。它们只是在展示Python中函数并不是全新的概念,它只是一个普通的<type 'function'>对象。

2
关于您的第三个问题,<type 'function'> 不是元组。Python 中元组的表示方法是 (a,b),而不是尖括号。 foo.__class__ 返回一个类对象,也就是一个代表 foo 所属类的对象;类对象在解释器中会产生描述性字符串,这里告诉你 foo 的类是名为 'function'type。(在现代 Python 中,类和类型基本上是相同的。)
这并不意味着太多东西,和其他任何对象一样,函数都有一个类型:
>>> x = 1
>>> x.__class__
<type 'int'>

>>> y = "bar"
>>> y.__class__
<type 'str'>

>>> def foo(): pass
... 
>>> foo.__class__
<type 'function'>

2

你证明了函数是一等对象,因为你可以将foo作为参数传递给方法。

一等对象的属性在这篇文章中很好地总结了:https://dev59.com/8HVC5IYBdhLWcg3wlyMo#245208

根据语言的不同,这可能意味着:

  • 可以表示为匿名文字值
  • 可存储在变量中
  • 可存储在数据结构中
  • 具有内在身份(与任何给定名称无关)
  • 可与其他实体比较相等
  • 可作为过程/函数的参数传递
  • 可作为过程/函数的结果返回
  • 可在运行时构建
  • 可打印
  • 可读取
  • 可在分布式进程之间传输
  • 可在运行进程之外存储

我们在谈论哪个方法?是print吗?我们将foo.__class__传递给print,而不是foo本身。据我所知,foo.__class__是foo的属性(或成员变量)? - liv2hak

1
关于您对 @I.K.答案的评论,下面的 f_at_2() 是指该方法。
def f_at_2(f):
    return f(2)

def foo(n):
    return n ** n

def bar(n):
    return n * n

def baz(n):
    return n / 2

funcs = [foo, bar, baz]

for f in funcs:
    print f.func_name, f_at_2(f)

...

>>> 
foo 4
bar 4
baz 1
>>> 

方法是类中的一个函数,但这个概念也适用于函数(在类之外)。这些函数(作为对象)包含在数据结构中并传递给另一个对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接