提问



@staticmethod修饰的函数和用@classmethod修饰的函数有什么区别?[137] [138]

最佳参考


也许一些示例代码会有所帮助:注意fooclass_foostatic_foo的调用签名的差异:


class A(object):
    def foo(self,x):
        print "executing foo(%s,%s)"%(self,x)

    @classmethod
    def class_foo(cls,x):
        print "executing class_foo(%s,%s)"%(cls,x)

    @staticmethod
    def static_foo(x):
        print "executing static_foo(%s)"%x    

a=A()


下面是对象实例调用方法的常用方法。对象实例a隐式传递为第一个参数。


a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)





使用classmethods ,对象实例的类隐式传递为第一个参数而不是self


a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)


您也可以使用该类调用class_foo。事实上,如果你定义的东西是
一个类方法,可能是因为你打算从类而不是从类实例中调用它。 A.foo(1)会引发一个TypeError,但A.class_foo(1)工作正常:


A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)


人们发现类方法的一个用途是创建可继承的替代构造函数。





使用staticmethods 时,self(对象实例)和cls(类)都不会作为第一个参数隐式传递。它们的行为类似于普通函数,除了您可以从实例或类中调用它们:


a.static_foo(1)
# executing static_foo(1)

A.static_foo('hi')
# executing static_foo(hi)


Staticmethod用于将与类有逻辑连接的函数分组到类中。





foo只是一个功能,但是当你打电话a.foo时,你不会得到这个功能,
你得到一个部分应用的函数版本,对象实例a绑定为函数的第一个参数。 foo期望2个参数,而a.foo只需要1个参数。


a必然会foo。这就是下面的绑定一词的含义:


print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>


a.class_fooa不与class_foo绑定,而A类与class_foo绑定。


print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>


在这里,使用静态方法,即使它是一种方法,a.static_foo只是返回
一个好的没有参数的ole函数。static_foo期望一个参数,和
a.static_foo也期待一个论点。


print(a.static_foo)
# <function static_foo at 0xb7d479cc>


当然,当您使用类A调用static_foo时会发生同样的事情。


print(A.static_foo)
# <function static_foo at 0xb7d479cc>

其它参考1


staticmethod 是一种对调用它的类或实例一无所知的方法。它只是获取传递的参数,没有隐含的第一个参数。它在Python中基本没用 - 您可以使用模块函数而不是静态方法。


另一方面, classmethod 是一个方法,它将调用它的类或它所调用的实例的类作为第一个参数传递。当您希望该方法成为该类的工厂时,这很有用:因为它获取了作为第一个参数调用的实际类,所以即使涉及子类,也可以始终实例化正确的类。例如,观察dict.fromkeys(),类方法如何在子类上调用时返回子类的实例:


>>> class DictSubclass(dict):
...     def __repr__(self):
...         return "DictSubclass"
... 
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>> 

其它参考2


基本上@classmethod创建一个方法,其第一个参数是它被调用的类(而不是类实例),@staticmethod没有任何隐式参数。

其它参考3


官方python文档:


@classmethod [140]



  类方法接收类为
  隐含的第一个参数,就像一个
  instance方法接收实例。
  要声明一个类方法,请使用它
  成语:


class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ... 

  
  @classmethod形式是一种功能
   decorator - 请参阅说明
  函数中的函数定义
  定义了解详情。[141] [142]

  
  它可以在课堂上调用
  (例如C.f())或实例
  (如C().f())。实例是
  被忽略了除了它的类。如果一个
  为派生调用类方法
  class,派生类对象是
  作为隐含的第一个参数传递。

  
  类方法与C ++不同
  或Java静态方法。如果你想
  那些,见staticmethod()
  节。[143]



@staticmethod [144]



  静态方法不会收到
  隐含第一个参数。宣布一个
  静态方法,使用这个成语:


class C:
    @staticmethod
    def f(arg1, arg2, ...): ... 

  
  @staticmethod表单是一个函数
   decorator - 请参阅说明
  函数中的函数定义
  定义了解详情。[145] [146]

  
  它可以在课堂上调用
  (例如C.f())或实例
  (如C().f())。实例是
  被忽略了除了它的类。

  
  Python中的静态方法是类似的
  那些在Java或C ++中找到的。为一个
  更高级的概念,请参阅
  classmethod()在本节中。[147]


其它参考4


这是关于这个问题的简短文章[148]



  @staticmethod函数只不过是在类中定义的函数。它可以在不首先实例化类的情况下调用。它的定义是通过继承不可变的。

  
  @classmethod函数也可以在不实例化类的情况下调用,但它的定义遵循Sub类,而不是Parent类,通过继承。那是因为@classmethod函数的第一个参数必须始终是cls(class)。


其它参考5


要决定是否使用@staticmethod或@classmethod,你必须查看你的方法。 如果您的方法访问您班级中的其他变量/方法,请使用@classmethod 。另一方面,如果你的方法没有触及班级的任何其他部分,那么使用@staticmethod。[149] [150]


class Apple:

    _counter = 0

    @staticmethod
    def about_apple():
        print('Apple is good for you.')

        # note you can still access other member of the class
        # but you have to use the class instance 
        # which is not very nice, because you have repeat yourself
        # 
        # For example:
        # @staticmethod
        #    print('Number of apples have been juiced: %s' % Apple._counter)
        #
        # @classmethod
        #    print('Number of apples have been juiced: %s' % cls._counter)
        #
        #    @classmethod is especially useful when you move your function to other class,
        #       you don't have to rename the class reference 

    @classmethod
    def make_apple_juice(cls, number_of_apples):
        print('Make juice:')
        for i in range(number_of_apples):
            cls._juice_this(i)

    @classmethod
    def _juice_this(cls, apple):
        print('Juicing %d...' % apple)
        cls._counter += 1

其它参考6



  

Python中@staticmethod和@classmethod有什么区别?




您可能已经看过像这个伪代码的Python代码,它演示了各种方法类型的签名,并提供了一个文档字符串来解释每个:


class Foo(object):

    def a_normal_instance_method(self, arg_1, kwarg_2=None):
        '''
        Return a value that is a function of the instance with its
        attributes, and other arguments such as arg_1 and kwarg2
        '''

    @staticmethod
    def a_static_method(arg_0):
        '''
        Return a value that is a function of arg_0. It does not know the 
        instance or class it is called from.
        '''

    @classmethod
    def a_class_method(cls, arg1):
        '''
        Return a value that is a function of the class and other arguments.
        respects subclassing, it is called with the class it is called from.
        '''


正常实例方法



首先,我将解释a_normal_instance_method。这被称为实例方法。当使用实例方法时,它被用作部分函数(与总函数相对,当在源代码中查看时为所有值定义),即,当使用时,第一个参数被预定义为对象的实例,具有所有给定的属性。它具有绑定到它的对象的实例,并且必须从对象的实例调用。通常,它将访问实例的各种属性。


例如,这是一个字符串的实例:


', '


如果我们在这个字符串上使用实例方法join来加入另一个iterable,
它显然是实例的一个功能,除了是可迭代列表的函数之外,['a', 'b', 'c']:


>>> ', '.join(['a', 'b', 'c'])
'a, b, c'


绑定方法



可以通过点查找绑定实例方法以供稍后使用。


例如,这会将str.join方法绑定到':'实例:


>>> join_with_colons = ':'.join 


之后我们可以将它用作已经绑定了第一个参数的函数。这样,它就像实例上的部分函数一样:


>>> join_with_colons('abcde')
'a:b:c:d:e'
>>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF'])
'FF:FF:FF:FF:FF:FF'


静态方法



静态方法不将实例作为参数。


它与模块级功能非常相似。


但是,模块级功能必须存在于模块中,并专门导入到使用它的其他位置。


但是,如果它附加到对象,它也将通过导入和继承方便地跟随对象。


静态方法的一个例子是str.maketrans,从Python 3中的string模块移动。它使str.translate适合使用的转换表。从字符串实例中使用时看起来确实相当愚蠢,如下所示,但从string模块导入函数相当笨拙,能够从类中调用它很好,如在str.maketrans


# demonstrate same function whether called from instance or not:
>>> ', '.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
>>> str.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}


在python 2中,您必须从越来越不实用的字符串模块中导入此函数:


>>> import string
>>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc'))
'abcDEFG'


类方法



类方法类似于实例方法,因为它采用隐式的第一个参数,但不是采用实例,而是采用类。通常这些用作替代构造函数以获得更好的语义用法,并且它将支持继承。


内置类方法的最典型示例是dict.fromkeys。它被用作dict的替代构造函数(非常适合当你知道你的键是什么并且想要它们的默认值时。)


>>> dict.fromkeys(['a', 'b', 'c'])
{'c': None, 'b': None, 'a': None}


当我们继承dict时,我们可以使用相同的构造函数,它创建子类的实例。


>>> class MyDict(dict): 'A dict subclass, use to demo classmethods'
>>> md = MyDict.fromkeys(['a', 'b', 'c'])
>>> md
{'a': None, 'c': None, 'b': None}
>>> type(md)
<class '__main__.MyDict'>


有关替代构造函数的其他类似示例,请参阅pandas源代码,另请参阅classmethodstaticmethod上的官方Python文档。[151] [152] [153]

其它参考7


在Python 2.4中添加了@decorators如果你正在使用python< 2.4你可以使用classmethod()和staticmethod()函数。


例如,如果要创建工厂方法(一个函数根据它获取的参数返回类的不同实现的实例),您可以执行以下操作:


class Cluster(object):

    def _is_cluster_for(cls, name):
        """
        see if this class is the cluster with this name
        this is a classmethod
        """ 
        return cls.__name__ == name
    _is_cluster_for = classmethod(_is_cluster_for)

    #static method
    def getCluster(name):
        """
        static factory method, should be in Cluster class
        returns a cluster object for the given name
        """
        for cls in Cluster.__subclasses__():
            if cls._is_cluster_for(name):
                return cls()
    getCluster = staticmethod(getCluster)


还要注意这是使用classmethod和静态方法的一个很好的例子,
静态方法显然属于类,因为它在内部使用类Cluster。
classmethod只需要有关类的信息,而不需要对象的实例。


使_is_cluster_for方法成为类方法的另一个好处是,子类可以决定改变它的实现,可能因为它非常通用并且可以处理多种类型的集群,所以只需检查类的名称还不够。

其它参考8


我认为一个更好的问题是你什么时候使用@classmethod vs @staticmethod?


@classmethod允许您轻松访问与类定义关联的私有成员。这是做单例的好方法,或者是控制所创建对象的实例数的工厂类。


@staticmethod提供了边际性能提升,但是我还没有看到一个类中的静态方法的有效使用,这个方法不能作为类外的独立函数来实现。

其它参考9


静态方法:



  • 没有自我论证的简单函数。

  • 处理类属性;不是实例属性。

  • 可以通过类和实例调用。

  • 内置函数staticmethod()用于创建它们。



静态方法的好处:



  • 它在classscope中定位函数名称

  • 它将功能代码移动到更接近使用位置

  • 导入与模块级函数相比更方便,因为不必专门导入每种方法


    @staticmethod
    def some_static_method(*args, **kwds):
        pass
    



课程方法:



  • 第一个参数为classname的函数。

  • 可以通过类和实例调用。

  • 这些是使用classmethod内置函数创建的。


     @classmethod
     def some_class_method(cls, *args, **kwds):
         pass
    


其它参考10


@staticmethod只是禁用默认函数作为方法描述符。 classmethod将您的函数包装在一个可调用的容器中,该容器将对所属类的引用作为第一个参数传递:


>>> class C(object):
...  pass
... 
>>> def f():
...  pass
... 
>>> staticmethod(f).__get__(None, C)
<function f at 0x5c1cf0>
>>> classmethod(f).__get__(None, C)
<bound method type.f of <class '__main__.C'>>


事实上,classmethod具有运行时开销,但可以访问拥有类。或者,我建议使用元类并将类方法放在该元类上:


>>> class CMeta(type):
...  def foo(cls):
...   print cls
... 
>>> class C(object):
...  __metaclass__ = CMeta
... 
>>> C.foo()
<class '__main__.C'>

其它参考11


关于如何在Python中使用静态,类或抽象方法的权威指南是本主题的一个很好的链接,并总结如下。[154]


@staticmethod 函数只不过是在类中定义的函数。它可以在不首先实例化类的情况下调用。它的定义是通过继承不可变的。



  • Python不必实例化对象的绑定方法。

  • 它简化了代码的可读性,并且它不依赖于对象本身的状态;



@classmethod 函数也可以在不实例化类的情况下调用,但是它的定义遵循Sub类,而不是Parent类,通过继承,可以被子类覆盖。那是因为@classmethod函数的第一个参数必须始终是 cls (class)。



  • 工厂方法,用于为类创建实例,例如使用某种预处理。

  • 调用静态方法的静态方法:如果在几个静态方法中拆分静态方法,则不应该对类名进行硬编码,而是使用类方法


其它参考12


@classmethod意味着:当调用此方法时,我们将类作为第一个参数而不是该类的实例传递(正如我们通常使用的方法)。这意味着您可以在该方法中使用类及其属性,而不是特定实例。


@staticmethod意味着:当调用此方法时,我们不会将类的实例传递给它(就像我们通常使用的方法一样)。这意味着你可以在类中放置一个函数但是你无法访问该类的实例(当您的方法不使用该实例时,这很有用)。

其它参考13


关于staticmethod vs classmethod的另一个考虑因素是继承。假设您有以下课程:


class Foo(object):
    @staticmethod
    def bar():
        return "In Foo"


然后你想在子类中覆盖bar():


class Foo2(Foo):
    @staticmethod
    def bar():
        return "In Foo2"


这有效,但请注意,现在子类(Foo2中的bar()实现不再能够利用该类特定的任何内容。例如,假设Foo2有一个名为magic()的方法,你想在bar() bar()的实现中使用它:


class Foo2(Foo):
    @staticmethod
    def bar():
        return "In Foo2"
    @staticmethod
    def magic():
        return "Something useful you'd like to use in bar, but now can't" 


这里的解决方法是在bar()中调用Foo2.magic(),但随后你重复自己(如果Foo2的名称发生变化,你将不得不记得更新bar() bar()]] 方法)。


对我而言,这是对开放/封闭原则的轻微违反,因为Foo中做出的决定正在影响您在派生类中重构公共代码的能力(即它不太适合扩展)。如果[[bar() classmethod我们没事[[:[155]


class Foo(object):
    @classmethod
    def bar(cls):
        return "In Foo"

class Foo2(Foo):
    @classmethod
    def bar(cls):
        return "In Foo2 " + cls.magic()
    @classmethod
    def magic(cls):
        return "MAGIC"

print Foo2().bar()


给:In Foo2 MAGIC

其它参考14


我将尝试使用示例来解释基本差异。


class A(object):
    x = 0

    def say_hi(self):
        pass

    @staticmethod
    def say_hi_static():
        pass

    @classmethod
    def say_hi_class(cls):
        pass

    def run_self(self):
        self.x += 1
        print self.x # outputs 1
        self.say_hi()
        self.say_hi_static()
        self.say_hi_class()

    @staticmethod
    def run_static():
        print A.x  # outputs 0
        # A.say_hi() #  wrong
        A.say_hi_static()
        A.say_hi_class()

    @classmethod
    def run_class(cls):
        print cls.x # outputs 0
        # cls.say_hi() #  wrong
        cls.say_hi_static()
        cls.say_hi_class()


1 - 我们可以直接调用static和classmethods而无需初始化


# A.run_self() #  wrong
A.run_static()
A.run_class()


2-静态方法不能调用self方法但可以调用其他静态方法和class方法


3-静态方法属于类,根本不使用对象。


4-类方法不是绑定到对象而是绑定到类。

其它参考15


在Python中,classmethod接收一个类作为隐式的第一个参数。对象实例的类隐式传递为第一个参数。这可能很有用
当一个人希望方法成为类的工厂,因为它将实际的类(它调用方法)作为第一个参数,即使子类也有关,也可以实例化正确的类。[156]


staticmethod只是在类中定义的函数。它对调用它的类或实例一无所知,只获取在没有任何隐式第一个参数的情况下传递的参数。
例:


class Test(object):
    def foo(self, a):
        print "testing (%s,%s)"%(self,a)

    @classmethod
    def foo_classmethod(cls, a):
        print "testing foo_classmethod(%s,%s)"%(cls,a)

    @staticmethod
    def foo_staticmethod(a):
        print "testing foo_staticmethod(%s)"%a

test = Test()


staticmethods用于对与类具有某种逻辑连接的函数进行分组。

其它参考16


我开始用C ++学习编程语言,然后是Java,然后是Python,所以这个问题也困扰了我,直到我理解了每个的简单用法。


类方法: Python与Java和C ++不同,它没有构造函数重载。所以要实现这一点你可以使用classmethod。下面的例子将解释这个


让我们考虑我们有一个Person类,它接受两个参数first_namelast_name并创建Person的实例。


class Person(object):

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name


现在,如果需求只需要使用单个名称创建一个类,那么只需要first_name。你不能在python中做这样的事情。


当您尝试创建对象(实例)时,这将给您一个错误。


class Person(object):

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

    def __init__(self, first_name):
        self.first_name = first_name


但是,您可以使用@classmethod实现相同的操作,如下所述


class Person(object):

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

    @classmethod
    def get_person(cls, first_name):
        return cls(first_name, "")


静态方法::这很简单,它没有绑定到实例或类,你可以使用类名简单地调用它。


所以,让我们在上面的例子中说你需要验证first_name不应该超过20个字符,你可以简单地这样做。


@staticmethod  
def validate_name(name):
    return len(name) <= 20


你可以简单地使用Class Name调用


Person.validate_name("Gaurang Shah")

其它参考17


首先让我先说一下用@classmethod和@staticmethod修饰的方法之间的相似性。


相似性:可以在 Class 本身上调用它们,而不仅仅是类的实例。所以,它们在某种意义上都是 Class的方法。


差异: classmethod将接收类本身作为第一个参数,而staticmethod则不接收。


因此,静态方法在某种意义上并不局限于Class本身,只是因为它可能具有相关功能而挂在那里。


>>> class Klaus:
        @classmethod
        def classmthd(*args):
            return args

        @staticmethod
        def staticmthd(*args):
            return args

# 1. Call classmethod without any arg
>>> Klaus.classmthd()  
(__main__.Klaus,)  # the class gets passed as the first argument

# 2. Call classmethod with 1 arg
>>> Klaus.classmthd('chumma')
(__main__.Klaus, 'chumma')

# 3. Call staticmethod without any arg
>>> Klaus.staticmthd()  
()

# 4. Call staticmethod with 1 arg
>>> Klaus.staticmthd('chumma')
('chumma',)

其它参考18


@classmethod:可用于创建对该类创建的所有实例的共享全局访问.....如更新多个用户的记录....
我特别发现它在创建单身时也很有用.. :)


@static方法:与关联的类或实例无关......但为了便于阅读,可以使用静态方法

其它参考19


类方法与Python中的静态方法


类方法


@classmethod装饰器是一个内置函数装饰器,它是一个在定义函数后得到的表达式。评估结果会影响您的函数定义。


类方法接收类作为隐式的第一个参数,就像实例方法接收实例一样


语法:


class C(object):
    @classmethod
    def fun(cls, arg1, arg2, ...):
       ....

fun: function that needs to be converted into a class method
returns: a class method for function.



  • 类方法是绑定到类而不是类的方法
    班级的对象。

  • 他们可以访问类的状态,因为它需要一个类
    指向类而不是对象实例的参数。

  • 它可以修改将应用于所有实例的类状态
    班上的。例如,它可以修改将要的类变量
    适用于所有情况。



静态方法


静态方法不会接收隐式的第一个参数。


语法:


class C(object):
    @staticmethod
    def fun(arg1, arg2, ...):
        ...
returns: a static method for function fun.



  • 静态方法也是绑定到类的方法而不是
    班级的对象。

  • 静态方法无法访问或修改类状态。

  • 它存在于一个类中,因为它对于该方法是有意义的
    在课堂上出现。



类方法与静态方法



  • 类方法将cls作为第一个参数,而静态方法
    不需要特定的参数。

  • 类方法可以在静态方法时访问或修改类状态
    无法访问或修改它。

  • 我们在python中使用@classmethod装饰器来创建一个类方法
    我们使用@staticmethod装饰器在python中创建一个静态方法。



何时使用?



  • 我们通常使用class方法来创建工厂方法。厂
    方法返回类对象(类似于构造函数)
    不同的用例。

  • 我们通常使用静态方法来创建效用函数。



如何定义类方法和静态方法?


要在python中定义类方法,我们使用@classmethod装饰器来定义我们使用@staticmethod装饰器的静态方法。


让我们看一个例子来理解它们之间的区别。
我们假设我们要创建一个Person类。现在,python不支持像C ++或Java那样的方法重载,所以我们使用类方法来创建工厂方法。在下面的示例中,我们使用类方法从出生年份创建人物对象。


如上所述,我们使用静态方法来创建效用函数。在下面的例子中,我们使用静态方法来检查一个人是否成年。


实施


# Python program to demonstrate 
# use of class method and static method.
from datetime import date

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # a class method to create a Person object by birth year.
    @classmethod
    def fromBirthYear(cls, name, year):
        return cls(name, date.today().year - year)

    # a static method to check if a Person is adult or not.
    @staticmethod
    def isAdult(age):
        return age > 18

person1 = Person('mayank', 21)
person2 = Person.fromBirthYear('mayank', 1996)

print person1.age
print person2.age

# print the result
print Person.isAdult(22)


输出


21
21
True


参考文献[157]

其它参考20


顾名思义,类方法用于更改类而不是对象。要对类进行更改,它们将修改class属性(不是对象属性),因为这是更新类的方式。
这就是类方法将类(通常用cls表示)作为第一个参数的原因。


class A(object):
    m=54

    @classmethod
    def class_method(cls):
        print "m is %d" % cls.m


另一方面,静态方法用于执行未绑定到类的功能,即它们不会读取或写入类变量。因此,静态方法不会将类作为参数。使用它们使类可以执行与类的目的无直接关系的功能。


class X(object):
    m=54 #will not be referenced

    @staticmethod
    def static_method():
        print "Referencing/calling a variable or function outside this class. E.g. Some global variable/function."

其它参考21


分析@staticmethod 字面提供不同的见解。


类的常规方法是隐式动态方法,它将实例作为第一个参数。

相反,static方法不会将实例作为第一个参数,因此称为static


静态方法确实是一个与类定义之外的函数相同的正常函数
幸运的是,它只是为了在应用它的地方站得更近,或者你可以滚动来找到它。

其它参考22


我的贡献证明了@classmethod@staticmethod和实例方法之间的区别,包括实例如何间接调用@staticmethod。但是,不是间接地从实例中调用@staticmethod,而是将其设为私有可能更加pythonic。从私人方法中获取某些东西并没有在这里展示,但它基本上是相同的概念。


#!python3

from os import system
system('cls')
# %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %

class DemoClass(object):
    # instance methods need a class instance and
    # can access the instance through 'self'
    def instance_method_1(self):
        return 'called from inside the instance_method_1()'

    def instance_method_2(self):
        # an instance outside the class indirectly calls the static_method
        return self.static_method() + ' via instance_method_2()'

    # class methods don't need a class instance, they can't access the
    # instance (self) but they have access to the class itself via 'cls'
    @classmethod
    def class_method(cls):
        return 'called from inside the class_method()'

    # static methods don't have access to 'cls' or 'self', they work like
    # regular functions but belong to the class' namespace
    @staticmethod
    def static_method():
        return 'called from inside the static_method()'
# %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %

# works even if the class hasn't been instantiated
print(DemoClass.class_method() + '\n')
''' called from inside the class_method() '''

# works even if the class hasn't been instantiated
print(DemoClass.static_method() + '\n')
''' called from inside the static_method() '''
# %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %

# >>>>> all methods types can be called on a class instance <<<<<
# instantiate the class
democlassObj = DemoClass()

# call instance_method_1()
print(democlassObj.instance_method_1() + '\n')
''' called from inside the instance_method_1() '''

# # indirectly call static_method through instance_method_2(), there's really no use
# for this since a @staticmethod can be called whether the class has been
# instantiated or not
print(democlassObj.instance_method_2() + '\n')
''' called from inside the static_method() via instance_method_2() '''

# call class_method()
print(democlassObj.class_method() + '\n')
'''  called from inside the class_method() '''

# call static_method()
print(democlassObj.static_method())
''' called from inside the static_method() '''

"""
# whether the class is instantiated or not, this doesn't work
print(DemoClass.instance_method_1() + '\n')
'''
TypeError: TypeError: unbound method instancemethod() must be called with
DemoClass instance as first argument (got nothing instead)
'''
"""

其它参考23


#!/usr/bin/python
#coding:utf-8

class Demo(object):
    def __init__(self,x):
        self.x = x

    @classmethod
    def addone(self, x):
        return x+1

    @staticmethod
    def addtwo(x):
        return x+2

    def addthree(self, x):
        return x+3

def main():
    print Demo.addone(2)
    print Demo.addtwo(2)

    #print Demo.addthree(2) #Error
    demo = Demo(2)
    print demo.addthree(2)


if __name__ == '__main__':
    main()

其它参考24


在iPython中快速解决其他方法相同的方法表明@staticmethod会产生边际性能增益(以纳秒为单位),但除此之外似乎没有任何功能。此外,在编译期间通过staticmethod()处理该方法的额外工作(在运行脚本时执行任何代码之前发生)可能会消除任何性能提升。


为了代码可读性,我要避免@staticmethod,除非你的方法用于加载工作,其中纳秒计数。