在Python中,函数是第一类对象吗?

6 投票
5 回答
1988 浏览
提问于 2025-04-18 02:32

我正在学习一个关于Python的教程。这个教程在解释Python中的函数是“第一类对象”。

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

print(issubclass(foo.__class__,object))

我运行上面的代码得到的输出是

<type 'function'>
True

这个程序是用来展示Python中的函数是第一类对象吗?我有以下几个问题。

  1. 上面的代码是怎么证明函数是第一类对象的?
  2. 第一类对象有什么特点?
  3. function.__class__是什么意思?它返回一个元组<type,function>,这有什么用呢?

5 个回答

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

方法其实就是一个类里面的函数,但这个概念也可以用在类外的函数上。函数(作为对象)被放在一个数据结构里,然后传递给另一个对象。

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://stackoverflow.com/a/245208/3248346

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

  • 可以用一个匿名的字面值表示
  • 可以存储在变量中
  • 可以存储在数据结构中
  • 有一个内在的身份(不依赖于任何给定的名称)
  • 可以和其他对象进行相等比较
  • 可以作为参数传递给过程或函数
  • 可以作为过程或函数的返回结果
  • 可以在运行时构造
  • 可以被打印出来
  • 可以被读取
  • 可以在分布式进程之间传输
  • 可以存储在运行进程之外
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__可以告诉你你所拥有的对象是什么类型。例如,如果你在Python中定义了一个列表对象:a = [1,2,3],那么a.__class__的结果将是<type 'list'>。如果你有一个日期时间对象(通过from datetime import datetime导入,然后d = datetime.now()),那么d这个实例的类型将是<type 'datetime.datetime'>。他们只是想说明在Python中,函数并不是一个全新的概念。它只是一个普通的对象,类型是<type 'function'>

12

这是Guido在他的博客中关于“第一类对象”的说法:

我设计Python的一个目标就是让所有对象都成为“第一类”。我的意思是,我希望在这个语言中所有可以被命名的对象(比如整数、字符串、函数、类、模块、方法等等)都享有同等的地位。也就是说,它们可以被赋值给变量,可以放在列表中,可以存储在字典里,可以作为参数传递,等等。

这篇博客文章值得一读。

在你发布的例子中,教程可能想表达的是,第一类对象通常是“对象”类的子类。

撰写回答