有时候我喜欢为一个对象编写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
答案 0 :(得分:7)
请改用lazy property。吸毒者是so 1990's。
答案 1 :(得分:3)
不是每次都进行明确的“hasattr”测试,而是让Python运行时为你做。在类中定义__getattr__
,仅在引用未定义属性时调用。
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}进行__getattr__
测试,但是对于像内省或内省这样的内容,您无法将{a'作为dir
中的属性的可见性IDE自动完成。
答案 2 :(得分:1)
您可以在Python中使用完全相同的模式。你好像担心是否必须一直做my_object.get_foo()
是Pythonic。值得庆幸的是,Python为您提供了一个很好的工具,可以使用properties:
class my_class(object):
@property
def foo(self):
# calculate if needed
return self._foo
这使得您可以使用使用作为属性,即使它是作为函数实现的。即,用户将执行my_object.foo
,而不关心它在幕后运行功能。
要注意的另一件事是Python惯例说私有属性拼写_foo
而不是mFoo
。
答案 3 :(得分:1)
我会做这样的事情:
@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