11

可调用对象的目的是什么?他们解决了什么问题?

4

3 回答 3

13

在 Python 中可以调用多种对象,它们可以用于多种用途:

  • 函数是可调用的,并且它们可能带有来自外部函数的“闭包”
  • 类是可调用的,调用一个类可以获得该类的一个实例
  • 方法是可调用的,用于特定于实例的类似函数的行为
  • staticmethods 和 classmethods 是可调用的,对于类似方法的功能,当功能在某种意义上与“整个类”相关时(staticmethods 的有用性是值得怀疑的,因为 classmethod 也可以这样做;-)
  • 生成器是可调用的,调用生成器会得到一个迭代器对象
  • 最后,这可能就是您要问的具体问题(没有意识到以上所有内容也是对象......!!!),您可以编写一个实例可调用的类:这通常是最简单的调用方式更新实例的状态并依赖它(尽管具有合适闭包和绑定方法的函数提供了替代方案,但当您需要执行调用其他一些特定操作时,可调用实例是一种方法同一个对象:例如,您希望能够调用但也应用索引的对象最好是可调用和可索引的类的实例;-)。

Python 的标准库提供了大量“他们解决的问题”的示例,其中包含我上面提到的每种特定类型的许多案例。

于 2010-03-12T23:53:37.790 回答
9

它们接受参数并根据这些参数返回结果。

调用只是函数的抽象形式,或者是定义对象像函数一样工作的接口(即接受参数)。

由于函数是第一类对象,因此函数显然是可调用对象。如果您谈论的是__call__方法,这只是您可以重载自定义对象行为的众多特殊方法之一,例如用于算术运算或定义调用对象时会发生什么。

使用这种方法的一个想法是拥有某种自身创建其他对象的工厂对象。

于 2010-03-12T23:43:58.557 回答
2

在某些区域,尤其是在“函数调用函数的函数”中,对象允许较少的嵌套。

考虑制作一个经典的装饰器,在调用函数之前检查授权级别。使用它很清楚:

@check_authorization(level="Manager")
def update_price(Item, new_price):...

您可以将其作为嵌套函数执行:

def check_authorization(level):
     def take_params(function):
         def concrete(*args, **kwargs):
             if user_level_greater_than(level):
                 return function(*args, 
                     **kwargs)
             return None
         return concrete
     return take_params

或者你可以把它作为一个类,这可能更清楚:

  class check_authorization(object):
      def __init__(level):
         self.level = level
      def __call__(function):
          self.function = function
          return self.dec
      def dec(self, *args, **kwargs):
          if user_level_greater_than(self.level):
             return self.function(*args,v**kwargs)
          return None

许多人会发现这种扁平化方法更清晰。当然,我相信作弊,因为我喜欢正确的签名和元数据:

from dectools.dectools import make_call_if

@make_call_if
def check_authorization(function, arg, kwargs, level):
    return user_level_greater_than(level)

可调用对象是一种适用于某些已知应用程序的工具,也可能适用于现实生活中遇到的奇怪问题。

于 2010-03-13T00:00:56.623 回答