【问题标题】:Call a method as property or function?将方法调用为属性或函数?
【发布时间】:2017-03-20 08:57:53
【问题描述】:

是否可以有一个方法并将其作为函数或属性调用?

def Foo:
  def bar(self,x=1,y=2):
    return x+y

foo=Foo()
foo.bar #should return 3
foo.bar(4,5) #should return 9

这似乎是不可能的,因为:

  • foo.bar 将调用__getattribute__;如果它是一个描述符,__get__ 将从 __getattribute__ 中被调用,这意味着 bar() 甚至在返回给调用者之前就被评估了
  • 如果一个属性是一个函数,它只返回一个函数,然后 () 被应用到那个函数
  • 因此,如果调用者正在调用属性或函数,则无法在 __getattribute__ 中检测到
  • 因此,双重行为是不可能的

我想要实现的是(伪代码):

def __getattribute__():
   if len(args)>1: return function
   else: return property

但是因为args没有传递给__getattribute__或者__get__,所以我不知道在哪里以及如何在属性和函数之间切换。

【问题讨论】:

  • 问题确实是Foo不知道你要对属性做什么:调用部分没有传达给Foo...
  • 除非...如果属性返回的结果具有 .__call__ 方法并且调用者可以选择保留结果或调用函数...这很糟糕、丑陋且值得怀疑...但是。 ..也许
  • 你可以——在某种程度上——生成一个计算默认结果的代理元素,并将__call__附加到结果中。问题是,如果函数有副作用,这些将被“解雇”...
  • 还有其他事情发生,因为 setter 根本不调用 getattribute!它们是如何工作的!?

标签: python properties


【解决方案1】:

只需使用:

foo.bar() # 3
foo.bar(4, 5) # 9

如果你坚持,这是一个非常丑陋、无法使用的解决方案,它实际上会返回 3 和 9。适用于 python 3.6。不要使用它:

class CallableInt(int):
    """But, why????"""
    def __call__(self, x, y):
        return x + y


class Foo:
    @property
    def bar(self):
        return CallableInt(3)


foo = Foo()
print(foo.bar)
print(foo.bar(4, 5))

【讨论】:

  • 确实,这行得通,只有两个问题(同一枚硬币的两个面):1)总是会评估属性 2)如果属性也调用 self 作为函数,这根本行不通(但随后我需要详细说明为什么要理解它;-))
猜你喜欢
  • 1970-01-01
  • 2022-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
相关资源
最近更新 更多