Python 中的 classmethod 和 staticmethod 有什么具体用途

作者&投稿:良琪 (若有异议请与网页底部的电邮联系)
Python 中的 classmethod 和 staticmethod 有什么具体用途~

class MyClass: ... @classmethod # classmethod的修饰符 def class_method(cls, arg1, arg2, ...): ... @staticmethod # staticmethod的修饰符 def static_method(arg1, arg2, ...): ...对于classmethod的参数,需要隐式地传递类名,
而staticmethod参数中则不需要传递类名,其实这就是二者最大的区别。
二者都可以通过类名或者类实例对象来调用,因为强调的是classmethod和staticmethod,所以在写代码的时候最好使用类名,也是一种良好的编程习惯吧。

staticmethod就是为了要在类中定义而设置的,一般来说很少这样使用,可以使用模块级(module-level)的函数来替代它。既然要把它定义在类中,想必有作者的考虑。
而对于classmethod,可以通过子类来进行重定义。

今天刚看了流畅的python,里面有一章就讲到这两个的具体用例。
from math import hypot, atan2from array import arrayclass Vector(object): __slots__ = ('_x', '_y') typecode = 'd' def __init__(self, x=0, y=0): self._x = float(x) self._y = float(y) @property def x(self): return self._x @property def y(self): return self._y @classmethod def frombytes(cls, octets): typecode = chr(octests[0]) memv = momoryview(octets[1:]).cast(typecode) return cls(*memv) def __hash__(self): return hash(self.x) ^ hash(self.y) def __iter__(self): return (i for i in (self.x, self.y)) def __repr__(self): class_name = type(self).__name__ return f'{class_name}({self.x}, {self.y})' def __str__(self): return str(tuple(self)) def angle(self): return atan2(self.y, self.x) def __format__(self, fmt_spec=''): if fmt_spec.endswith('p'): fmt_spec = fmt_spec[:-1] coords = (abs(self), self.angel()) outer_fmt = ' sqrt(vector.x, vector.y) = 5 ''' return hypot(self.x, self.y) def __bool__(self): return abs(self) != 0 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) def __mul__(self, scalar): return Vector(self.x * scalar, self.y * scalar)

classmethod:类方法
staticmethod:静态方法

在python中,静态方法和类方法都是可以通过类对象和类对象实例访问。但是区别是:

@classmethod 是一个函数修饰符,它表示接下来的是一个类方法,而对于平常我们见到的则叫做实例方法。 类方法的第一个参数cls,而实例方法的第一个参数是self,表示该类的一个实例。 

普通对象方法至少需要一个self参数,代表类对象实例

类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量cls是子类,而非父类。 对于类方法,可以通过类来调用,就像C.f(),有点类似C++中的静态方法, 也可以通过类的一个实例来调用,就像C().f(),这里C(),写成这样之后它就是类的一个实例了。 

静态方法则没有,它基本上跟一个全局函数相同,一般来说用的很少

Example 1:

>>> class a():
@staticmethod
def staticm():
print 'static'
def normalm(self):
print 'nomarl',self
@classmethod
def classm(cls):
print 'class',cls


>>> a1=a()
>>> a1.normalm()
nomarl <__main__.a instance at 0x84dddec>
>>> a1.staticm()
static
>>> a1.classm()
class __main__.a
>>> type(a)
<type 'classobj'>
>>> type(a1)
<type 'instance'>


Example 2:

class A(object):
@classmethod
def cm(cls):
print '类方法cm(cls)调用者:', cls.__name__
@staticmethod
def sm():
print '静态方法sm()被调用'
class B(A):
pass
A.cm()
B.cm()
A.sm()
B.sm()
输出:
类方法cm(cls)调用者: A
类方法cm(cls)调用者: B
静态方法sm()被调用
静态方法sm()被调用


@classmethod与@staticmethod的应用实例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
class TClassStatic(object):
    obj_num = 0
    def __init__(self, data):
        self.data = data
        TClassStatic.obj_num += 1
    def printself(self):
        print("self.data: ", self.data)
    @staticmethod
    def smethod():
        print("the number of obj is : ", TClassStatic.obj_num)
    @classmethod
    def cmethod(cls):
        print("cmethod : ", cls.obj_num)
        cls.smethod()
def main():
    objA = TClassStatic(10)
    objB = TClassStatic(12)
    objB.printself()
    objA.smethod()
    objB.cmethod()
    print("------------------------------")
    TClassStatic.smethod()
    TClassStatic.cmethod()
if __name__ == "__main__":
    main()123456789101112131415161718192021222324252627282930313233

输出结果如下:

('self.data: ', 12)
('the number of obj is : ', 2)
('cmethod : ', 2)
('the number of obj is : ', 2)
------------------------------
('the number of obj is : ', 2)
('cmethod : ', 2)
('the number of obj is : ', 2)


classmethod:类方法staticmethod:静态方法
在python中,静态方法和类方法都是可以通过类对象和类对象实例访问。但是区别是:
@classmethod 是一个函数修饰符,它表示接下来的是一个类方法,而对于平常我们见到的则叫做实例方法。 类方法的第一个参数cls,而实例方法的第一个参数是self,表示该类的一个实例。
普通对象方法至少需要一个self参数,代表类对象实例
类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量cls是子类,而非父类。 对于类方法,可以通过类来调用,就像C.f(),有点类似C++中的静态方法, 也可以通过类的一个实例来调用,就像C().f(),这里C(),写成这样之后它就是类的一个实例了。
静态方法则没有,它基本上跟一个全局函数相同,一般来说用的很少
Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

>>> class a():
@staticmethod
def staticm():
print 'static'
def normalm(self):
print 'nomarl',self
@classmethod
def classm(cls):
print 'class',cls

>>> a1=a()
>>> a1.normalm()
nomarl
>>> a1.staticm()
static
>>> a1.classm()
class __main__.a
>>> type(a)

>>> type(a1)

Example 2:

class A(object):
@classmethod
def cm(cls):
print '类方法cm(cls)调用者:', cls.__name__
@staticmethod
def sm():
print '静态方法sm()被调用'
class B(A):
pass
A.cm()
B.cm()
A.sm()
B.sm()
输出:
类方法cm(cls)调用者: A
类方法cm(cls)调用者: B
静态方法sm()被调用
静态方法sm()被调用

@classmethod与@staticmethod的应用实例

#!/usr/bin/env python
# -*- coding: utf-8 -*-
class TClassStatic(object):
obj_num = 0
def __init__(self, data):
self.data = data
TClassStatic.obj_num += 1
def printself(self):
print("self.data: ", self.data)
@staticmethod
def smethod():
print("the number of obj is : ", TClassStatic.obj_num)
@classmethod
def cmethod(cls):
print("cmethod : ", cls.obj_num)
cls.smethod()
def main():
objA = TClassStatic(10)
objB = TClassStatic(12)
objB.printself()
objA.smethod()
objB.cmethod()
print("------------------------------")
TClassStatic.smethod()
TClassStatic.cmethod()
if __name__ == "__main__":
main()123456789101112131415161718192021222324252627282930313233

输出结果如下:

('self.data: ', 12)
('the number of obj is : ', 2)
('cmethod : ', 2)
('the number of obj is : ', 2)
------------------------------
('the number of obj is : ', 2)
('cmethod : ', 2)
('the number of obj is : ', 2)

classmethod将方法变成类方法,自动传给方法的第一个参数是类,而不是类的实例
staticmethod将class中的方法变成静态方法,可以当做普通方法一样调用 ,而不会将类实例本身作为第一个self参数传给方法


洞口县18929896627: Python 中的 classmethod 和 staticmethod 有什么具体用途 -
父米圣诺: 今天刚看了流畅的python,里面有一章就讲到这两个的具体用例.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 ...

洞口县18929896627: python的class中的object是什么意思 -
父米圣诺: object 是指这个类继承的最顶级的对象.python3.x 中已经可以省略object,可直接 class Sample(): pass

洞口县18929896627: 在python里 np.cumsum这个命令是干嘛的,怎么用啊? -
父米圣诺: 累计求和的命令.具体例子如下所示:1 2 3 4 5 6 7 8 9 10 11 12 13 14>>> a =np.array([[1,2,3], [4,5,6]]) >>> a array([[1, 2, 3],[4, 5, 6]]) >>> np.cumsum(a) array([ 1, 3, 6, 10, 15, 21]) >>> np.cumsum(a, dtype=float) # specifies type of output value(...

洞口县18929896627: Python中静态方法和类方法的区别 -
父米圣诺: 面相对象程序设计中,类方法和静态方法是经常用到的两个术语.逻辑上讲:类方法是只能由类名调用;静态方法可以由类名或对象名进行调用.在C++中,静态方法与类方法逻辑上是等e79fa5e98193e59b9ee7ad9431333361323532价的,...

洞口县18929896627: python中init方法中定义的 -- metaclass--=xxx的作用? -
父米圣诺: __metaclass__是Python2的写法,代表指定该类的元类.Python3中对应的写法是class 要定义的类名(metaclass=元类名) 元类是生成类的工厂,就像类是生成对象实例的工厂.在Python中所有类的默认元类是type,如果需要自定义类的生成方式,例如给类添加特定的属性,那么就需要替换默认元类为你自己编写的元类,此时就要用到metaclass语法.一个重要的利用场景就是ORM框架,因为数据库模型类的编写者是无法预知这个类可能有哪些字段的,所以必须要利用元类动态地生成这个类. 关于元类的说明可以看:网页链接

洞口县18929896627: python中的 -- name- - =="--main--"是什么意思呢 -
父米圣诺: __name__为python程序内置属性 __name__为__main__时表示程序作为主程序执行,而不是使用import 作为模块导入

洞口县18929896627: 关于python里定义class的问题 -
父米圣诺: 对象构造后第一个调用的函数,在python里面实例的属性是可以动态构建的,在类里面定义的属性是类属性,不是实例属性,定义实例自己的属性的最好地方是__init__函数里面. 比如 class TEST():class_attr #类属性,通过TEST.class_attr调...

洞口县18929896627: Python中class与type有什么区别? -
父米圣诺: 我看是这样的 Python 2.7.13 (default, Sep 26 2018, 18:42:22) [GCC 6.3.0 20170516] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> type('Hello, world!') <type 'str'>Python 3.5.3 (default, Sep 27 2018, ...

洞口县18929896627: 如何在Python中正确使用static,class,abstract方法 -
父米圣诺: class 方法直接写 static方法在方法前加上@staticmethod abstract方法先从abc导入 from abc import abstractmethod 然后在方法前加上@abstractmethod

洞口县18929896627: python里的 -- name--属性,是怎么回事? -
父米圣诺: 在使用自身的时候,就是main,比如你执行: python test.py 此时在test.py里面的name就是main 如果你在test2中import test,那么name就是文件名

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网