在函数中使用静态方法代替子函数的必要性
Necessity of using static methods instead of sub-functions in a function
我看过关于 difference between @classmethod
and @staticmethod
and about 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
in Pizza
。假设将来我不会在 Pizza
中定义任何其他功能,即我只做比萨饼烹饪。我不能简单地将其定义为一个函数 cook_pizza
吗?这样 mix_ingredients
就不会是全局的,也不会与其他实例发生名称冲突。
在这种情况下写成 @staticmethod
有什么优点或缺点吗?比如Pizza(cheese, vegetables).cook()
是否比cook_pizza(cheese, vegetables)
性能更好,因为前者在过程中不需要每次都定义mix_ingredients
?
基本区别在于您可以使用使用 staticmethod 修饰的函数而无需实例化 class,
但是如果你创建一个 sub-function/inner-function 你就不能从定义它的外部函数访问它。
方法
没有实例化:
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
可能是一个静态方法,因为它不使用在 class 级别定义的任何变量或自身的存储。
感谢:@Shadow @abarnert 在此答案的讨论线程中做出的贡献。
我看过关于 difference between @classmethod
and @staticmethod
and about 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
in Pizza
。假设将来我不会在 Pizza
中定义任何其他功能,即我只做比萨饼烹饪。我不能简单地将其定义为一个函数 cook_pizza
吗?这样 mix_ingredients
就不会是全局的,也不会与其他实例发生名称冲突。
在这种情况下写成 @staticmethod
有什么优点或缺点吗?比如Pizza(cheese, vegetables).cook()
是否比cook_pizza(cheese, vegetables)
性能更好,因为前者在过程中不需要每次都定义mix_ingredients
?
基本区别在于您可以使用使用 staticmethod 修饰的函数而无需实例化 class,
但是如果你创建一个 sub-function/inner-function 你就不能从定义它的外部函数访问它。
方法
没有实例化:
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
可能是一个静态方法,因为它不使用在 class 级别定义的任何变量或自身的存储。
感谢:@Shadow @abarnert 在此答案的讨论线程中做出的贡献。