在函数中使用静态方法而不是子函数的必要性

时间:2018-04-27 03:28:10

标签: python function oop static-methods

我见过有关difference between @classmethod and @staticmethodthat 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

1 个答案:

答案 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在这个答案的讨论主题中的贡献。