+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2019-07(2)

2019-08(97)

2019-09(111)

2019-10(13)

2019-11(5)

Python 类的几个内置装饰器—— Staticmethod Classmethod Property

发布于2020-05-17 18:43     阅读(387)     评论(0)     点赞(1)     收藏(0)


通常情况下,想调用某个类中的方法时,需要先实例化一个对象再进行调用。

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

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

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

从它们的使用上来看:

  • @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
  • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。

@property 属性方法

属性方法的作用就是通过@property把一个方法变成一个静态属性

  1. class Foo(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def func(self):
  5. print("%s:基本方法" %self.name)
  6. @property  # pro = property(pro)
  7. def pro(self):
  8. print("%s:属性方法" %self.name)
  9. foo_obj = Foo("alex")
  10. foo_obj.func()
  11. foo_obj.pro

@getter @setter @deleter

  1. class A(object):
  2. def __init__(self, name):
  3. self.__name = name
  4. @property
  5. def name(self):
  6. return self.__name
  7. @name.setter
  8. def name(self, value):
  9. if isinstance(value, str):
  10. self.__name = value
  11. else:
  12. raise TypeError("%s must be str" % value)
  13. @name.deleter
  14. def name(self):
  15. raise AttributeError("can not be delete")
  16. a = A("alex")
  17. print(a.name)
  18. a.name = 222
  19. del a.name

总结:

  • @property属性方法 封装类中的方法,给用户更加简单的调用方式,隐藏具体的实现细节。
  • @method.getter 获取属性
  • @method.setter 设置属性, 可以写更多逻辑(比如格式转换,类型判断),并提醒其他人这里面可能有magic
  • @method.deleter 删除属性

@staticmethod

  • 可以看成是静态方法已经跟这个类没关系了,相当于已经脱离了这个类,是一个完全独立的函数,只是调用的时候必须通过这个类, 或者为了规范代码而将函数放到类中
  • 类中定义函方法 PyCharm 提示Method xxx may be ‘static’, 原因是该方法不涉及对该类属性的操作,编译器建议声明为@staticmethod,面向对象思想体现

利用staticmethod来实现多种实例化方式

  1. import time
  2. class Date(object):
  3. def __init__(self, year, month, day):
  4. self.year = year
  5. self.month = month
  6. self.day = day
  7. @staticmethod
  8. def now():
  9. t = time.localtime()
  10. return Date(t.tm_year, t.tm_mon, t.tm_mday)
  11. date = Date.now()
  12. print(date.year, date.month, date.day)
  13. date = Date(1999,12,12)

@classmethod

类方法只能访问类变量,不能访问实例变量, 也就是跟类有关,跟实例无关。

  1. class ParentClass(object):
  2. var = "test for parent"
  3. @classmethod
  4. def clsmethod(cls):
  5. print(cls.var)
  6. class SubClass(ParentClass):
  7. var = "test for sub"
  8. ParentClass.clsmethod()
  9. >>>
  10. test for parent
  11. SubClass.clsmethod()
  12. >>>
  13. test for sub

此时ParentClass.clsmethod输出为 “test for parent”,而Subclass.clsmethod输出为“test for sub”。

通过此比较很好的诠释了@classmethod类方法隐式传入的第一个参数是当前类,而不是父类。`

同时类方法操作的是class 类对象提供的内部信息。而staticmethod可以作为一般的工具函数来使用。

总结:

  • Classmethod主要用途是作为构造函数;
    Python只有一个构造函数__new__,如果想要多种构造函数就很不方便。只能在new里面写一堆if isinstance 。
      有classmethod之后就可以用classmethod来写不同的构造函数,cpython里面大部分classmethod最后都是 return cls(XXX), return XXX.__new__ ()之类的。
  • Staticmethod主要用途是限定Namespace
    也就是说这个函数虽然是个普通的function,但是它只有这个class会用到,不适合作为module level的function,这时候就把它作为staticmethod
      如果不考虑namespace的问题的话直接在module里面def function就行了。

参考:https://zhuanlan.zhihu.com/p/139786213

原文链接:https://blog.csdn.net/dzysunshine/article/details/106156920



所属网站分类: 技术文章 > 博客

作者:遥远的她

链接: https://www.pythonheidong.com/blog/article/377250/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

1 0
收藏该文
已收藏

评论内容:(最多支持255个字符)