通常情况下,想调用某个类中的方法时,需要先实例化一个对象再进行调用。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
既然@staticmethod
和@classmethod
都可以直接类名.方法名()来调用,那他们有什么区别呢?
从它们的使用上来看:
- @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
- @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
@property 属性方法
属性方法的作用就是通过@property
把一个方法变成一个静态属性
class Foo(object):
def __init__(self, name):
self.name = name
def func(self):
print("%s:基本方法" %self.name)
@property # pro = property(pro)
def pro(self):
print("%s:属性方法" %self.name)
foo_obj = Foo("alex")
foo_obj.func()
foo_obj.pro
@getter @setter @deleter
class A(object):
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
if isinstance(value, str):
self.__name = value
else:
raise TypeError("%s must be str" % value)
@name.deleter
def name(self):
raise AttributeError("can not be delete")
a = A("alex")
print(a.name)
a.name = 222
del a.name
总结:
- @property属性方法 封装类中的方法,给用户更加简单的调用方式,隐藏具体的实现细节。
- @method.getter 获取属性
- @method.setter 设置属性, 可以写更多逻辑(比如格式转换,类型判断),并提醒其他人这里面可能有magic
- @method.deleter 删除属性
@staticmethod
- 可以看成是静态方法已经跟这个类没关系了,相当于已经脱离了这个类,是一个完全独立的函数,只是调用的时候必须通过这个类, 或者为了规范代码而将函数放到类中
- 类中定义函方法 PyCharm 提示Method xxx may be ‘static’, 原因是该方法不涉及对该类属性的操作,编译器建议声明为@staticmethod,面向对象思想体现
利用staticmethod来实现多种实例化方式
import time
class Date(object):
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
@staticmethod
def now():
t = time.localtime()
return Date(t.tm_year, t.tm_mon, t.tm_mday)
date = Date.now()
print(date.year, date.month, date.day)
date = Date(1999,12,12)
@classmethod
类方法只能访问类变量,不能访问实例变量, 也就是跟类有关,跟实例无关。
class ParentClass(object):
var = "test for parent"
@classmethod
def clsmethod(cls):
print(cls.var)
class SubClass(ParentClass):
var = "test for sub"
ParentClass.clsmethod()
>>>
test for parent
SubClass.clsmethod()
>>>
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
就行了。