【问题标题】:Why do we have callable objects in python?为什么我们在 python 中有可调用对象?
【发布时间】:2011-01-27 01:15:56
【问题描述】:

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

【问题讨论】:

标签: python callable


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    为什么要使用它的一个想法是让某种工厂对象本身创建其他对象。

    【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-01-30
      • 2013-08-06
      • 2014-04-11
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 2018-11-24
      • 2023-01-25
      • 2023-03-03
      相关资源
      最近更新 更多