在Python中使用静态方法的优点是什么?
我在代码中遇到了python的unbound方法错误
class Sample(object): '''This class defines various methods related to the sample''' def drawSample(samplesize,List): sample=random.sample(List,samplesize) return sample Choices=range(100) print Sample.drawSample(5,Choices)
在阅读了许多有用的post之后,我想到了如何添加@staticmethod来获得代码的工作。 我是python新手。 有人可以请解释为什么要想定义静态方法? 或者,为什么不是所有的方法都被定义为静态方法?
静态方法的使用是有限的,因为他们没有权限访问类的实例的属性(就像普通的方法一样),并且他们没有权限访问类本身的属性(就像类方法一样)。
所以他们对日常的方法没有用处。
然而,将一些效用函数与一个类组合在一起可以是有用的,例如从一种types到另一种types的简单转换,除了提供的参数外(也可能是模块的全局属性),不需要访问任何信息。 )
他们可以放在课堂外,但是在课堂上分组可能是合理的。
您也可以通过实例或类引用方法,而不是模块名称,这可能有助于读者理解该方法与哪个实例相关。
请参阅这篇文章的详细解释。
TL; DR
它消除了self
论证的使用。
2.减less内存使用量,因为Python不必为每个对象实例化一个绑定方法 :
>>>RandomClass().regular_method is RandomClass().regular_method False >>>RandomClass().static_method is RandomClass().static_method True >>>RandomClass.static_method is RandomClass().static_method True
3.提高了代码的可读性,表示该方法不依赖于对象本身的状态。
4.它允许方法重写,如果方法是在模块级定义的(即在类之外),子类将不能覆盖该方法。
这不是真正的问题,但是既然你已经说过你是一个Python新手,也许会有所帮助,而且没有其他人明确表示出来。
我永远不会通过使该方法成为静态方法来修复上述代码。 我要么放弃课程,只写一个函数:
def drawSample(samplesize,List): sample=random.sample(List,samplesize) return sample Choices=range(100) print drawSample(5,Choices)
如果你有很多相关的function,你可以将它们分组到一个模块中,也就是把它们放在同一个文件中,例如sample.py。 然后
import sample Choices=range(100) print sample.drawSample(5,Choices)
或者我会为这个类添加一个init方法,并创build一个有用方法的实例:
class Sample(object): '''This class defines various methods related to the sample''' def __init__(self, thelist): self.list = thelist def draw_sample(self, samplesize): sample=random.sample(self.list,samplesize) return sample choices=Sample(range(100)) print choices.draw_sample(5)
(我也在上面的例子中改变了案例惯例,以符合PEP 8推荐的风格。)
Python的优点之一是它并不强迫你为所有的东西使用类。 只有当数据或状态应该与方法关联时,才可以使用它们,这是类的用途。 否则,你可以使用函数,这是什么function。
当你从一个对象实例中调用一个函数对象时,它就成为一个“绑定方法”,并获取实例对象本身作为第一个参数传入。
当你在一个对象实例上调用一个classmethod
对象(包装一个函数对象)时,实例对象的类将作为第一个参数传入。
当您调用staticmethod
对象(包装函数对象)时,不会使用隐式的第一个参数。
class Foo(object): def bar(*args): print args @classmethod def baaz(*args): print args @staticmethod def quux(*args): print args >>> foo = Foo() >>> Foo.bar(1,2,3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unbound method bar() must be called with Foo instance as first argument (got int instance instead) >>> Foo.baaz(1,2,3) (<class 'Foo'>, 1, 2, 3) >>> Foo.quux(1,2,3) (1, 2, 3) >>> foo.bar(1,2,3) (<Foo object at 0x1004a4510>, 1, 2, 3) >>> foo.baaz(1,2,3) (<class 'Foo'>, 1, 2, 3) >>> foo.quux(1,2,3) (1, 2, 3)
为什么要定义静态方法 ?
假设我们有一个叫Math
的class
没有人会想要创buildclass Math
对象
然后调用像ceil
, floor
和fabs
这样的方法。
所以我们把它们变成static
比如做
>> Math.floor(3.14)
比…更好
>> mymath = Math() >> mymath.floor(3.14)
所以他们在某种程度上是有用的。 您不需要创build一个类的实例来使用它们。
为什么不是所有的方法都被定义为静态方法 ?
他们不能访问实例variables。
class Foo(object): def __init__(self): self.bar = 'bar' def too(self): print self.bar @staticmethod def foo(): print self.bar Foo().too() # works Foo.foo() # doesn't work
这就是为什么我们不能使所有的方法都是静态的。
静态方法是伟大的,因为你不必声明该方法所属的对象的实例。
python的站点有一些关于静态方法的很好的文档:
http://docs.python.org/library/functions.html#staticmethod
静态方法在Python中几乎没有任何理由。 您可以使用实例方法或类方法。
def method(self, args): self.member = something @classmethod def method(cls, args): cls.member = something @staticmethod def method(args): MyClass.member = something # The above isn't really working # if you have a subclass
由于命名空间函数很好(正如之前指出的那样):
-
当我想要明确不改变对象状态的方法时,我使用静态方法。 这阻止了我的团队中的人们开始改变这些方法中的对象的属性。
-
当我重构真正烂的代码时,我开始尝试尽可能多地创build
@staticmethod
方法。 这使我可以将这些方法提取到一个类中 – 尽pipe我同意这一点,但这种方法很less用到,它确实有用了几次。