python实例方法、类方法@classmethod、静态方法@staticmethod和属性方法@property区别

1、#类方法@classmethod,只能访问类变量,不能访问实例变量,通过cls参数传递当前类对象,不需要实例化,直接【类名.方法名()】,可通过类对象和类对象实例访问

2、#静态方法@staticmethod,名义归类管,实际跟类没关系,跟类关联截断了,是类下单独的函数,可以不传递任何参数,不需要实例化,直接【类名.方法名(),可通过类对象和类对象实例访问

3、#实例方法,一般类下未带修饰符@是实例方法,需要实例化后调用

在这里插入图片描述
@property、@staticmethod和@classmethod应用与区分
在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以对属性随便修改,不能限制输入

class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    @property      #引用装饰器property
    def age(self):
        return self.__age
    @age.setter    #函数修饰后可以作为装饰器使用调用后可以修改原始数据
    def age(self,value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')  #非int类型抛异常
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!') #年龄基本都是0-100以内,限制输入
        self.__age = value

s = Student('Mitsui', 24) #当age参数传入24,age会去找被property修饰的age 实际上age = self.__age而非self.age
print(s.name,s.age)       #也就是age参数会传入age()方法中的value参数,开始执行age.setter,实现规范输入的目的,
s.age = 18                #同时在调用时,把 age()方法变成一个可以赋值的属性,让调用者更加方便的调用
s.name = 'BOBO'
print(s.name)
print(s.age)            #没有赋值实际上执行了age方法下的 ‘return self.__age’

@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

import time   #引用时间模块
class Date():
    def __init__(self,year,month,day):   #定义一个时间,调用类或者实例化时可以传参
        self.year = year
        self.month = month
        self.day = day

    @classmethod   #@classmethod 可以调用类
    def now(cls):      #用cls把类传递过来
        print(cls)          #打印cls,验证是哪个类在调用它
        t = time.localtime()      #获得有格式的时间
        obj = cls(t.tm_year,t.tm_mon,t.tm_mday)     #将时间的对应参数按装饰后的cls传入类属性,隐藏丑陋的接口
        return obj                                 #调用时可以直接self.year 即 cls.year , cls.month如此调用
    @classmethod
    def Euro(cls):            #定义一个欧洲时间,以伦敦为例
        t=time.localtime(time.time()-28800)      #伦敦时间与北京时间差8个时区,减去计算机识别对应的秒数
        return cls(t.tm_year,t.tm_mon,t.tm_mday)    #同上

class EuroDate(Date):  #可以定义一个子类继承自Date类
    def __str__(self):   #__str__ 定义在类内部,必须返回一个字符串类型,打印由这个类产生的对象时,会触发执行
        return '现在是%s年%s月%s日from %s' % (self.year,self.month,self.day,__class__.__name__) #格式化输出这个str

n = Date(1,1,1)  #由于定义类时设置了3个参数,所以这里实例化要传参
n1 = n.now()    #经过@classmethod 实例一样可以像类一样调用内部方法。
print(n1.year,n1.month,n1.day)
e1 = EuroDate.Euro()  #使用子类调用继承的父类的方法
print(e1)

输出:

<class ‘main.Date’>
2017 4 22
<class ‘main.EuroDate’>
现在是2017年4月21日from EuroDate

@staticmethod

staticmethod #类的工具包 给类用,函数不用传值,不用绑定传self,都可以调用这个函数

作者:李保银
链接:https://www.zhihu.com/question/20021164/answer/18224953
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Kls(object):
    def __init__(self, data):
        self.data = data
    def printd(self):
        print(self.data)
    @staticmethod
    def smethod(*arg):
        print('Static:', arg)
    @classmethod
    def cmethod(*arg):
        print('Class:', arg)
 
>>> ik = Kls(23)
>>> ik.printd()
23
>>> ik.smethod()
Static: ()
>>> ik.cmethod()
Class: (<class '__main__.Kls'>,)
>>> Kls.printd()
TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead)
>>> Kls.smethod()
Static: ()
>>> Kls.cmethod()
Class: (<class '__main__.Kls'>,)

在这里插入图片描述
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。

而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。

这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。

既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢

从它们的使用上来看,

@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。

而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值