Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中实现惰性getter的正确模式是什么?_Python_Design Patterns_Getter - Fatal编程技术网

Python中实现惰性getter的正确模式是什么?

Python中实现惰性getter的正确模式是什么?,python,design-patterns,getter,Python,Design Patterns,Getter,有时我喜欢为对象编写getter属性,这样在第一次调用它们时,繁重的工作只执行一次,并且保存该值并在以后的调用中返回。在objective-c中,我将使用ivar或静态变量来保存该值。比如: - (id)foo { if ( _foo == nil ) { _foo = // hard work to figure out foo } return _foo } 这种模式在Python中是否适用,或者是否有一种更被接受的方法?到目前为止,我有基本

有时我喜欢为对象编写getter属性,这样在第一次调用它们时,繁重的工作只执行一次,并且保存该值并在以后的调用中返回。在objective-c中,我将使用ivar或静态变量来保存该值。比如:

- (id)foo
{
    if ( _foo == nil )
    {
        _foo = // hard work to figure out foo
    }
    return _foo
}
这种模式在Python中是否适用,或者是否有一种更被接受的方法?到目前为止,我有基本相同的东西。我不喜欢我的解决方案,因为我的对象被值和这些值的getter弄得乱七八糟:

def foo(self):
    if not hasattr(self, "mFoo":
        self.mFoo = # heavy lifting to compute foo
    return self.mFoo

改用a。getter是。您可以在Python中使用完全相同的模式。您似乎担心是否必须始终执行
my\u object.get\u foo()
是Pythonic。谢天谢地,Python在这里为您提供了一个很好的工具,其形式如下:

这使您可以将某些内容用作属性,即使它是作为函数实现的。也就是说,用户将执行my_object.foo
,而不关心它在幕后运行函数


另一件需要注意的事情是,Python约定将私有属性拼写为
\u foo
,而不是
mFoo

我会这样做:

@property
def foo(self):
    return self._foo_value if hasattr(self, '_foo_value') else calculate_foo()

def calculate_foo(self):
    self._foo_value = # heavy foo calculation
    return self._foo_value
现在,无论是否已计算,您都可以使用以下方法访问“foo”:

object.foo

不要每次都进行显式的“hasattr”测试,而是让Python运行时为您进行测试。在类中定义
\uuuu getattr\uuuu
,只有在引用未定义的属性时才会调用该类

class Sth(object):
    @property
    def a(self):
        print "property a"
        return self._a

    def _a_compute(self):
        # put expensive computation code here
        print "_a_compute"
        return 1000

    def __getattr__(self, attr):
        print "__getattr__"
        if attr == '_a':
            self._a = self._a_compute()
            return self._a


ss = Sth()
print "first time"
print ss.a
print
print "second time"
print ss.a
打印以下内容:

first time
property a
__getattr__
_a_compute
1000

second time
property a
1000

您可以省略属性,直接对“a”进行
\uuu getattr\uuuu
测试,但是对于内省或IDE自动完成之类的事情,您将无法将“a”作为
dir
中的属性进行可见性。

谢谢,起初我对getattr和getattribute感到困惑。不过这是有道理的。@darren确实没有,这就是我在午夜错误的一边发布的结果。:)我现在已经修好了。
first time
property a
__getattr__
_a_compute
1000

second time
property a
1000