我见过有关difference between @classmethod
and @staticmethod
和that between @staticmethod
and global functions的讨论,但我仍然对@staticmethod
与函数中的子函数之间的区别感到困惑。
请考虑以下示例(从The definitive guide on how to use static, class or abstract methods in Python修订):
class Pizza(object):
def __init__(self, cheese, vegetables):
self.cheese = cheese
self.vegetables = vegetables
@staticmethod
def mix_ingredients(x, y):
return x + y
def cook(self):
return self.mix_ingredients(self.cheese, self.vegetables)
为什么不:
def cook_pizza(cheese, vegetables):
def mix_ingredients(x, y):
return x + y
return mix_ingredients(cheese, vegetables)
在此示例中,我使用的函数是cook
中的Pizza
。假设我将来在Pizza
中没有定义任何其他功能,即我只用披萨烹饪。我不能简单地将其定义为单个函数cook_pizza
吗?这样,mix_ingredients
将不是全局的,也不会与其他实例发生名称冲突。
在这种情况下,作为@staticmethod
,是否有任何优点或缺点?例如,Pizza(cheese, vegetables).cook()
的效果是否优于cook_pizza(cheese, vegetables)
,因为前者不需要在每次进程中定义mix_ingredients
?
答案 0 :(得分:2)
基本区别在于你可以使用staticmethod修饰的函数而无需实例化类,
但是如果你创建了一个子函数/内部函数,你就无法从它所定义的外部函数中访问它。
没有实例化:
In [2]: Pizza.cook()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-4a252d4e9619> in <module>()
----> 1 Pizza.cook()
TypeError: cook() missing 1 required positional argument: 'self'
使用实例:
In [4]: Pizza('cheese', 'vegetables').cook()
Out[4]: 'cheesevegetables'
没有实例化:
In [5]: Pizza.mix_ingredients(1,2)
Out[5]: 3
每次调用cook_pizza
时,它都会定义嵌套函数,这会对执行时间产生影响。
import timeit
def method():
return 'method'
def method_with_inner():
def inner():
return 'inner'
return inner()
执行
print(timeit.timeit("method()", setup="from __main__ import method"))
0.0910306089790538
print(timeit.timeit("method_with_inner()", setup="from __main__ import method_with_inner"))
0.24090809898916632
cook_pizza
可以是静态方法,因为它不使用在类级别定义的任何变量或自我存储。
谢谢:@Shadow @abarnert在这个答案的讨论主题中的贡献。