将 class 属性别名为函数
Aliasing a class attribute to a function
是否可以做类似下面的事情:
class foo():
def bar(): # a method that doesn't take any args
# slow calculation
return somefloat
b = bar # bar is a function but b just gives you the float attribute
f = foo()
f.b # returns somefloat but doesn't require the empty parentheses
我希望这个例子很清楚,因为我不太清楚我想做的事情的术语是什么。我的基本目标是为没有参数的方法删除一堆括号,以使代码更清晰易读。
该函数速度慢且很少使用,因此实时计算比提前计算一次并存储变量更容易。
这可能吗?这是好的做法吗?有没有更好的方法?
b = bar
显然不行。但是 属性 最简单的 "doesn't require the empty parentheses" 问你:
b = property(bar)
现在每次访问 f.b
都会调用 f.bar()
"behind the curtains"。
然而,这意味着如果您访问 f.b
两次,f.bar()
将被调用两次,重复计算。如果重复是无关紧要的(即,如果对同一个对象的重复计算结果没有改变)你可以做得更好("caching" 的结果在 f.b
中永远一旦它第一次被计算) - 一些喜欢:
class foo(object):
def bar(self): # a method that doesn't take any args
# slow calculation
return somefloat
def _cache_bar(self):
result = self.bar()
setattr(self, 'b', result)
return result
b = property(_cache_bar)
实现这个的标准方法是使用property
, which is a decorator:
class Foo():
@property
def bar(self):
# slow calculation
return somefloat
f = Foo()
f.bar # returns somefloat but doesn't require the empty parentheses
有两点需要注意:
您仍然需要像往常一样在方法签名中使用 self
,因为有时您需要引用例如self.some_attribute
方法内部。如您所见,这根本不会影响 属性 的 use。
没有必要用 f.bar()
方法和 f.b
属性 让你的 API 变得混乱 - 最好决定什么最有效对你的 class 有意义,而不是提供一堆不同的方法来做同样的事情。
通过静态方法,但需要通过括号调用。
class foo(object):
@staticmethod
def bar(): # a method that doesn't take any args
# slow calculation
return "abc"
b = bar # bar is a function but b just gives you the float attribute
f = foo()
print f.b()
输出:
$ python test.py
abc
是否可以做类似下面的事情:
class foo():
def bar(): # a method that doesn't take any args
# slow calculation
return somefloat
b = bar # bar is a function but b just gives you the float attribute
f = foo()
f.b # returns somefloat but doesn't require the empty parentheses
我希望这个例子很清楚,因为我不太清楚我想做的事情的术语是什么。我的基本目标是为没有参数的方法删除一堆括号,以使代码更清晰易读。
该函数速度慢且很少使用,因此实时计算比提前计算一次并存储变量更容易。
这可能吗?这是好的做法吗?有没有更好的方法?
b = bar
显然不行。但是 属性 最简单的 "doesn't require the empty parentheses" 问你:
b = property(bar)
现在每次访问 f.b
都会调用 f.bar()
"behind the curtains"。
然而,这意味着如果您访问 f.b
两次,f.bar()
将被调用两次,重复计算。如果重复是无关紧要的(即,如果对同一个对象的重复计算结果没有改变)你可以做得更好("caching" 的结果在 f.b
中永远一旦它第一次被计算) - 一些喜欢:
class foo(object):
def bar(self): # a method that doesn't take any args
# slow calculation
return somefloat
def _cache_bar(self):
result = self.bar()
setattr(self, 'b', result)
return result
b = property(_cache_bar)
实现这个的标准方法是使用property
, which is a decorator:
class Foo():
@property
def bar(self):
# slow calculation
return somefloat
f = Foo()
f.bar # returns somefloat but doesn't require the empty parentheses
有两点需要注意:
您仍然需要像往常一样在方法签名中使用
self
,因为有时您需要引用例如self.some_attribute
方法内部。如您所见,这根本不会影响 属性 的 use。没有必要用
f.bar()
方法和f.b
属性 让你的 API 变得混乱 - 最好决定什么最有效对你的 class 有意义,而不是提供一堆不同的方法来做同样的事情。
通过静态方法,但需要通过括号调用。
class foo(object):
@staticmethod
def bar(): # a method that doesn't take any args
# slow calculation
return "abc"
b = bar # bar is a function but b just gives you the float attribute
f = foo()
print f.b()
输出:
$ python test.py
abc