实例方法
class Kls(object):
def __init__(self, data):
self.data = data
def printd(self):
print(self.data)
ik1 = Kls('leo')
ik2 = Kls('lee')
ik1.printd()
ik2.printd()
# leo
# lee
实例ik1
会传递给self
参数,这样self
参数就可以引用当前正在调用实例方法的实例。
类方法
Python 的类方法采用装饰器@classmethod
来定义
class Kls(object):
num_inst = 0
def __init__(self):
Kls.num_inst = Kls.num_inst + 1
@classmethod
def get_no_of_instance(cls):
return cls.num_inst
ik1 = Kls()
ik2 = Kls()
print(ik1.get_no_of_instance())
print(Kls.get_no_of_instance())
# 2
# 2
在上述例子中,我们需要统计类Kls
实例的个数,因此定义了一个类变量num_inst
来存放实例个数。通过装饰器@classmethod
的使用,方法get_no_of_instance
被定义成一个类方法。在调用类方法时,Python 会将类(class Kls
)传递给cls
,这样在get_no_of_instance
内部就可以引用类变量num_inst
。
由于在调用类方法时,只需要将类型本身传递给类方法,因此,既可以通过类也可以通过实例来调用类方法。
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 0x000001F088567D60>
# func3
# 类属性
静态方法
在开发中,我们常常需要定义一些方法,这些方法跟类有关,但在实现时并不需要引用类或者实例,
例如,设置环境变量,修改另一个类的变量等。这个时候,我们可以使用静态方法。
Python 使用装饰器@staticmethod
来定义一个静态方法。
IND = 'ON'
class Kls(object):
def __init__(self, data):
self.data = data
@staticmethod
def checkind():
return IND == 'ON'
def do_reset(self):
if self.checkind():
print('Reset done for: %s' % self.data)
def set_db(self):
if self.checkind():
print('DB connection made for: %s' % self.data)
ik1 = Kls(24)
ik1.do_reset()
ik1.set_db()
########################################################################
# Reset done for: 24
# DB connection made for: 24
区别概括
class Kls(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)
ik = Kls()
# 实例方法
ik.foo(1)
print(ik.foo)
print('==========================================')
# executing foo(<__main__.Kls object at 0x00000279F1087B80>,1)
# <bound method Kls.foo of <__main__.Kls object at 0x00000279F1087B80>>
# ==========================================
# 类方法
ik.class_foo(1)
Kls.class_foo(1)
print(ik.class_foo)
print('==========================================')
# executing class_foo(<class '__main__.Kls'>,1)
# executing class_foo(<class '__main__.Kls'>,1)
# <bound method Kls.class_foo of <class '__main__.Kls'>>
# ==========================================
# 静态方法
ik.static_foo(1)
Kls.static_foo('hi')
print(ik.static_foo)
# executing static_foo(1)
# executing static_foo(hi)
# <function Kls.static_foo at 0x00000279F109D3A0>
-
实例方法
调用时会把实例
ik
作为第一个参数传递给self
参数。因此,调用ik.foo(1)
时输出了实例ik
的地址。 -
类方法
调用时会把类
Kls
作为第一个参数传递给cls
参数。因此,调用ik.class_foo(1)
时输出了Kls
类型信息。 -
静态方法
调用时并不需要传递类或者实例。其实,静态方法很像我们在类外定义的函数,只不过静态方法可以通过类或者实例来调用而已。
值得注意的是,在上述例子中,foo
只是个函数,但当调用ik.foo
的时候我们得到的是一个已经跟实例ik
绑定的函数。
- 调用
foo
时需要两个参数,但调用ik.foo
时只需要一个参数。foo
跟ik
进行了绑定. 当我们打印ik.foo
时,会看到以下输出:
<bound method Kls.foo of <__main__.Kls object at 0x00000279F1087B80>>
- 调用
ik.class_foo
时,由于class_foo
是类方法,因此,class_foo
跟Kls
进行了绑定(而不是跟ik
绑定)。当我们打印ik.class_foo
时,输出:
<bound method Kls.class_foo of <class '__main__.Kls'>>
- 调用
ik.static_foo
时,静态方法并不会与类或者实例绑定,因此,打印ik.static_foo
(或者Kls.static_foo
)时输出:
<function Kls.static_foo at 0x00000279F109D3A0>
概括来说,是否与类或者实例进行绑定,这就是实例方法,类方法,静态方法的区别
网友评论