Python中实现惰性getter的正确模式是什么?
有时我喜欢为对象编写getter属性,这样在第一次调用它们时,繁重的工作只执行一次,并且保存该值并在以后的调用中返回。在objective-c中,我将使用ivar或静态变量来保存该值。比如: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中是否适用,或者是否有一种更被接受的方法?到目前为止,我有基本
- (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