1.@classmethod

官方文档说明:
classmethod是用来指定一个类的方法为类方法‍,没有此参数指定的类的方法为实例方法,使用方法如下:
class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ...

简单来说,类方法,我们不用通过实例化类就能访问的方法。@classmethod 装饰的方法不能使用实例属性,只能是类属性。

它主要使用在和类进行交互,但不和其实例进行交互的函数方法上。例如:

class A(object):
    bar = 1
    def func1(self):  
        print ('foo') 
    @classmethod
    def func2(cls):
        print ('func2')
        print (cls.bar)
        cls().func1()   # 调用 foo 方法

A.func2()               # 不需要实例化

#输出结果
# func2
# 1
# foo

在上面的栗子中,func2()方法被@classmethod 装饰后,我们能通过A.func2()直接运行方法,而不需要实例!

在下面的这个栗子中可以明显看到两者的区别:

class A(object):

    # 属性默认为类属性(可以给直接被类本身调用)
    num = "类属性"

    # 实例化方法(必须实例化类之后才能被调用)
    def func1(self): # self : 表示实例化类后的地址id
        print("func1")
        print(self)

    # 类方法(不需要实例化类就可以被类本身调用)
    @classmethod
    def func2(cls):  # cls : 表示没用被实例化的类本身
        print("func2")
        print(cls)
        print(cls.num)
        cls().func1()

    # 不传递传递默认self参数的方法(该方法也是可以直接被类调用的,但是这样做不标准)
    def func3():
        print("func3")
        print(A.num) # 属性是可以直接用类本身调用的

# A.func1() 这样调用是会报错:因为func1()调用时需要默认传递实例化类后的地址id参数,如果不实例化类是无法调用的
A.func2()
A.func3()

# 输出
func2
<class '__main__.A'>
类属性
func1
<__main__.A object at 0x0000014F87D6A4D0>
func3
类属性

2.@staticmethod

@staticmethod 修饰的方法称为:静态方法。和@classmethod非常的相似,但是@staticmethod 不强制要求传递参数(它做的事与类方法或实例方法一样)。

可以这样理解,@staticmethod 修饰的方法是放在类外的函数,我们为了方便将它移动到了类里面,它对类的运行无影响。

class C(object):
    @staticmethod
    def f():
        print('runoob');
 
C.f();          # 静态方法无需实例化
cobj = C()
cobj.f()        # 也可以实例化后调用

# 输出结果
# runoob
# runoob
# 可以看到两者没有区别

 

 

 

 

 

 

posted on 2023-04-20 21:51  白的枫叶  阅读(474)  评论(0)    收藏  举报