Python OOP(2)-static method,class method and instance method

时间:2023-02-09 18:35:20

静态方法(Static Method)

一种简单函数,符合以下要求:

1.嵌套在类中。

2.没有self参数。

特点

1.类调用、实例调用,静态方法都不会接受自动的self参数。

2.会记录所有实例的信息,而不是为实例提供行为。

简单说staticmethod 无法访问类属性、实例属性,相当于一个相对独立的方法,跟类其实没什么关系,换个角度来讲,其实就是放在一个类的作用域里的函数而已。

#!python2
#-*- coding:utf-8 -*- class A:
v1="class argu" def __init__(self):
self.v1="instance argu" def fun1():
print "Static fun" fun1=staticmethod(fun1) a=A() #实例调用
a.v1 'instance argu' #类调用
A.v1 'class argu' a.fun1() A.fun1()

另一种写法是在python2.4以后用装饰器decorator

#!python2
#-*- coding:utf-8 -*- class A:
v1="class argu" def __init__(self):
self.v1="instance argu" @staticmethod def fun1():
print "Static fun" a=A() #实例调用
a.v1 'instance argu' #类调用
A.v1 'class argu' a.fun1() A.fun1()

类方法(Class Method)

一种函数,符合以下特征

1.类调用、或实例调用,传递的参数是一个类对象。

注意classmethod 可以访问类属性,无法访问实例属性。上述的变量val1,在类里是类变量,在实例中又是实例变量,所以容易混淆

适用于:

程序需要处理与类而不是与实例相关的数据。也就是说这种数据信息通常存储在类自身上,不需要任何实例也可以处理。

例如:

1.记录有一个类创建的实例的数目。

2.维护当前内存中一个类的所有实例的列表。

以上情况也可以同以下方式解决:

在类定义之外生成一个的简单函数

#记录实例创建数目

def amountinstance():
print "Amount of instances is : %d" %(c1.numInstance) class c1:
numInstance=0
def __init__(self):
c1.numInstance+=1 a=c1()
b=c1()
c=c1()
amountinstance() 3

因为类名称对简单函数而言,是可读取的全局变量,所以看到上例可以正常工作。

此外,函数名变成了全局变量,故仅适用于这个单一模块。

这样处理的缺点如下:

1.给文件的作用域添加了一个额外的名称,该名称仅能处理单个的类,不能应付多个类需要处理的情况。

2.该函数与类的直接关联很小,函数的定义可能在数百行代码之外的位置。

3.该函数位于类的命名空间之外,子类不能通过重新定义来代替或扩展它。

class MyClass:
val1 = 'Value 1'
def __init__(self):
self.val2 = 'Value 2'
def staticmd():
print '静态方法,无法访问val1和val2'
smd = staticmethod(staticmd) def classmd(cls):
print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值'
cmd = classmethod(classmd) mc = MyClass()
mc.cmd() 类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值 MyClass.cmd() 类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

另一种写法是在python2.4以后用装饰器decorator

class MyClass:
val1 = 'Value 1'
def __init__(self):
self.val2 = 'Value 2' @staticmethod def staticmd():
print '静态方法,无法访问val1和val2' @classmethod def classmd(cls):
print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值' mc = MyClass()
mc.classmd() 类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值 MyClass.classmd() 类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值 #实例的val1与类的val1是不一样的,类方法可以访问的是类的val1 mc.val1 = 'Value changed'
mc.classmd()
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值 MyClass.classmd()
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值 MyClass.val1='Value changed'
mc.classmd() 类方法,类:__main__.MyClass,val1:Value changed,无法访问val2的值 MyClass.classmd() 类方法,类:__main__.MyClass,val1:Value changed,无法访问val2的值

最后汇总instance method, static method 和class method 的实现和调用

#!python2
#-*- coding:utf-8 -*- class Methods(): def im(self,v2):
self.v2=v2
print "Call instance method: %d " % v2 @staticmethod def sm(v2):
print "Call static method: %d " % v2 @classmethod def cm(cls,v2):
print "Call class method: %d " % v2 obj=Methods() #instance method call
#实例方法调用一定要将类实例化,方可通过实例调用 obj.im(1) Call instance method: 1 Methods.im(obj,1) Call instance method: 1 #static method call
#静态方法调用时不需要实例参数
obj.sm(2) Call static method: 2 Methods.sm(2) Call static method: 2 #class method call
# 类方法调用时,Python会把类(不是实例)传入类方法第一个(最左侧)参数cls(默认) obj.cm(3) Call class method: 3 Methods.cm(3) Call class method: 3