【问题标题】:Making a property method callable使属性方法可调用
【发布时间】:2018-09-05 08:45:59
【问题描述】:

我有一个带有属性方法的类:

class SomeClass(object):

    @property
    def some_method(self):

        return True

我想调用 some_method 并将其存储为表达式。

例如:

some_expr = SomeClass().some_method

不应将值 True 存储在 some_expr 中;而是应该存储表达式 SomeClass().some_method 以便它可以调用。

我该如何实现?

【问题讨论】:

  • 为什么?它总是评估为True,除非你真的搞砸了。
  • 另外,我觉得最简单的方法是不使用属性。我的意思是,属性的​​全部意义在于您不必调用它,但它可以动态生成并且看起来像一个成员 var。我想,再一次,你为什么要这样做?

标签: python python-2.7 methods python-decorators


【解决方案1】:

这是使属性可调用的一种方法:

代码:

class CallableProperty(object):

    def __init__(self, instance, name):
        self.instance = instance
        self.name = name

    def __call__(self):
        return getattr(self.instance, self.name)

测试代码:

class SomeClass(object):

    @property
    def some_method(self):
        return True

x = SomeClass()
y = CallableProperty(x, 'some_method')

print(y())

结果:

True

【讨论】:

    【解决方案2】:

    一个简单的方法是这样做:

    call_prop = lambda: SomeClass().some_prop
    

    但你没有充分的理由需要这个。

    【讨论】:

      【解决方案3】:

      所以-“属性”是一个描述符。这意味着它是一个定义了 get 方法的对象(python 中的一切都是对象)。当你访问一个类属性时,如果那里的对象有 get 方法,python 会帮你调用它。该装饰器采用提供的函数并将其转换为分配给类的对象上的 get(self) 方法。太好了!

      如果出于某种原因,您实际上希望调用该函数而不是调用该函数,则可以通过类字典访问它...

      f = SomeClass.__dict__['some_method'].__get__ 如果“self”方法无关紧要,哪一个允许你做f(1)

      如果你真的想变得花哨,你可以做new_f = functools.partial(f, SomeClass()) 那么……new_f() == True

      真的很好奇你为什么要这样做;)

      【讨论】:

        【解决方案4】:

        注意,您本质上是想在属性实例上使用 .__get__ 可调用的。但是,这需要一个实例作为第一个参数,因此您可以部分应用一些实例:

        In [6]: class SomeClass(object):
           ...:
           ...:     @property
           ...:     def some_method(self):
           ...:
           ...:         return True
           ...:
        
        In [7]: from functools import partial
        

        然后是这样的:

        In [9]: some_exp = partial(SomeClass.some_method.__get__, SomeClass())
        
        In [10]: some_exp()
        Out[10]: True
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-27
          • 2012-10-24
          • 1970-01-01
          • 2016-09-04
          • 2011-07-19
          • 1970-01-01
          • 2015-12-03
          • 2011-05-13
          相关资源
          最近更新 更多