python3 classmethod 与staticmethod区别

classmethod 与staticmethod区别

  • 某个函数前面加上了staticmethod或者classmethod的话,那么这个函数就可以不通过实例化直接调用。
  • 什么意思呢?就是说有时候,我们需要把一些具有特定功能的函数放到一起,做成包导入Python程序,最好就是把他们放到一个类中,但是一个类每次我都要去实例化他,我觉得很麻烦,于是我在函数前面加上了@staticmethod,@classmethod,那么我下次用这个函数的功能的时候,可以直接用 类名.函数名的形式了。

区别

  • @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
  • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
  • 如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。
  • 而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

简单来说,就是staticmethod不需要传入表示自身对象参数,而classmethod需要传入一个类似于self的cls参数。那么既然classmethod麻烦一点,必然有他麻烦的道理,就是:使用classmethod的话,凡是在该类中的类的属性,方法,实例化对象等,都可以调用出来。

定义类方法的几种方式:

  • 常规方式    : 需要self隐士传递当前类对象的实例。
  • @classmethod 装饰器修饰 :需要通过cls参数传递当前类对象
  • @staticmethod 装饰器修饰 :与普通函数是一样
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.foo(1)        #executing foo(<__main__.A object at 0x0000000001E9B488>, 1)
a.class_foo(2)  #executing class_foo(<class '__main__.A'>, 2)
a.static_foo(3) #executing static_foo(3)

#@classmethod修饰方法调用: 类对象或对象实例调用
A.class_foo(4) #executing class_foo(<class '__main__.A'>, 4)
a.class_foo(5) #executing class_foo(<class '__main__.A'>, 5)

# 通过类对象 访问常规方法即没有修饰符的方法
A.foo(a,6) #executing foo(<__main__.A object at 0x000000000284C488>, 6)

其他案例:

class A(object):
    def __init__(self,name):
        self.name = name

    def foo(self, x):
        print("executing foo(%s, %s, %s)" % (self, x,self.name))

    @classmethod
    def class_foo(cls, x):
        print("executing class_foo(%s, %s)" % (cls, x))
        # 返回一个实例对象
        return cls(x)

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

dd = A.class_foo(2) # executing class_foo(<class '__main__.A'>, 2)
print(dd.name)      # 2
dd.foo(3)           # executing foo(<__main__.A object at 0x0000000001E8B708>, 3, 2)
class CeShi:
    name = '测试'
    def __init__(self,x,y):
        self.x = x
        self.y = y

    @property           #在CeShi_add函数前加上@property,使得该函数可直接调用,封装起来
    def CeShi_add(self):
        return self.x + self.y

                        #在CeShi_info函数前加上@classmethon,则该函数变为类方法,
    @classmethod        #该函数只能访问到类的数据属性,不能获取实例的数据属性
    def CeShi_info(cls):  #python自动传入位置参数cls就是类本身
        print('这是一个%s'%cls.name)   #cls.CeShi_name调用类自己的数据属性

CeShi.CeShi_info()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值